Browse Source

Merge remote-tracking branch 'up/develop' into designDebugPanel

cl-refactor
yann300 10 years ago
parent
commit
68d2036788
  1. 5
      cmake/EthCompilerSettings.cmake
  2. 95
      eth/main.cpp
  3. 112
      ethminer/MinerAux.h
  4. 2
      libdevcore/FixedHash.h
  5. 49
      libethash-cl/ethash_cl_miner.cpp
  6. 11
      libethash-cl/ethash_cl_miner.h
  7. 14
      libethcore/Ethash.cpp
  8. 15
      libethcore/Ethash.h
  9. 5
      libethcore/EthashAux.cpp
  10. 1
      libethcore/EthashAux.h
  11. 15
      libethereum/ClientBase.cpp
  12. 1
      libethereum/ClientBase.h
  13. 36
      libethereum/EthereumHost.cpp
  14. 2
      libethereum/EthereumHost.h
  15. 7
      libethereum/State.cpp
  16. 5
      libp2p/Host.cpp
  17. 1
      libp2p/Host.h
  18. 2
      test/TestHelper.cpp
  19. 13
      test/libevm/vm.cpp

5
cmake/EthCompilerSettings.cmake

@ -55,6 +55,11 @@ else ()
message(WARNING "Your compiler is not tested, if you run into any issues, we'd welcome any patches.")
endif ()
# Set stack memory limits
if (APPLE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-stack_size,1000000")
endif()
if (PROFILING AND (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")))
set(CMAKE_CXX_FLAGS "-g ${CMAKE_CXX_FLAGS}")
set(CMAKE_C_FLAGS "-g ${CMAKE_C_FLAGS}")

95
eth/main.cpp

@ -93,6 +93,7 @@ void interactiveHelp()
<< " accounts Gives information on all owned accounts (balances, mining beneficiary and default signer)." << endl
<< " newaccount <name> Creates a new account with the given name." << endl
<< " transact Execute a given transaction." << endl
<< " transactnonce Execute a given transaction with a specified nonce." << endl
<< " txcreate Execute a given contract creation transaction." << endl
<< " send Execute a given transaction with current secret." << endl
<< " contract Create a new contract with current secret." << endl
@ -108,6 +109,7 @@ void interactiveHelp()
<< " exportconfig <path> Export the config (.RLP) to the path provided." << endl
<< " importconfig <path> Import the config (.RLP) from the path provided." << endl
<< " inspect <contract> Dumps a contract to <APPDATA>/<contract>.evm." << endl
<< " reprocess <block> Reprocess a given block." << endl
<< " dumptrace <block> <index> <filename> <format> Dumps a transaction trace" << endl << "to <filename>. <format> should be one of pretty, standard, standard+." << endl
<< " dumpreceipt <block> <index> Dumps a transation receipt." << endl
<< " exit Exits the application." << endl;
@ -806,13 +808,19 @@ int main(int argc, char** argv)
cout << "Transaction Signer: " << signingKey << endl;
cout << "Mining Benefactor: " << beneficiary << endl;
if (bootstrap || !remoteHost.empty())
{
web3.startNetwork();
cout << "Node ID: " << web3.enode() << endl;
}
else
cout << "Networking disabled. To start, use netstart or pass -b or a remote host." << endl;
if (bootstrap)
for (auto const& i: Host::pocHosts())
web3.requirePeer(i.first, i.second);
if (remoteHost.size())
if (!remoteHost.empty())
web3.addNode(p2p::NodeId(), remoteHost + ":" + toString(remotePort));
#if ETH_JSONRPC || !ETH_TRUE
@ -1175,6 +1183,75 @@ int main(int argc, char** argv)
else
cwarn << "Require parameters: submitTransaction ADDRESS AMOUNT GASPRICE GAS SECRET DATA";
}
else if (c && cmd == "transactnonce")
{
auto const& bc =c->blockChain();
auto h = bc.currentHash();
auto blockData = bc.block(h);
BlockInfo info(blockData);
if (iss.peek() != -1)
{
string hexAddr;
u256 amount;
u256 gasPrice;
u256 gas;
string sechex;
string sdata;
u256 nonce;
iss >> hexAddr >> amount >> gasPrice >> gas >> sechex >> sdata >> nonce;
if (!gasPrice)
gasPrice = gasPricer->bid(priority);
cnote << "Data:";
cnote << sdata;
bytes data = dev::eth::parseData(sdata);
cnote << "Bytes:";
string sbd = asString(data);
bytes bbd = asBytes(sbd);
stringstream ssbd;
ssbd << bbd;
cnote << ssbd.str();
int ssize = sechex.length();
int size = hexAddr.length();
u256 minGas = (u256)Transaction::gasRequired(data, 0);
if (size < 40)
{
if (size > 0)
cwarn << "Invalid address length:" << size;
}
else if (gas < minGas)
cwarn << "Minimum gas amount is" << minGas;
else if (ssize < 40)
{
if (ssize > 0)
cwarn << "Invalid secret length:" << ssize;
}
else
{
try
{
Secret secret = h256(fromHex(sechex));
Address dest = h160(fromHex(hexAddr));
c->submitTransaction(secret, amount, dest, data, gas, gasPrice, nonce);
}
catch (BadHexCharacter& _e)
{
cwarn << "invalid hex character, transaction rejected";
cwarn << boost::diagnostic_information(_e);
}
catch (...)
{
cwarn << "transaction rejected";
}
}
}
else
cwarn << "Require parameters: submitTransaction ADDRESS AMOUNT GASPRICE GAS SECRET DATA NONCE";
}
else if (c && cmd == "txcreate")
{
auto const& bc =c->blockChain();
@ -1403,6 +1480,22 @@ int main(int argc, char** argv)
cout << "Hex: " << toHex(rb) << endl;
cout << r << endl;
}
else if (c && cmd == "reprocess")
{
string block;
iss >> block;
h256 blockHash;
try
{
if (block.size() == 64 || block.size() == 66)
blockHash = h256(block);
else
blockHash = c->blockChain().numberHash(stoi(block));
c->state(blockHash);
}
catch (...)
{}
}
else if (c && cmd == "dumptrace")
{
unsigned block;

112
ethminer/MinerAux.h

@ -30,6 +30,7 @@
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/trim_all.hpp>
#include <boost/optional.hpp>
#include <libdevcore/FileSystem.h>
#include <libevmcore/Instruction.h>
@ -97,11 +98,11 @@ public:
if ((arg == "-F" || arg == "--farm") && i + 1 < argc)
{
mode = OperationMode::Farm;
farmURL = argv[++i];
m_farmURL = argv[++i];
}
else if (arg == "--farm-recheck" && i + 1 < argc)
try {
farmRecheckPeriod = stol(argv[++i]);
m_farmRecheckPeriod = stol(argv[++i]);
}
catch (...)
{
@ -110,7 +111,7 @@ public:
}
else if (arg == "--opencl-platform" && i + 1 < argc)
try {
openclPlatform = stol(argv[++i]);
m_openclPlatform = stol(argv[++i]);
}
catch (...)
{
@ -119,8 +120,8 @@ public:
}
else if (arg == "--opencl-device" && i + 1 < argc)
try {
openclDevice = stol(argv[++i]);
miningThreads = 1;
m_openclDevice = stol(argv[++i]);
m_miningThreads = 1;
}
catch (...)
{
@ -128,17 +129,18 @@ public:
throw BadArgument();
}
else if (arg == "--list-devices")
{
ProofOfWork::GPUMiner::listDevices();
exit(0);
}
m_shouldListDevices = true;
else if (arg == "--allow-opencl-cpu")
m_clAllowCPU = true;
else if (arg == "--cl-extragpu-mem" && i + 1 < argc)
m_extraGPUMemory = 1000000 * stol(argv[++i]);
else if (arg == "--phone-home" && i + 1 < argc)
{
string m = argv[++i];
if (isTrue(m))
phoneHome = true;
m_phoneHome = true;
else if (isFalse(m))
phoneHome = false;
m_phoneHome = false;
else
{
cerr << "Bad " << arg << " option: " << m << endl;
@ -147,7 +149,7 @@ public:
}
else if (arg == "--benchmark-warmup" && i + 1 < argc)
try {
benchmarkWarmup = stol(argv[++i]);
m_benchmarkWarmup = stol(argv[++i]);
}
catch (...)
{
@ -156,7 +158,7 @@ public:
}
else if (arg == "--benchmark-trial" && i + 1 < argc)
try {
benchmarkTrial = stol(argv[++i]);
m_benchmarkTrial = stol(argv[++i]);
}
catch (...)
{
@ -165,7 +167,7 @@ public:
}
else if (arg == "--benchmark-trials" && i + 1 < argc)
try {
benchmarkTrials = stol(argv[++i]);
m_benchmarkTrials = stol(argv[++i]);
}
catch (...)
{
@ -175,21 +177,12 @@ public:
else if (arg == "-C" || arg == "--cpu")
m_minerType = MinerType::CPU;
else if (arg == "-G" || arg == "--opencl")
{
if (!ProofOfWork::GPUMiner::configureGPU())
{
cout << "No GPU device with sufficient memory was found. Defaulting to CPU" << endl;
m_minerType = MinerType::CPU;
}
else
{
m_minerType = MinerType::GPU;
miningThreads = 1;
}
}
else if (arg == "--current-block" && i + 1 < argc)
m_currentBlock = stol(argv[++i]);
else if (arg == "--no-precompute")
{
precompute = false;
m_precompute = false;
}
else if ((arg == "-D" || arg == "--create-dag") && i + 1 < argc)
{
@ -197,7 +190,7 @@ public:
mode = OperationMode::DAGInit;
try
{
initDAG = stol(m);
m_initDAG = stol(m);
}
catch (...)
{
@ -247,7 +240,7 @@ public:
else if ((arg == "-t" || arg == "--mining-threads") && i + 1 < argc)
{
try {
miningThreads = stol(argv[++i]);
m_miningThreads = stol(argv[++i]);
}
catch (...)
{
@ -262,20 +255,35 @@ public:
void execute()
{
if (m_shouldListDevices)
{
ProofOfWork::GPUMiner::listDevices();
exit(0);
}
if (m_minerType == MinerType::CPU)
ProofOfWork::CPUMiner::setNumInstances(miningThreads);
ProofOfWork::CPUMiner::setNumInstances(m_miningThreads);
else if (m_minerType == MinerType::GPU)
{
ProofOfWork::GPUMiner::setDefaultPlatform(openclPlatform);
ProofOfWork::GPUMiner::setDefaultDevice(openclDevice);
ProofOfWork::GPUMiner::setNumInstances(miningThreads);
ProofOfWork::GPUMiner::setNumInstances(m_miningThreads);
if (!ProofOfWork::GPUMiner::configureGPU(
m_openclPlatform,
m_openclDevice,
m_clAllowCPU,
m_extraGPUMemory,
m_currentBlock
))
{
cout << "No GPU device with sufficient memory was found. Can't GPU mine. Remove the -G argument" << endl;
exit(1);
}
}
if (mode == OperationMode::DAGInit)
doInitDAG(initDAG);
doInitDAG(m_initDAG);
else if (mode == OperationMode::Benchmark)
doBenchmark(m_minerType, phoneHome, benchmarkWarmup, benchmarkTrial, benchmarkTrials);
doBenchmark(m_minerType, m_phoneHome, m_benchmarkWarmup, m_benchmarkTrial, m_benchmarkTrials);
else if (mode == OperationMode::Farm)
doFarm(m_minerType, farmURL, farmRecheckPeriod);
doFarm(m_minerType, m_farmURL, m_farmRecheckPeriod);
}
static void streamHelp(ostream& _out)
@ -306,6 +314,10 @@ public:
<< " --opencl-platform <n> When mining using -G/--opencl use OpenCL platform n (default: 0)." << endl
<< " --opencl-device <n> When mining using -G/--opencl use OpenCL device n (default: 0)." << endl
<< " -t, --mining-threads <n> Limit number of CPU/GPU miners to n (default: use everything available on selected platform)" << endl
<< " --allow-opencl-cpu Allows CPU to be considered as an OpenCL device if the OpenCL platform supports it." << endl
<< " --list-devices List the detected OpenCL devices and exit." <<endl
<< " --current-block Let the miner know the current block number at configuration time. Will help determine DAG size and required GPU memory." <<endl
<< " --cl-extragpu-mem Set the memory (in MB) you believe your GPU requires for stuff other than mining. Windows rendering e.t.c.." <<endl
;
}
@ -441,7 +453,7 @@ private:
cnote << "Grabbing DAG for" << newSeedHash;
if (!(dag = EthashAux::full(newSeedHash, true, [&](unsigned _pc){ cout << "\rCreating DAG. " << _pc << "% done..." << flush; return 0; })))
BOOST_THROW_EXCEPTION(DAGCreationFailure());
if (precompute)
if (m_precompute)
EthashAux::computeFull(sha3(newSeedHash), true);
if (hh != current.headerHash)
{
@ -490,22 +502,26 @@ private:
/// Mining options
MinerType m_minerType = MinerType::CPU;
unsigned openclPlatform = 0;
unsigned openclDevice = 0;
unsigned miningThreads = UINT_MAX;
unsigned dagChunks = 1;
unsigned m_openclPlatform = 0;
unsigned m_openclDevice = 0;
unsigned m_miningThreads = UINT_MAX;
bool m_shouldListDevices = false;
bool m_clAllowCPU = false;
boost::optional<uint64_t> m_currentBlock;
// default value is 350MB of GPU memory for other stuff (windows system rendering, e.t.c.)
unsigned m_extraGPUMemory = 350000000;
/// DAG initialisation param.
unsigned initDAG = 0;
unsigned m_initDAG = 0;
/// Benchmarking params
bool phoneHome = true;
unsigned benchmarkWarmup = 3;
unsigned benchmarkTrial = 3;
unsigned benchmarkTrials = 5;
bool m_phoneHome = true;
unsigned m_benchmarkWarmup = 3;
unsigned m_benchmarkTrial = 3;
unsigned m_benchmarkTrials = 5;
/// Farm params
string farmURL = "http://127.0.0.1:8545";
unsigned farmRecheckPeriod = 500;
bool precompute = true;
string m_farmURL = "http://127.0.0.1:8545";
unsigned m_farmRecheckPeriod = 500;
bool m_precompute = true;
};

2
libdevcore/FixedHash.h

@ -100,7 +100,7 @@ public:
FixedHash operator|(FixedHash const& _c) const { return FixedHash(*this) |= _c; }
FixedHash& operator&=(FixedHash const& _c) { for (unsigned i = 0; i < N; ++i) m_data[i] &= _c.m_data[i]; return *this; }
FixedHash operator&(FixedHash const& _c) const { return FixedHash(*this) &= _c; }
FixedHash& operator~() { for (unsigned i = 0; i < N; ++i) m_data[i] = ~m_data[i]; return *this; }
FixedHash operator~() const { FixedHash ret; for (unsigned i = 0; i < N; ++i) ret[i] = ~m_data[i]; return ret; }
/// @returns true if all bytes in @a _c are set in this object.
bool contains(FixedHash const& _c) const { return (*this & _c) == _c; }

49
libethash-cl/ethash_cl_miner.cpp

@ -32,11 +32,11 @@
#include <vector>
#include <libethash/util.h>
#include <libethash/ethash.h>
#include <libethash/internal.h>
#include "ethash_cl_miner.h"
#include "ethash_cl_miner_kernel.h"
#define ETHASH_BYTES 32
#define ETHASH_CL_MINIMUM_MEMORY 2000000000
// workaround lame platforms
#if !CL_VERSION_1_2
@ -51,6 +51,8 @@ using namespace std;
// TODO: If at any point we can use libdevcore in here then we should switch to using a LogChannel
#define ETHCL_LOG(_contents) cout << "[OPENCL]:" << _contents << endl
// Types of OpenCL devices we are interested in
#define ETHCL_QUERIED_DEVICE_TYPES (CL_DEVICE_TYPE_GPU | CL_DEVICE_TYPE_ACCELERATOR)
static void addDefinition(string& _source, char const* _id, unsigned _value)
{
@ -82,9 +84,8 @@ string ethash_cl_miner::platform_info(unsigned _platformId, unsigned _deviceId)
}
// get GPU device of the selected platform
vector<cl::Device> devices;
unsigned platform_num = min<unsigned>(_platformId, platforms.size() - 1);
platforms[platform_num].getDevices(CL_DEVICE_TYPE_ALL, &devices);
vector<cl::Device> devices = getDevices(platforms, _platformId);
if (devices.empty())
{
ETHCL_LOG("No OpenCL devices found.");
@ -99,6 +100,17 @@ string ethash_cl_miner::platform_info(unsigned _platformId, unsigned _deviceId)
return "{ \"platform\": \"" + platforms[platform_num].getInfo<CL_PLATFORM_NAME>() + "\", \"device\": \"" + device.getInfo<CL_DEVICE_NAME>() + "\", \"version\": \"" + device_version + "\" }";
}
std::vector<cl::Device> ethash_cl_miner::getDevices(std::vector<cl::Platform> const& _platforms, unsigned _platformId)
{
vector<cl::Device> devices;
unsigned platform_num = min<unsigned>(_platformId, _platforms.size() - 1);
_platforms[platform_num].getDevices(
s_allowCPU ? CL_DEVICE_TYPE_ALL : ETHCL_QUERIED_DEVICE_TYPES,
&devices
);
return devices;
}
unsigned ethash_cl_miner::getNumPlatforms()
{
vector<cl::Platform> platforms;
@ -116,9 +128,7 @@ unsigned ethash_cl_miner::getNumDevices(unsigned _platformId)
return 0;
}
vector<cl::Device> devices;
unsigned platform_num = min<unsigned>(_platformId, platforms.size() - 1);
platforms[platform_num].getDevices(CL_DEVICE_TYPE_ALL, &devices);
vector<cl::Device> devices = getDevices(platforms, _platformId);
if (devices.empty())
{
ETHCL_LOG("No OpenCL devices found.");
@ -127,13 +137,18 @@ unsigned ethash_cl_miner::getNumDevices(unsigned _platformId)
return devices.size();
}
bool ethash_cl_miner::configureGPU()
bool ethash_cl_miner::configureGPU(bool _allowCPU, unsigned _extraGPUMemory, boost::optional<uint64_t> _currentBlock)
{
return searchForAllDevices([](cl::Device const _device) -> bool
s_allowCPU = _allowCPU;
s_extraRequiredGPUMem = _extraGPUMemory;
// by default let's only consider the DAG of the first epoch
uint64_t dagSize = _currentBlock ? ethash_get_datasize(*_currentBlock) : 1073739904U;
uint64_t requiredSize = dagSize + _extraGPUMemory;
return searchForAllDevices([&requiredSize](cl::Device const _device) -> bool
{
cl_ulong result;
_device.getInfo(CL_DEVICE_GLOBAL_MEM_SIZE, &result);
if (result >= ETHASH_CL_MINIMUM_MEMORY)
if (result >= requiredSize)
{
ETHCL_LOG(
"Found suitable OpenCL device [" << _device.getInfo<CL_DEVICE_NAME>()
@ -145,13 +160,16 @@ bool ethash_cl_miner::configureGPU()
ETHCL_LOG(
"OpenCL device " << _device.getInfo<CL_DEVICE_NAME>()
<< " has insufficient GPU memory." << result <<
" bytes of memory found < " << ETHASH_CL_MINIMUM_MEMORY << " bytes of memory required"
" bytes of memory found < " << requiredSize << " bytes of memory required"
);
return false;
}
);
}
bool ethash_cl_miner::s_allowCPU = false;
unsigned ethash_cl_miner::s_extraRequiredGPUMem;
bool ethash_cl_miner::searchForAllDevices(function<bool(cl::Device const&)> _callback)
{
vector<cl::Platform> platforms;
@ -175,8 +193,7 @@ bool ethash_cl_miner::searchForAllDevices(unsigned _platformId, function<bool(cl
if (_platformId >= platforms.size())
return false;
vector<cl::Device> devices;
platforms[_platformId].getDevices(CL_DEVICE_TYPE_ALL, &devices);
vector<cl::Device> devices = getDevices(platforms, _platformId);
for (cl::Device const& device: devices)
if (_callback(device))
return true;
@ -204,8 +221,7 @@ void ethash_cl_miner::doForAllDevices(unsigned _platformId, function<void(cl::De
if (_platformId >= platforms.size())
return;
vector<cl::Device> devices;
platforms[_platformId].getDevices(CL_DEVICE_TYPE_ALL, &devices);
vector<cl::Device> devices = getDevices(platforms, _platformId);
for (cl::Device const& device: devices)
_callback(device);
}
@ -253,8 +269,7 @@ bool ethash_cl_miner::init(
ETHCL_LOG("Using platform: " << platforms[_platformId].getInfo<CL_PLATFORM_NAME>().c_str());
// get GPU device of the default platform
vector<cl::Device> devices;
platforms[_platformId].getDevices(CL_DEVICE_TYPE_ALL, &devices);
vector<cl::Device> devices = getDevices(platforms, _platformId);
if (devices.empty())
{
ETHCL_LOG("No OpenCL devices found.");
@ -269,7 +284,7 @@ bool ethash_cl_miner::init(
// configure chunk number depending on max allocateable memory
cl_ulong result;
device.getInfo(CL_DEVICE_MAX_MEM_ALLOC_SIZE, &result);
if (result >= ETHASH_CL_MINIMUM_MEMORY)
if (result >= _dagSize)
{
m_dagChunksNum = 1;
ETHCL_LOG("Using 1 big chunk. Max OpenCL allocateable memory is" << result);

11
libethash-cl/ethash_cl_miner.h

@ -12,6 +12,7 @@
#include "cl.hpp"
#endif
#include <boost/optional.hpp>
#include <time.h>
#include <functional>
#include <libethash/ethash.h>
@ -40,7 +41,7 @@ public:
static unsigned getNumDevices(unsigned _platformId = 0);
static std::string platform_info(unsigned _platformId = 0, unsigned _deviceId = 0);
static void listDevices();
static bool configureGPU();
static bool configureGPU(bool _allowCPU, unsigned _extraGPUMemory, boost::optional<uint64_t> _currentBlock);
bool init(
uint8_t const* _dag,
@ -56,6 +57,9 @@ public:
void search_chunk(uint8_t const* header, uint64_t target, search_hook& hook);
private:
static std::vector<cl::Device> getDevices(std::vector<cl::Platform> const& _platforms, unsigned _platformId);
enum { c_max_search_results = 63, c_num_buffers = 2, c_hash_batch_size = 1024, c_search_batch_size = 1024*256 };
cl::Context m_context;
@ -70,4 +74,9 @@ private:
unsigned m_workgroup_size;
bool m_opencl_1_1;
/// Allow CPU to appear as an OpenCL device or not. Default is false
static bool s_allowCPU;
/// GPU memory required for other things, like window rendering e.t.c.
/// User can set it via the --cl-extragpu-mem argument.
static unsigned s_extraRequiredGPUMem;
};

14
libethcore/Ethash.cpp

@ -381,9 +381,17 @@ void Ethash::GPUMiner::listDevices()
return ethash_cl_miner::listDevices();
}
bool Ethash::GPUMiner::configureGPU()
{
return ethash_cl_miner::configureGPU();
bool Ethash::GPUMiner::configureGPU(
unsigned _platformId,
unsigned _deviceId,
bool _allowCPU,
unsigned _extraGPUMemory,
boost::optional<uint64_t> _currentBlock
)
{
s_platformId = _platformId;
s_deviceId = _deviceId;
return ethash_cl_miner::configureGPU(_allowCPU, _extraGPUMemory, _currentBlock);
}
#endif

15
libethcore/Ethash.h

@ -87,11 +87,8 @@ public:
static unsigned instances() { return s_numInstances > 0 ? s_numInstances : std::thread::hardware_concurrency(); }
static std::string platformInfo();
static void setDefaultPlatform(unsigned) {}
static void setDagChunks(unsigned) {}
static void setDefaultDevice(unsigned) {}
static void listDevices() {}
static bool configureGPU() { return false; }
static bool configureGPU(unsigned, unsigned, bool, unsigned, boost::optional<uint64_t>) { return false; }
static void setNumInstances(unsigned _instances) { s_numInstances = std::min<unsigned>(_instances, std::thread::hardware_concurrency()); }
protected:
void kickOff() override
@ -120,9 +117,13 @@ public:
static std::string platformInfo();
static unsigned getNumDevices();
static void listDevices();
static bool configureGPU();
static void setDefaultPlatform(unsigned _id) { s_platformId = _id; }
static void setDefaultDevice(unsigned _id) { s_deviceId = _id; }
static bool configureGPU(
unsigned _platformId,
unsigned _deviceId,
bool _allowCPU,
unsigned _extraGPUMemory,
boost::optional<uint64_t> _currentBlock
);
static void setNumInstances(unsigned _instances) { s_numInstances = std::min<unsigned>(_instances, getNumDevices()); }
protected:

5
libethcore/EthashAux.cpp

@ -54,6 +54,11 @@ uint64_t EthashAux::cacheSize(BlockInfo const& _header)
return ethash_get_cachesize((uint64_t)_header.number);
}
uint64_t EthashAux::dataSize(uint64_t _blockNumber)
{
return ethash_get_datasize(_blockNumber);
}
h256 EthashAux::seedHash(unsigned _number)
{
unsigned epoch = _number / ETHASH_EPOCH_LENGTH;

1
libethcore/EthashAux.h

@ -66,6 +66,7 @@ public:
static h256 seedHash(unsigned _number);
static uint64_t number(h256 const& _seedHash);
static uint64_t cacheSize(BlockInfo const& _header);
static uint64_t dataSize(uint64_t _blockNumber);
static LightType light(h256 const& _seedHash);

15
libethereum/ClientBase.cpp

@ -45,6 +45,21 @@ State ClientBase::asOf(BlockNumber _h) const
return asOf(bc().numberHash(_h));
}
void ClientBase::submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, u256 _nonce)
{
prepareForTransaction();
auto a = toAddress(_secret);
u256 n = postMine().transactionsFrom(a);
cdebug << "submitTx: " << a << "postMine=" << n << "; tq=" << m_tq.maxNonce(a);
Transaction t(_value, _gasPrice, _gas, _dest, _data, _nonce, _secret);
m_tq.import(t.rlp());
StructuredLogger::transactionReceived(t.sha3().abridged(), t.sender().abridged());
cnote << "New transaction " << t << "(maxNonce for sender" << a << "is" << m_tq.maxNonce(a) << ")";
}
void ClientBase::submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice)
{
prepareForTransaction();

1
libethereum/ClientBase.h

@ -76,6 +76,7 @@ public:
virtual ~ClientBase() {}
/// Submits the given message-call transaction.
virtual void submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, u256 _nonce);
virtual void submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo) override;
/// Submits a new contract-creation transaction.

36
libethereum/EthereumHost.cpp

@ -81,6 +81,7 @@ void EthereumHost::reset()
m_hashMan.reset(m_chain.number() + 1);
m_needSyncBlocks = true;
m_needSyncHashes = true;
m_syncingNewHashes = false;
m_syncingLatestHash = h256();
m_syncingTotalDifficulty = 0;
m_latestBlockSent = h256();
@ -88,6 +89,14 @@ void EthereumHost::reset()
m_hashes.clear();
}
void EthereumHost::resetSyncTo(h256 const& _h)
{
m_needSyncHashes = true;
m_needSyncBlocks = true;
m_syncingLatestHash = _h;
m_syncingNewHashes = false;
}
void EthereumHost::doWork()
{
bool netChange = ensureInitialised();
@ -367,8 +376,13 @@ void EthereumHost::onPeerHashes(EthereumPeer* _peer, h256s const& _hashes, bool
}
if (_complete)
{
clog(NetMessageSummary) << "Start new blocks download...";
m_needSyncBlocks = true;
continueSync();
m_syncingNewHashes = true;
m_man.resetToChain(m_hashes);
m_hashes.clear();
m_hashMan.reset(m_chain.number() + 1);
continueSync(_peer);
}
else if (syncByNumber && m_hashMan.isComplete())
{
@ -426,6 +440,7 @@ void EthereumHost::onPeerBlocks(EthereumPeer* _peer, RLP const& _r)
unsigned unknown = 0;
unsigned got = 0;
unsigned repeated = 0;
h256 lastUnknown;
for (unsigned i = 0; i < itemCount; ++i)
{
@ -454,6 +469,7 @@ void EthereumHost::onPeerBlocks(EthereumPeer* _peer, RLP const& _r)
break;
case ImportResult::UnknownParent:
lastUnknown = h;
unknown++;
break;
@ -468,6 +484,13 @@ void EthereumHost::onPeerBlocks(EthereumPeer* _peer, RLP const& _r)
}
clog(NetMessageSummary) << dec << success << "imported OK," << unknown << "with unknown parents," << future << "with future timestamps," << got << " already known," << repeated << " repeats received.";
if (m_syncingNewHashes && unknown > 0)
{
_peer->m_latestHash = lastUnknown;
resetSyncTo(lastUnknown);
}
continueSync(_peer);
}
@ -487,7 +510,7 @@ void EthereumHost::onPeerNewHashes(EthereumPeer* _peer, h256s const& _hashes)
void EthereumHost::onPeerNewBlock(EthereumPeer* _peer, RLP const& _r)
{
RecursiveGuard l(x_sync);
if (isSyncing_UNSAFE() || _peer->isConversing())
if ((isSyncing_UNSAFE() || _peer->isConversing()) && !m_syncingNewHashes)
{
clog(NetMessageSummary) << "Ignoring new blocks since we're already downloading.";
return;
@ -527,9 +550,7 @@ void EthereumHost::onPeerNewBlock(EthereumPeer* _peer, RLP const& _r)
clog(NetMessageSummary) << "Received block with no known parent. Resyncing...";
_peer->m_latestHash = h;
_peer->m_totalDifficulty = difficulty;
m_needSyncHashes = true;
m_needSyncBlocks = true;
m_syncingLatestHash = h;
resetSyncTo(h);;
sync = true;
}
}
@ -647,7 +668,7 @@ void EthereumHost::continueSync(EthereumPeer* _peer)
{
_peer->requestHashes(m_syncingLatestHash);
m_syncingV61 = false;
m_estimatedHashes = _peer->m_expectedHashes;
m_estimatedHashes = _peer->m_expectedHashes - (_peer->m_protocolVersion == protocolVersion() ? 0 : c_chainReorgSize);
}
else
_peer->setIdle();
@ -659,6 +680,7 @@ void EthereumHost::continueSync(EthereumPeer* _peer)
{
// Done our chain-get.
m_needSyncBlocks = false;
m_syncingNewHashes = false;
clog(NetNote) << "Chain download complete.";
// 1/100th for each useful block hash.
_peer->addRating(m_man.chainSize() / 100); //TODO: what about other peers?
@ -743,6 +765,6 @@ HashChainStatus EthereumHost::status()
RecursiveGuard l(x_sync);
if (m_syncingV61)
return HashChainStatus { static_cast<unsigned>(m_hashMan.chainSize()), static_cast<unsigned>(m_hashMan.gotCount()), false };
return HashChainStatus { m_estimatedHashes > 0 ? m_estimatedHashes - c_chainReorgSize : 0, static_cast<unsigned>(m_hashes.size()), m_estimatedHashes > 0 };
return HashChainStatus { m_estimatedHashes > 0 ? m_estimatedHashes : 0, static_cast<unsigned>(m_hashes.size()), m_estimatedHashes > 0 };
}

2
libethereum/EthereumHost.h

@ -97,6 +97,7 @@ private:
void foreachPeerPtr(std::function<void(std::shared_ptr<EthereumPeer>)> const& _f) const;
void foreachPeer(std::function<void(EthereumPeer*)> const& _f) const;
bool isSyncing_UNSAFE() const;
void resetSyncTo(h256 const& _h);
/// Sync with the BlockChain. It might contain one of our mined blocks, we might have new candidates from the network.
void doWork();
@ -151,6 +152,7 @@ private:
bool m_needSyncBlocks = true; ///< Indicates if we still need to download some blocks
h256 m_syncingLatestHash; ///< Latest block's hash, as of the current sync.
u256 m_syncingTotalDifficulty; ///< Latest block's total difficulty, as of the current sync.
bool m_syncingNewHashes = false; ///< True if currently downloading hashes received with NewHashes
h256s m_hashes; ///< List of hashes with unknown block numbers. Used for PV60 chain downloading and catching up to a particular unknown
unsigned m_estimatedHashes = 0; ///< Number of estimated hashes for the last peer over PV60. Used for status reporting only.
bool m_syncingV61 = false; ///< True if recent activity was over pv61+. Used for status reporting only.

7
libethereum/State.cpp

@ -141,7 +141,12 @@ State::State(OverlayDB const& _db, BlockChain const& _bc, h256 _h, ImportRequire
// 2. Enact the block's transactions onto this state.
m_ourAddress = bi.coinbaseAddress;
enact(BlockChain::verifyBlock(b), _bc, _ir);
boost::timer t;
auto vb = BlockChain::verifyBlock(b);
cnote << "verifyBlock:" << t.elapsed();
t.restart();
enact(vb, _bc, _ir);
cnote << "enact:" << t.elapsed();
}
else
{

5
libp2p/Host.cpp

@ -61,10 +61,13 @@ ReputationManager::ReputationManager()
void ReputationManager::noteRude(Session const& _s, std::string const& _sub)
{
DEV_WRITE_GUARDED(x_nodes)
m_nodes[make_pair(_s.id(), _s.info().clientVersion)].subs[_sub].isRude = true;
}
bool ReputationManager::isRude(Session const& _s, std::string const& _sub) const
{
DEV_READ_GUARDED(x_nodes)
{
auto nit = m_nodes.find(make_pair(_s.id(), _s.info().clientVersion));
if (nit == m_nodes.end())
@ -73,6 +76,8 @@ bool ReputationManager::isRude(Session const& _s, std::string const& _sub) const
bool ret = sit == nit->second.subs.end() ? false : sit->second.isRude;
return _sub.empty() ? ret : (ret || isRude(_s));
}
return false;
}
Host::Host(std::string const& _clientVersion, NetworkPreferences const& _n, bytesConstRef _restoreNetwork):
Worker("p2p", 0),

1
libp2p/Host.h

@ -99,6 +99,7 @@ public:
private:
std::unordered_map<std::pair<p2p::NodeId, std::string>, Reputation> m_nodes; ///< Nodes that were impolite while syncing. We avoid syncing from these if possible.
SharedMutex mutable x_nodes;
};
/**

2
test/TestHelper.cpp

@ -352,6 +352,8 @@ void ImportTest::exportTest(bytes const& _output, State const& _statePost)
BOOST_CHECK_MESSAGE((m_TestObject["out"].get_str() == m_TestObject["expectOut"].get_str()), warning);
else
BOOST_WARN_MESSAGE((m_TestObject["out"].get_str() == m_TestObject["expectOut"].get_str()), warning);
m_TestObject.erase(m_TestObject.find("expectOut"));
}
// export logs

13
test/libevm/vm.cpp

@ -388,6 +388,19 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
o["callcreates"] = fev.exportCallCreates();
o["out"] = output.size() > 4096 ? "#" + toString(output.size()) : toHex(output, 2, HexPrefix::Add);
// compare expected output with post output
if (o.count("expectOut") > 0)
{
std::string warning = "Check State: Error! Unexpected output: " + o["out"].get_str() + " Expected: " + o["expectOut"].get_str();
if (Options::get().checkState)
BOOST_CHECK_MESSAGE((o["out"].get_str() == o["expectOut"].get_str()), warning);
else
BOOST_WARN_MESSAGE((o["out"].get_str() == o["expectOut"].get_str()), warning);
o.erase(o.find("expectOut"));
}
o["gas"] = toCompactHex(fev.gas, HexPrefix::Add, 1);
o["logs"] = exportLog(fev.sub.logs);
}

Loading…
Cancel
Save