Browse Source

Pregenerate DAG when mining on AZ/eth/ethminer.

Use regeneratable key for decrets by default.
cl-refactor
Gav Wood 10 years ago
parent
commit
846de9acea
  1. 9
      ethminer/MinerAux.h
  2. 8
      libethcore/Ethash.cpp
  3. 1
      libethcore/Ethash.h
  4. 6
      libethereum/Client.cpp
  5. 36
      libethereum/Executive.cpp
  6. 1
      libethereum/Executive.h
  7. 10
      libethereum/ExtVM.cpp
  8. 2
      libethereum/ExtVM.h
  9. 3
      libethereum/KeyManager.cpp
  10. 10
      libethereum/KeyManager.h
  11. 14
      libevm/ExtVMFace.h
  12. 26
      libevm/VM.cpp
  13. 7
      test/libevm/vm.cpp
  14. 2
      test/libevm/vm.h

9
ethminer/MinerAux.h

@ -174,6 +174,10 @@ public:
m_minerType = MinerType::GPU; m_minerType = MinerType::GPU;
miningThreads = 1; miningThreads = 1;
} }
else if (arg == "--no-precompute")
{
precompute = false;
}
else if ((arg == "-D" || arg == "--create-dag") && i + 1 < argc) else if ((arg == "-D" || arg == "--create-dag") && i + 1 < argc)
{ {
string m = boost::to_lower_copy(string(argv[++i])); string m = boost::to_lower_copy(string(argv[++i]));
@ -268,6 +272,7 @@ public:
<< "Work farming mode:" << endl << "Work farming mode:" << endl
<< " -F,--farm <url> Put into mining farm mode with the work server at URL (default: http://127.0.0.1:8545)" << endl << " -F,--farm <url> Put into mining farm mode with the work server at URL (default: http://127.0.0.1:8545)" << endl
<< " --farm-recheck <n> Leave n ms between checks for changed work (default: 500)." << endl << " --farm-recheck <n> Leave n ms between checks for changed work (default: 500)." << endl
<< " --no-precompute Don't precompute the next epoch's DAG." << endl
#endif #endif
<< "Ethash verify mode:" << endl << "Ethash verify mode:" << endl
<< " -w,--check-pow <headerHash> <seedHash> <difficulty> <nonce> Check PoW credentials for validity." << endl << " -w,--check-pow <headerHash> <seedHash> <difficulty> <nonce> Check PoW credentials for validity." << endl
@ -423,6 +428,8 @@ private:
cnote << "Grabbing DAG for" << newSeedHash; cnote << "Grabbing DAG for" << newSeedHash;
if (!(dag = EthashAux::full(newSeedHash, true, [&](unsigned _pc){ cout << "\rCreating DAG. " << _pc << "% done..." << flush; return 0; }))) if (!(dag = EthashAux::full(newSeedHash, true, [&](unsigned _pc){ cout << "\rCreating DAG. " << _pc << "% done..." << flush; return 0; })))
BOOST_THROW_EXCEPTION(DAGCreationFailure()); BOOST_THROW_EXCEPTION(DAGCreationFailure());
if (precompute)
EthashAux::computeFull(sha3(newSeedHash), true);
if (hh != current.headerHash) if (hh != current.headerHash)
{ {
current.headerHash = hh; current.headerHash = hh;
@ -486,5 +493,5 @@ private:
/// Farm params /// Farm params
string farmURL = "http://127.0.0.1:8545"; string farmURL = "http://127.0.0.1:8545";
unsigned farmRecheckPeriod = 500; unsigned farmRecheckPeriod = 500;
bool precompute = true;
}; };

8
libethcore/Ethash.cpp

@ -75,6 +75,13 @@ Ethash::WorkPackage Ethash::package(BlockInfo const& _bi)
return ret; return ret;
} }
void Ethash::ensurePrecomputed(unsigned _number)
{
if (_number % ETHASH_EPOCH_LENGTH > ETHASH_EPOCH_LENGTH * 9 / 10)
// 90% of the way to the new epoch
EthashAux::computeFull(EthashAux::seedHash(_number + ETHASH_EPOCH_LENGTH), true);
}
void Ethash::prep(BlockInfo const& _header, std::function<int(unsigned)> const& _f) void Ethash::prep(BlockInfo const& _header, std::function<int(unsigned)> const& _f)
{ {
EthashAux::full(_header.seedHash(), true, _f); EthashAux::full(_header.seedHash(), true, _f);
@ -306,6 +313,7 @@ void Ethash::GPUMiner::workLoop()
cnote << "workLoop" << !!m_miner << m_minerSeed << w.seedHash; cnote << "workLoop" << !!m_miner << m_minerSeed << w.seedHash;
if (!m_miner || m_minerSeed != w.seedHash) if (!m_miner || m_minerSeed != w.seedHash)
{ {
cnote << "Initialising miner...";
m_minerSeed = w.seedHash; m_minerSeed = w.seedHash;
delete m_miner; delete m_miner;

1
libethcore/Ethash.h

@ -74,6 +74,7 @@ public:
static std::string name(); static std::string name();
static unsigned revision(); static unsigned revision();
static void prep(BlockInfo const& _header, std::function<int(unsigned)> const& _f = std::function<int(unsigned)>()); static void prep(BlockInfo const& _header, std::function<int(unsigned)> const& _f = std::function<int(unsigned)>());
static void ensurePrecomputed(unsigned _number);
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);

6
libethereum/Client.cpp

@ -457,11 +457,13 @@ ProofOfWork::WorkPackage Client::getWork()
// this will be reset as soon as a new block arrives, allowing more transactions to be processed. // this will be reset as soon as a new block arrives, allowing more transactions to be processed.
bool oldShould = shouldServeWork(); bool oldShould = shouldServeWork();
m_lastGetWork = chrono::system_clock::now(); m_lastGetWork = chrono::system_clock::now();
m_remoteWorking = true;
// if this request has made us bother to serve work, prep it now. // if this request has made us bother to serve work, prep it now.
if (!oldShould && shouldServeWork()) if (!oldShould && shouldServeWork())
onPostStateChanged(); onPostStateChanged();
else
// otherwise, set this to true so that it gets prepped next time.
m_remoteWorking = true;
return ProofOfWork::package(m_miningInfo); return ProofOfWork::package(m_miningInfo);
} }
@ -627,6 +629,8 @@ void Client::onPostStateChanged()
m_miningInfo = m_postMine.info(); m_miningInfo = m_postMine.info();
} }
m_farm.setWork(m_miningInfo); m_farm.setWork(m_miningInfo);
Ethash::ensurePrecomputed(m_bc.number());
} }
m_remoteWorking = false; m_remoteWorking = false;
} }

36
libethereum/Executive.cpp

@ -159,6 +159,42 @@ bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _sen
return !m_ext; return !m_ext;
} }
bool Executive::call(CallParameters const& _p, u256 const& _gasPrice, Address const& _origin)
{
m_isCreation = false;
// cnote << "Transferring" << formatBalance(_value) << "to receiver.";
auto it = !(_p.codeAddress & ~h160(0xffffffff)) ? precompiled().find((unsigned)(u160)_p.codeAddress) : precompiled().end();
if (it != precompiled().end())
{
bigint g = it->second.gas(_p.data);
if (_p.gas < g)
{
m_endGas = 0;
m_excepted = TransactionException::OutOfGasBase;
// Bail from exception.
return true; // true actually means "all finished - nothing more to be done regarding go().
}
else
{
m_endGas = (u256)(_p.gas - g);
m_precompiledOut = it->second.exec(_p.data);
m_out = &m_precompiledOut;
}
}
else if (m_s.addressHasCode(_p.codeAddress))
{
m_vm = VMFactory::create(_p.gas);
bytes const& c = m_s.code(_p.codeAddress);
m_ext = make_shared<ExtVM>(m_s, m_lastHashes, _p.receiveAddress, _p.senderAddress, _origin, _p.value, _gasPrice, _p.data, &c, m_depth);
}
else
m_endGas = _p.gas;
m_s.transferBalance(_p.senderAddress, _p.receiveAddress, _p.value);
return !m_ext;
}
bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _gas, bytesConstRef _init, Address _origin) bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _gas, bytesConstRef _init, Address _origin)
{ {
m_isCreation = true; m_isCreation = true;

1
libethereum/Executive.h

@ -95,6 +95,7 @@ public:
/// Set up the executive for evaluating a bare CALL (message call) operation. /// Set up the executive for evaluating a bare CALL (message call) operation.
/// @returns false iff go() must be called (and thus a VM execution in required). /// @returns false iff go() must be called (and thus a VM execution in required).
bool call(Address _myAddress, Address _codeAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256 _gas, Address _originAddress); bool call(Address _myAddress, Address _codeAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256 _gas, Address _originAddress);
bool call(CallParameters const& _cp, u256 const& _gasPrice, Address const& _origin);
/// Finalise an operation through accruing the substate into the parent context. /// Finalise an operation through accruing the substate into the parent context.
void accrueSubState(SubState& _parentContext); void accrueSubState(SubState& _parentContext);

10
libethereum/ExtVM.cpp

@ -26,16 +26,16 @@ using namespace std;
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;
bool ExtVM::call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData, u256& io_gas, bytesRef _out, OnOpFunc const& _onOp, Address _myAddressOverride, Address _codeAddressOverride) bool ExtVM::call(CallParameters& _p)
{ {
Executive e(m_s, lastHashes, depth + 1); Executive e(m_s, lastHashes, depth + 1);
if (!e.call(_receiveAddress, _codeAddressOverride, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, io_gas, origin)) if (!e.call(_p, gasPrice, origin))
{ {
e.go(_onOp); e.go(_p.onOp);
e.accrueSubState(sub); e.accrueSubState(sub);
} }
io_gas = e.endGas(); _p.gas = e.endGas();
e.out().copyTo(_out); e.out().copyTo(_p.out);
return !e.excepted(); return !e.excepted();
} }

2
libethereum/ExtVM.h

@ -58,7 +58,7 @@ public:
virtual h160 create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc const& _onOp = {}) override final; virtual h160 create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc const& _onOp = {}) override final;
/// Create a new message call. Leave _myAddressOverride as the default to use the present address as caller. /// Create a new message call. Leave _myAddressOverride as the default to use the present address as caller.
virtual bool call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData, u256& io_gas, bytesRef _out, OnOpFunc const& _onOp = {}, Address _myAddressOverride = {}, Address _codeAddressOverride = {}) override final; virtual bool call(CallParameters& _params) override final;
/// Read address's balance. /// Read address's balance.
virtual u256 balance(Address _a) override final { return m_s.balance(_a); } virtual u256 balance(Address _a) override final { return m_s.balance(_a); }

3
libethereum/KeyManager.cpp

@ -71,6 +71,7 @@ bool KeyManager::load(std::string const& _pass)
m_password = (string)s[3]; m_password = (string)s[3];
} }
m_cachedPasswords[hashPassword(m_password)] = m_password; m_cachedPasswords[hashPassword(m_password)] = m_password;
m_cachedPasswords[hashPassword(defaultPassword())] = defaultPassword();
return true; return true;
} }
catch (...) { catch (...) {
@ -214,4 +215,6 @@ void KeyManager::write(h128 const& _key, std::string const& _keysFile) const
writeFile(_keysFile, encryptSymNoAuth(_key, h128(), &s.out())); writeFile(_keysFile, encryptSymNoAuth(_key, h128(), &s.out()));
m_key = _key; m_key = _key;
m_cachedPasswords[hashPassword(defaultPassword())] = defaultPassword();
} }

10
libethereum/KeyManager.h

@ -75,10 +75,11 @@ public:
Address address(h128 const& _uuid) const; Address address(h128 const& _uuid) const;
h128 import(Secret const& _s, std::string const& _info, std::string const& _pass, std::string const& _passInfo); h128 import(Secret const& _s, std::string const& _info, std::string const& _pass, std::string const& _passInfo);
h128 import(Secret const& _s, std::string const& _info) { return import(_s, _info, m_password, std::string()); } h128 import(Secret const& _s, std::string const& _info) { return import(_s, _info, defaultPassword(), std::string()); }
SecretStore& store() { return m_store; } SecretStore& store() { return m_store; }
void importExisting(h128 const& _uuid, std::string const& _info, std::string const& _pass, std::string const& _passInfo); void importExisting(h128 const& _uuid, std::string const& _info, std::string const& _pass, std::string const& _passInfo);
void importExisting(h128 const& _uuid, std::string const& _info) { importExisting(_uuid, _info, defaultPassword(), std::string()); }
Secret secret(Address const& _address, std::function<std::string()> const& _pass = DontKnowThrow) const; Secret secret(Address const& _address, std::function<std::string()> const& _pass = DontKnowThrow) const;
Secret secret(h128 const& _uuid, std::function<std::string()> const& _pass = DontKnowThrow) const; Secret secret(h128 const& _uuid, std::function<std::string()> const& _pass = DontKnowThrow) const;
@ -87,6 +88,7 @@ public:
void kill(Address const& _a); void kill(Address const& _a);
private: private:
std::string defaultPassword() const { return asString(m_key.ref()); }
h256 hashPassword(std::string const& _pass) const; h256 hashPassword(std::string const& _pass) const;
// Only use if previously loaded ok. // Only use if previously loaded ok.
@ -103,7 +105,11 @@ private:
// Passwords that we're storing. // Passwords that we're storing.
mutable std::unordered_map<h256, std::string> m_cachedPasswords; mutable std::unordered_map<h256, std::string> m_cachedPasswords;
// The default password for keys in the keystore - protected by the master password. // DEPRECATED.
// Used to be the default password for keys in the keystore, stored in the keys file.
// Now the default password is based off the key of the keys file directly, so this is redundant
// except for the fact that people have existing keys stored with it. Leave for now until/unless
// we have an upgrade strategy.
std::string m_password; std::string m_password;
SecretStore m_store; SecretStore m_store;

14
libevm/ExtVMFace.h

@ -108,6 +108,18 @@ using LastHashes = std::vector<h256>;
using OnOpFunc = std::function<void(uint64_t /*steps*/, Instruction /*instr*/, bigint /*newMemSize*/, bigint /*gasCost*/, VM*, ExtVMFace const*)>; using OnOpFunc = std::function<void(uint64_t /*steps*/, Instruction /*instr*/, bigint /*newMemSize*/, bigint /*gasCost*/, VM*, ExtVMFace const*)>;
struct CallParameters
{
Address senderAddress;
Address codeAddress;
Address receiveAddress;
u256 gas;
u256 value;
bytesConstRef data;
bytesRef out;
OnOpFunc onOp;
};
/** /**
* @brief Interface and null implementation of the class for specifying VM externalities. * @brief Interface and null implementation of the class for specifying VM externalities.
*/ */
@ -153,7 +165,7 @@ public:
virtual h160 create(u256, u256&, bytesConstRef, OnOpFunc const&) { return h160(); } virtual h160 create(u256, u256&, bytesConstRef, OnOpFunc const&) { return h160(); }
/// Make a new message call. /// Make a new message call.
virtual bool call(Address, u256, bytesConstRef, u256&, bytesRef, OnOpFunc const&, Address, Address) { return false; } virtual bool call(CallParameters&) { return false; }
/// Revert any changes made (by any of the other calls). /// Revert any changes made (by any of the other calls).
virtual void log(h256s&& _topics, bytesConstRef _data) { sub.logs.push_back(LogEntry(myAddress, std::move(_topics), _data.toBytes())); } virtual void log(h256s&& _topics, bytesConstRef _data) { sub.logs.push_back(LogEntry(myAddress, std::move(_topics), _data.toBytes())); }

26
libevm/VM.cpp

@ -56,6 +56,8 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps)
{ {
m_stack.reserve((unsigned)c_stackLimit); m_stack.reserve((unsigned)c_stackLimit);
unique_ptr<CallParameters> callParams;
static const array<InstructionMetric, 256> c_metrics = metrics(); static const array<InstructionMetric, 256> c_metrics = metrics();
auto memNeed = [](u256 _offset, dev::u256 _size) { return _size ? (bigint)_offset + _size : (bigint)0; }; auto memNeed = [](u256 _offset, dev::u256 _size) { return _size ? (bigint)_offset + _size : (bigint)0; };
@ -626,13 +628,16 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps)
case Instruction::CALL: case Instruction::CALL:
case Instruction::CALLCODE: case Instruction::CALLCODE:
{ {
u256 gas = m_stack.back(); if (!callParams)
callParams.reset(new CallParameters);
callParams->gas = m_stack.back();
if (m_stack[m_stack.size() - 3] > 0) if (m_stack[m_stack.size() - 3] > 0)
gas += c_callStipend; callParams->gas += c_callStipend;
m_stack.pop_back(); m_stack.pop_back();
Address receiveAddress = asAddress(m_stack.back()); callParams->receiveAddress = asAddress(m_stack.back());
m_stack.pop_back(); m_stack.pop_back();
u256 value = m_stack.back(); callParams->value = m_stack.back();
m_stack.pop_back(); m_stack.pop_back();
unsigned inOff = (unsigned)m_stack.back(); unsigned inOff = (unsigned)m_stack.back();
@ -644,12 +649,19 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps)
unsigned outSize = (unsigned)m_stack.back(); unsigned outSize = (unsigned)m_stack.back();
m_stack.pop_back(); m_stack.pop_back();
if (_ext.balance(_ext.myAddress) >= value && _ext.depth < 1024) if (_ext.balance(_ext.myAddress) >= callParams->value && _ext.depth < 1024)
m_stack.push_back(_ext.call(inst == Instruction::CALL ? receiveAddress : _ext.myAddress, value, bytesConstRef(m_temp.data() + inOff, inSize), gas, bytesRef(m_temp.data() + outOff, outSize), _onOp, {}, receiveAddress)); {
callParams->onOp = _onOp;
callParams->senderAddress = _ext.myAddress;
callParams->codeAddress = inst == Instruction::CALL ? callParams->receiveAddress : callParams->senderAddress;
callParams->data = bytesConstRef(m_temp.data() + inOff, inSize);
callParams->out = bytesRef(m_temp.data() + outOff, outSize);
m_stack.push_back(_ext.call(*callParams));
}
else else
m_stack.push_back(0); m_stack.push_back(0);
m_gas += gas; m_gas += callParams->gas;
break; break;
} }
case Instruction::RETURN: case Instruction::RETURN:

7
test/libevm/vm.cpp

@ -44,13 +44,10 @@ h160 FakeExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _init, OnOpF
return na; return na;
} }
bool FakeExtVM::call(Address _receiveAddress, u256 _value, bytesConstRef _data, u256& io_gas, bytesRef _out, OnOpFunc const&, Address _myAddressOverride, Address _codeAddressOverride) bool FakeExtVM::call(CallParameters& _p)
{ {
Transaction t(_value, gasPrice, io_gas, _receiveAddress, _data.toVector()); Transaction t(_p.value, gasPrice, _p.gas, _p.receiveAddress, _p.data.toVector());
callcreates.push_back(t); callcreates.push_back(t);
(void)_out;
(void)_myAddressOverride;
(void)_codeAddressOverride;
return true; return true;
} }

2
test/libevm/vm.h

@ -59,7 +59,7 @@ public:
virtual void suicide(Address _a) override { std::get<0>(addresses[_a]) += std::get<0>(addresses[myAddress]); addresses.erase(myAddress); } virtual void suicide(Address _a) override { std::get<0>(addresses[_a]) += std::get<0>(addresses[myAddress]); addresses.erase(myAddress); }
virtual bytes const& codeAt(Address _a) override { return std::get<3>(addresses[_a]); } virtual bytes const& codeAt(Address _a) override { return std::get<3>(addresses[_a]); }
virtual h160 create(u256 _endowment, u256& io_gas, bytesConstRef _init, eth::OnOpFunc const&) override; virtual h160 create(u256 _endowment, u256& io_gas, bytesConstRef _init, eth::OnOpFunc const&) override;
virtual bool call(Address _receiveAddress, u256 _value, bytesConstRef _data, u256& io_gas, bytesRef _out, eth::OnOpFunc const&, Address, Address) override; virtual bool call(eth::CallParameters&) override;
void setTransaction(Address _caller, u256 _value, u256 _gasPrice, bytes const& _data); void setTransaction(Address _caller, u256 _value, u256 _gasPrice, bytes const& _data);
void setContract(Address _myAddress, u256 _myBalance, u256 _myNonce, std::map<u256, u256> const& _storage, bytes const& _code); void setContract(Address _myAddress, u256 _myBalance, u256 _myNonce, std::map<u256, u256> const& _storage, bytes const& _code);
void set(Address _a, u256 _myBalance, u256 _myNonce, std::map<u256, u256> const& _storage, bytes const& _code); void set(Address _a, u256 _myBalance, u256 _myNonce, std::map<u256, u256> const& _storage, bytes const& _code);

Loading…
Cancel
Save