Browse Source

DAG generation improvements.

Generate next DAG in AZ!
Cleanups to Ethash & Aux.
DAG Progress in AZ.
cl-refactor
Gav Wood 10 years ago
parent
commit
da1fcbb19b
  1. 6
      alethzero/Main.ui
  2. 23
      alethzero/MainWin.cpp
  3. 1
      alethzero/MainWin.h
  4. 5
      alethzero/Transact.cpp
  5. 107
      eth/main.cpp
  6. 8
      libdevcore/Common.h
  7. 10
      libdevcore/Worker.cpp
  8. 6
      libethcore/Ethash.cpp
  9. 2
      libethcore/Ethash.h
  10. 38
      libethcore/EthashAux.cpp
  11. 14
      libethcore/EthashAux.h
  12. 4
      libethereum/ClientBase.h
  13. 4
      libethereum/State.cpp

6
alethzero/Main.ui

@ -151,6 +151,7 @@
</property> </property>
<addaction name="mine"/> <addaction name="mine"/>
<addaction name="turboMining"/> <addaction name="turboMining"/>
<addaction name="prepNextDAG"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="newTransaction"/> <addaction name="newTransaction"/>
<addaction name="newAccount"/> <addaction name="newAccount"/>
@ -1727,6 +1728,11 @@ font-size: 14pt</string>
<string>In&amp;ject Block</string> <string>In&amp;ject Block</string>
</property> </property>
</action> </action>
<action name="prepNextDAG">
<property name="text">
<string>Prepare Next &amp;DAG</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<customwidgets> <customwidgets>

23
alethzero/MainWin.cpp

@ -204,7 +204,7 @@ Main::Main(QWidget *parent) :
QSettings s("ethereum", "alethzero"); QSettings s("ethereum", "alethzero");
m_networkConfig = s.value("peers").toByteArray(); m_networkConfig = s.value("peers").toByteArray();
bytesConstRef network((byte*)m_networkConfig.data(), m_networkConfig.size()); bytesConstRef network((byte*)m_networkConfig.data(), m_networkConfig.size());
m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir(), WithExisting::Trust, {"eth", "shh"}, p2p::NetworkPreferences(), network)); m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir(), WithExisting::Trust, {"eth"/*, "shh"*/}, p2p::NetworkPreferences(), network));
m_httpConnector.reset(new jsonrpc::HttpServer(SensibleHttpPort, "", "", dev::SensibleHttpThreads)); m_httpConnector.reset(new jsonrpc::HttpServer(SensibleHttpPort, "", "", dev::SensibleHttpThreads));
m_server.reset(new OurWebThreeStubServer(*m_httpConnector, *web3(), this)); m_server.reset(new OurWebThreeStubServer(*m_httpConnector, *web3(), this));
@ -943,10 +943,21 @@ void Main::on_preview_triggered()
refreshAll(); refreshAll();
} }
void Main::on_prepNextDAG_triggered()
{
EthashAux::computeFull(ethereum()->blockChain().number() + ETHASH_EPOCH_LENGTH);
}
void Main::refreshMining() void Main::refreshMining()
{ {
pair<uint64_t, unsigned> gp = EthashAux::fullGeneratingProgress();
QString t;
if (gp.first != EthashAux::NotGenerating)
t = QString("DAG for #%1-#%2: %3% complete; ").arg(gp.first).arg(gp.first + ETHASH_EPOCH_LENGTH - 1).arg(gp.second);
MiningProgress p = ethereum()->miningProgress(); MiningProgress p = ethereum()->miningProgress();
ui->mineStatus->setText(ethereum()->isMining() ? QString("%1s @ %2kH/s").arg(p.ms / 1000).arg(p.ms ? p.hashes / p.ms : 0) : "Not mining"); ui->mineStatus->setText(t + (ethereum()->isMining() ? p.hashes > 0 ? QString("%1s @ %2kH/s").arg(p.ms / 1000).arg(p.ms ? p.hashes / p.ms : 0) : "Awaiting DAG" : "Not mining"));
if (ethereum()->isMining() && p.hashes > 0)
{
if (!ui->miningView->isVisible()) if (!ui->miningView->isVisible())
return; return;
list<MineInfo> l = ethereum()->miningHistory(); list<MineInfo> l = ethereum()->miningHistory();
@ -955,10 +966,7 @@ void Main::refreshMining()
ui->miningView->resetStats(); ui->miningView->resetStats();
lh = p.hashes; lh = p.hashes;
ui->miningView->appendStats(l, p); ui->miningView->appendStats(l, p);
/* if (p.ms) }
for (MineInfo const& i: l)
cnote << i.hashes * 10 << "h/sec, need:" << i.requirement << " best:" << i.best << " best-so-far:" << p.best << " avg-speed:" << (p.hashes * 1000 / p.ms) << "h/sec";
*/
} }
void Main::setBeneficiary(Address const& _b) void Main::setBeneficiary(Address const& _b)
@ -1878,6 +1886,7 @@ void Main::on_mine_triggered()
{ {
if (ui->mine->isChecked()) if (ui->mine->isChecked())
{ {
// EthashAux::computeFull(ethereum()->blockChain().number());
ethereum()->setAddress(m_beneficiary); ethereum()->setAddress(m_beneficiary);
ethereum()->startMining(); ethereum()->startMining();
} }
@ -2027,6 +2036,7 @@ std::string Main::prettyU256(dev::u256 const& _n) const
void Main::on_post_clicked() void Main::on_post_clicked()
{ {
return;
shh::Message m; shh::Message m;
m.setTo(stringToPublic(ui->shhTo->currentText())); m.setTo(stringToPublic(ui->shhTo->currentText()));
m.setPayload(parseData(ui->shhData->toPlainText().toStdString())); m.setPayload(parseData(ui->shhData->toPlainText().toStdString()));
@ -2051,6 +2061,7 @@ int Main::authenticate(QString _title, QString _text)
void Main::refreshWhispers() void Main::refreshWhispers()
{ {
return;
ui->whispers->clear(); ui->whispers->clear();
for (auto const& w: whisper()->all()) for (auto const& w: whisper()->all())
{ {

1
alethzero/MainWin.h

@ -124,6 +124,7 @@ private slots:
// Mining // Mining
void on_mine_triggered(); void on_mine_triggered();
void on_prepNextDAG_triggered();
// View // View
void on_refresh_triggered(); void on_refresh_triggered();

5
alethzero/Transact.cpp

@ -299,8 +299,9 @@ void Transact::rejigData()
return; return;
// Determine how much balance we have to play with... // Determine how much balance we have to play with...
auto s = findSecret(value() + ethereum()->gasLimitRemaining() * gasPrice()); //findSecret(value() + ethereum()->gasLimitRemaining() * gasPrice());
auto b = ethereum()->balanceAt(KeyPair(s).address(), PendingBlock); auto s = fromAccount();
auto b = ethereum()->balanceAt(s, PendingBlock);
m_allGood = true; m_allGood = true;
QString htmlInfo; QString htmlInfo;

107
eth/main.cpp

@ -158,6 +158,11 @@ void help()
<< " --port <port> Connect to remote port (default: 30303)." << endl << " --port <port> Connect to remote port (default: 30303)." << endl
<< " --network-id <n> Only connect to other hosts with this network id (default:0)." << endl << " --network-id <n> Only connect to other hosts with this network id (default:0)." << endl
<< " --upnp <on/off> Use UPnP for NAT (default: on)." << endl << " --upnp <on/off> Use UPnP for NAT (default: on)." << endl
<< endl
<< "Client structured logging:" << endl
<< " --structured-logging Enable structured logging (default output to stdout)." << endl
<< " --structured-logging-format <format> Set the structured logging time format." << endl
<< " --structured-logging-url <URL> Set the structured logging destination (currently only file:// supported)." << endl
#if ETH_JSONRPC || !ETH_TRUE #if ETH_JSONRPC || !ETH_TRUE
<< endl << endl
<< "Work farming mode:" << endl << "Work farming mode:" << endl
@ -806,8 +811,11 @@ int main(int argc, char** argv)
structuredLoggingFormat = string(argv[++i]); structuredLoggingFormat = string(argv[++i]);
else if (arg == "--structured-logging") else if (arg == "--structured-logging")
structuredLogging = true; structuredLogging = true;
else if (arg == "--structured-logging-destination" && i + 1 < argc) else if (arg == "--structured-logging-url" && i + 1 < argc)
{
structuredLogging = true;
structuredLoggingURL = argv[++i]; structuredLoggingURL = argv[++i];
}
else if ((arg == "-d" || arg == "--path" || arg == "--db-path") && i + 1 < argc) else if ((arg == "-d" || arg == "--path" || arg == "--db-path") && i + 1 < argc)
dbPath = argv[++i]; dbPath = argv[++i];
else if ((arg == "-D" || arg == "--create-dag") && i + 1 < argc) else if ((arg == "-D" || arg == "--create-dag") && i + 1 < argc)
@ -1033,6 +1041,28 @@ int main(int argc, char** argv)
if (!clientName.empty()) if (!clientName.empty())
clientName += "/"; clientName += "/";
string logbuf;
bool silence = false;
std::string additional;
g_logPost = [&](std::string const& a, char const*){
if (silence)
logbuf += a + "\n";
else
cout << "\r \r" << a << endl << additional << flush;
};
auto getPassword = [&](string const& prompt){
auto s = silence;
silence = true;
cout << endl;
string ret = dev::getPassword(prompt);
silence = s;
return ret;
};
auto getAccountPassword = [&](Address const& a){
return getPassword("Enter password for address " + keyManager.accountDetails()[a].first + " (" + a.abridged() + "; hint:" + keyManager.accountDetails()[a].second + "): ");
};
StructuredLogger::get().initialize(structuredLogging, structuredLoggingFormat, structuredLoggingURL); StructuredLogger::get().initialize(structuredLogging, structuredLoggingFormat, structuredLoggingURL);
VMFactory::setKind(jit ? VMKind::JIT : VMKind::Interpreter); VMFactory::setKind(jit ? VMKind::JIT : VMKind::Interpreter);
auto netPrefs = publicIP.empty() ? NetworkPreferences(listenIP ,listenPort, upnp) : NetworkPreferences(publicIP, listenIP ,listenPort, upnp); auto netPrefs = publicIP.empty() ? NetworkPreferences(listenIP ,listenPort, upnp) : NetworkPreferences(publicIP, listenIP ,listenPort, upnp);
@ -1042,13 +1072,38 @@ int main(int argc, char** argv)
clientImplString, clientImplString,
dbPath, dbPath,
killChain, killChain,
nodeMode == NodeMode::Full ? set<string>{"eth", "shh"} : set<string>(), nodeMode == NodeMode::Full ? set<string>{"eth"/*, "shh"*/} : set<string>(),
netPrefs, netPrefs,
&nodesState); &nodesState);
if (mode == OperationMode::DAGInit) if (mode == OperationMode::DAGInit)
doInitDAG(web3.ethereum()->blockChain().number() + (initDAG == PendingBlock ? 30000 : 0)); doInitDAG(web3.ethereum()->blockChain().number() + (initDAG == PendingBlock ? 30000 : 0));
if (keyManager.exists())
while (masterPassword.empty())
{
masterPassword = getPassword("Please enter your MASTER password: ");
if (!keyManager.load(masterPassword))
{
cout << "Password invalid. Try again." << endl;
masterPassword.clear();
}
}
else
{
while (masterPassword.empty())
{
masterPassword = getPassword("Please enter a MASTER password to protect your key store (make it strong!): ");
string confirm = getPassword("Please confirm the password by entering it again: ");
if (masterPassword != confirm)
{
cout << "Passwords were different. Try again." << endl;
masterPassword.clear();
}
}
keyManager.create(masterPassword);
}
auto toNumber = [&](string const& s) -> unsigned { auto toNumber = [&](string const& s) -> unsigned {
if (s == "latest") if (s == "latest")
return web3.ethereum()->number(); return web3.ethereum()->number();
@ -1137,53 +1192,13 @@ int main(int argc, char** argv)
if (remoteHost.size()) if (remoteHost.size())
web3.addNode(p2p::NodeId(), remoteHost + ":" + toString(remotePort)); web3.addNode(p2p::NodeId(), remoteHost + ":" + toString(remotePort));
if (keyManager.exists())
while (masterPassword.empty())
{
masterPassword = getPassword("Please enter your MASTER password: ");
if (!keyManager.load(masterPassword))
{
cout << "Password invalid. Try again." << endl;
masterPassword.clear();
}
}
else
{
while (masterPassword.empty())
{
masterPassword = getPassword("Please enter a MASTER password to protect your key store (make it strong!): ");
string confirm = getPassword("Please confirm the password by entering it again: ");
if (masterPassword != confirm)
{
cout << "Passwords were different. Try again." << endl;
masterPassword.clear();
}
}
keyManager.create(masterPassword);
}
string logbuf;
bool silence = false;
std::string additional;
g_logPost = [&](std::string const& a, char const*) { if (silence) logbuf += a + "\n"; else cout << "\r \r" << a << endl << additional << flush; };
// TODO: give hints &c.
auto getPassword = [&](Address const& a){
auto s = silence;
silence = true;
cout << endl;
string ret = dev::getPassword("Enter password for address " + keyManager.accountDetails()[a].first + " (" + a.abridged() + "; hint:" + keyManager.accountDetails()[a].second + "): ");
silence = s;
return ret;
};
#if ETH_JSONRPC || !ETH_TRUE #if ETH_JSONRPC || !ETH_TRUE
shared_ptr<WebThreeStubServer> jsonrpcServer; shared_ptr<WebThreeStubServer> jsonrpcServer;
unique_ptr<jsonrpc::AbstractServerConnector> jsonrpcConnector; unique_ptr<jsonrpc::AbstractServerConnector> jsonrpcConnector;
if (jsonrpc > -1) if (jsonrpc > -1)
{ {
jsonrpcConnector = unique_ptr<jsonrpc::AbstractServerConnector>(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads)); jsonrpcConnector = unique_ptr<jsonrpc::AbstractServerConnector>(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads));
jsonrpcServer = shared_ptr<WebThreeStubServer>(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared<SimpleAccountHolder>([&](){return web3.ethereum();}, getPassword, keyManager), vector<KeyPair>())); jsonrpcServer = shared_ptr<WebThreeStubServer>(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared<SimpleAccountHolder>([&](){return web3.ethereum();}, getAccountPassword, keyManager), vector<KeyPair>()));
jsonrpcServer->StartListening(); jsonrpcServer->StartListening();
} }
#endif #endif
@ -1327,7 +1342,7 @@ int main(int argc, char** argv)
if (jsonrpc < 0) if (jsonrpc < 0)
jsonrpc = SensibleHttpPort; jsonrpc = SensibleHttpPort;
jsonrpcConnector = unique_ptr<jsonrpc::AbstractServerConnector>(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads)); jsonrpcConnector = unique_ptr<jsonrpc::AbstractServerConnector>(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads));
jsonrpcServer = shared_ptr<WebThreeStubServer>(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared<SimpleAccountHolder>([&](){return web3.ethereum();}, getPassword, keyManager), vector<KeyPair>())); jsonrpcServer = shared_ptr<WebThreeStubServer>(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared<SimpleAccountHolder>([&](){return web3.ethereum();}, getAccountPassword, keyManager), vector<KeyPair>()));
jsonrpcServer->StartListening(); jsonrpcServer->StartListening();
} }
else if (cmd == "jsonstop") else if (cmd == "jsonstop")
@ -1479,7 +1494,7 @@ int main(int argc, char** argv)
try try
{ {
Address dest = h160(fromHex(hexAddr, WhenError::Throw)); Address dest = h160(fromHex(hexAddr, WhenError::Throw));
c->submitTransaction(keyManager.secret(signingKey, [&](){ return getPassword(signingKey); }), amount, dest, bytes(), minGas); c->submitTransaction(keyManager.secret(signingKey, [&](){ return getAccountPassword(signingKey); }), amount, dest, bytes(), minGas);
} }
catch (BadHexCharacter& _e) catch (BadHexCharacter& _e)
{ {
@ -1548,7 +1563,7 @@ int main(int argc, char** argv)
else if (gas < minGas) else if (gas < minGas)
cwarn << "Minimum gas amount is" << minGas; cwarn << "Minimum gas amount is" << minGas;
else else
c->submitTransaction(keyManager.secret(signingKey, [&](){ return getPassword(signingKey); }), endowment, init, gas, gasPrice); c->submitTransaction(keyManager.secret(signingKey, [&](){ return getAccountPassword(signingKey); }), endowment, init, gas, gasPrice);
} }
else else
cwarn << "Require parameters: contract ENDOWMENT GASPRICE GAS CODEHEX"; cwarn << "Require parameters: contract ENDOWMENT GASPRICE GAS CODEHEX";

8
libdevcore/Common.h

@ -199,12 +199,12 @@ private:
#define DEV_TIMED_FUNCTION DEV_TIMED_SCOPE(__PRETTY_FUNCTION__) #define DEV_TIMED_FUNCTION DEV_TIMED_SCOPE(__PRETTY_FUNCTION__)
#endif #endif
#define DEV_TIMED_IF(S, MS) for (::std::pair<::dev::TimerHelper, bool> __eth_t(::dev::TimerHelper(#S, MS), true); __eth_t.second; __eth_t.second = false) #define DEV_TIMED_ABOVE(S, MS) for (::std::pair<::dev::TimerHelper, bool> __eth_t(::dev::TimerHelper(#S, MS), true); __eth_t.second; __eth_t.second = false)
#define DEV_TIMED_SCOPE_IF(S) ::dev::TimerHelper __eth_t(S, MS) #define DEV_TIMED_SCOPE_ABOVE(S) ::dev::TimerHelper __eth_t(S, MS)
#if WIN32 #if WIN32
#define DEV_TIMED_FUNCTION_IF(MS) DEV_TIMED_SCOPE_IF(__FUNCSIG__, MS) #define DEV_TIMED_FUNCTION_ABOVE(MS) DEV_TIMED_SCOPE_ABOVE(__FUNCSIG__, MS)
#else #else
#define DEV_TIMED_FUNCTION_IF(MS) DEV_TIMED_SCOPE_IF(__PRETTY_FUNCTION__, MS) #define DEV_TIMED_FUNCTION_ABOVE(MS) DEV_TIMED_SCOPE_ABOVE(__PRETTY_FUNCTION__, MS)
#endif #endif
enum class WithExisting: int enum class WithExisting: int

10
libdevcore/Worker.cpp

@ -65,15 +65,15 @@ void Worker::startWorking()
m_state.exchange(ex); m_state.exchange(ex);
// cnote << "Waiting until not Stopped..."; // cnote << "Waiting until not Stopped...";
DEV_TIMED_IF(Worker stopping, 100) DEV_TIMED_ABOVE(Worker stopping, 100)
while (m_state == WorkerState::Stopped) while (m_state == WorkerState::Stopped)
this_thread::sleep_for(chrono::milliseconds(20)); this_thread::sleep_for(chrono::milliseconds(20));
} }
})); }));
// cnote << "Spawning" << m_name; // cnote << "Spawning" << m_name;
} }
DEV_TIMED_IF(Start worker, 100) DEV_TIMED_ABOVE(Start worker, 100)
while (m_state != WorkerState::Started) while (m_state == WorkerState::Starting)
this_thread::sleep_for(chrono::microseconds(20)); this_thread::sleep_for(chrono::microseconds(20));
} }
@ -85,7 +85,7 @@ void Worker::stopWorking()
WorkerState ex = WorkerState::Started; WorkerState ex = WorkerState::Started;
m_state.compare_exchange_strong(ex, WorkerState::Stopping); m_state.compare_exchange_strong(ex, WorkerState::Stopping);
DEV_TIMED_IF(Stop worker, 100) DEV_TIMED_ABOVE(Stop worker, 100)
while (m_state != WorkerState::Stopped) while (m_state != WorkerState::Stopped)
this_thread::sleep_for(chrono::microseconds(20)); this_thread::sleep_for(chrono::microseconds(20));
} }
@ -99,7 +99,7 @@ void Worker::terminate()
{ {
m_state.exchange(WorkerState::Killing); m_state.exchange(WorkerState::Killing);
DEV_TIMED_IF(Terminate worker, 100) DEV_TIMED_ABOVE(Terminate worker, 100)
m_work->join(); m_work->join();
m_work.reset(); m_work.reset();

6
libethcore/Ethash.cpp

@ -76,9 +76,9 @@ Ethash::WorkPackage Ethash::package(BlockInfo const& _bi)
return ret; return ret;
} }
void Ethash::prep(BlockInfo const& _header) void Ethash::prep(BlockInfo const& _header, std::function<int(unsigned)> const& _f)
{ {
EthashAux::full(_header); EthashAux::full((unsigned)_header.number, _f);
} }
bool Ethash::preVerify(BlockInfo const& _header) bool Ethash::preVerify(BlockInfo const& _header)
@ -310,6 +310,8 @@ void Ethash::GPUMiner::workLoop()
unsigned device = instances() > 1 ? index() : s_deviceId; unsigned device = instances() > 1 ? index() : s_deviceId;
if (!EthashAux::computeFull(w.blockNumber))
return;
EthashAux::FullType dag = EthashAux::full(w.blockNumber); EthashAux::FullType dag = EthashAux::full(w.blockNumber);
bytesConstRef dagData = dag->data(); bytesConstRef dagData = dag->data();
m_miner->init(dagData.data(), dagData.size(), 32, s_platformId, device); m_miner->init(dagData.data(), dagData.size(), 32, s_platformId, device);

2
libethcore/Ethash.h

@ -74,7 +74,7 @@ public:
static std::string name(); static std::string name();
static unsigned revision(); static unsigned revision();
static void prep(BlockInfo const& _header); static void prep(BlockInfo const& _header, std::function<int(unsigned)> const& _f = std::function<int(unsigned)>());
static bool verify(BlockInfo const& _header); static bool verify(BlockInfo const& _header);
static bool preVerify(BlockInfo const& _header); static bool preVerify(BlockInfo const& _header);
static WorkPackage package(BlockInfo const& _header); static WorkPackage package(BlockInfo const& _header);

38
libethcore/EthashAux.cpp

@ -149,11 +149,6 @@ bytesConstRef EthashAux::FullAllocation::data() const
return bytesConstRef((byte const*)ethash_full_dag(full), size()); return bytesConstRef((byte const*)ethash_full_dag(full), size());
} }
EthashAux::FullType EthashAux::full(BlockInfo const& _header, function<int(unsigned)> const& _f)
{
return full((uint64_t)_header.number, _f);
}
static std::function<int(unsigned)> s_dagCallback; static std::function<int(unsigned)> s_dagCallback;
static int dagCallbackShim(unsigned _p) static int dagCallbackShim(unsigned _p)
{ {
@ -167,18 +162,45 @@ EthashAux::FullType EthashAux::full(uint64_t _blockNumber, function<int(unsigned
h256 seedHash = EthashAux::seedHash(_blockNumber); h256 seedHash = EthashAux::seedHash(_blockNumber);
FullType ret; FullType ret;
Guard lock(get()->x_fulls); DEV_GUARDED(get()->x_fulls)
if ((ret = get()->m_fulls[seedHash].lock())) if ((ret = get()->m_fulls[seedHash].lock()))
{ {
get()->m_lastUsedFull = ret; get()->m_lastUsedFull = ret;
return ret; return ret;
} }
s_dagCallback = _f; s_dagCallback = _f;
ret = get()->m_lastUsedFull = make_shared<FullAllocation>(l->light, dagCallbackShim); ret = make_shared<FullAllocation>(l->light, dagCallbackShim);
get()->m_fulls[seedHash] = ret;
DEV_GUARDED(get()->x_fulls)
get()->m_fulls[seedHash] = get()->m_lastUsedFull = ret;
return ret; return ret;
} }
unsigned EthashAux::computeFull(uint64_t _blockNumber)
{
Guard l(get()->x_fulls);
h256 seedHash = EthashAux::seedHash(_blockNumber);
if (FullType ret = get()->m_fulls[seedHash].lock())
{
get()->m_lastUsedFull = ret;
return 100;
}
if (!get()->m_fullGenerator || !get()->m_fullGenerator->joinable())
{
get()->m_fullProgress = 0;
get()->m_generatingFullNumber = _blockNumber / ETHASH_EPOCH_LENGTH * ETHASH_EPOCH_LENGTH;
get()->m_fullGenerator = unique_ptr<thread>(new thread([=](){
get()->full(_blockNumber, [](unsigned p){ get()->m_fullProgress = p; return 0; });
get()->m_fullProgress = 0;
get()->m_generatingFullNumber = NotGenerating;
}));
}
return (get()->m_generatingFullNumber == _blockNumber) ? get()->m_fullProgress : 0;
}
Ethash::Result EthashAux::FullAllocation::compute(h256 const& _headerHash, Nonce const& _nonce) const Ethash::Result EthashAux::FullAllocation::compute(h256 const& _headerHash, Nonce const& _nonce) const
{ {
ethash_return_value_t r = ethash_full_compute(full, *(ethash_h256_t*)_headerHash.data(), (uint64_t)(u64)_nonce); ethash_return_value_t r = ethash_full_compute(full, *(ethash_h256_t*)_headerHash.data(), (uint64_t)(u64)_nonce);

14
libethcore/EthashAux.h

@ -19,7 +19,9 @@
* @date 2014 * @date 2014
*/ */
#include <condition_variable>
#include <libethash/ethash.h> #include <libethash/ethash.h>
#include <libdevcore/Worker.h>
#include "Ethash.h" #include "Ethash.h"
namespace dev namespace dev
@ -65,7 +67,13 @@ public:
static LightType light(BlockInfo const& _header); static LightType light(BlockInfo const& _header);
static LightType light(uint64_t _blockNumber); static LightType light(uint64_t _blockNumber);
static FullType full(BlockInfo const& _header, std::function<int(unsigned)> const& _f = std::function<int(unsigned)>());
static const uint64_t NotGenerating = (uint64_t)-1;
/// Kicks off generation of DAG for @a _blocknumber and @returns false or @returns true if ready.
static unsigned computeFull(uint64_t _blockNumber);
/// Information on the generation progress.
static std::pair<uint64_t, unsigned> fullGeneratingProgress() { return std::make_pair(get()->m_generatingFullNumber, get()->m_fullProgress); }
/// Kicks off generation of DAG for @a _blocknumber and blocks until ready; @returns result.
static FullType full(uint64_t _blockNumber, std::function<int(unsigned)> const& _f = std::function<int(unsigned)>()); static FullType full(uint64_t _blockNumber, std::function<int(unsigned)> const& _f = std::function<int(unsigned)>());
static Ethash::Result eval(BlockInfo const& _header) { return eval(_header, _header.nonce); } static Ethash::Result eval(BlockInfo const& _header) { return eval(_header, _header.nonce); }
@ -83,8 +91,12 @@ private:
std::unordered_map<h256, std::shared_ptr<LightAllocation>> m_lights; std::unordered_map<h256, std::shared_ptr<LightAllocation>> m_lights;
Mutex x_fulls; Mutex x_fulls;
std::condition_variable m_fullsChanged;
std::unordered_map<h256, std::weak_ptr<FullAllocation>> m_fulls; std::unordered_map<h256, std::weak_ptr<FullAllocation>> m_fulls;
FullType m_lastUsedFull; FullType m_lastUsedFull;
std::unique_ptr<std::thread> m_fullGenerator;
uint64_t m_generatingFullNumber = NotGenerating;
unsigned m_fullProgress;
Mutex x_epochs; Mutex x_epochs;
std::unordered_map<h256, unsigned> m_epochs; std::unordered_map<h256, unsigned> m_epochs;

4
libethereum/ClientBase.h

@ -84,11 +84,11 @@ public:
using Interface::submitTransaction; using Interface::submitTransaction;
/// Makes the given call. Nothing is recorded into the state. /// Makes the given call. Nothing is recorded into the state.
virtual ExecutionResult call(Address const& _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, BlockNumber _blockNumber = PendingBlock, FudgeFactor _ff = FudgeFactor::Strict) override; virtual ExecutionResult call(Address const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) override;
using Interface::call; using Interface::call;
/// Makes the given create. Nothing is recorded into the state. /// Makes the given create. Nothing is recorded into the state.
virtual ExecutionResult create(Address const& _secret, u256 _value, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, BlockNumber _blockNumber = PendingBlock, FudgeFactor _ff = FudgeFactor::Strict) override; virtual ExecutionResult create(Address const& _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) override;
using Interface::create; using Interface::create;
using Interface::balanceAt; using Interface::balanceAt;

4
libethereum/State.cpp

@ -515,10 +515,10 @@ pair<TransactionReceipts, bool> State::sync(BlockChain const& _bc, TransactionQu
cnote << i.first << "Dropping old transaction (nonce too low)"; cnote << i.first << "Dropping old transaction (nonce too low)";
_tq.drop(i.first); _tq.drop(i.first);
} }
else if (got > req + 5) else if (got > req + 25)
{ {
// too new // too new
cnote << i.first << "Dropping new transaction (> 5 nonces ahead)"; cnote << i.first << "Dropping new transaction (> 25 nonces ahead)";
_tq.drop(i.first); _tq.drop(i.first);
} }
else else

Loading…
Cancel
Save