|
|
@ -53,21 +53,6 @@ void VersionChecker::setOk() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Client::Client(std::string const& _clientVersion, Address _us, std::string const& _dbPath, bool _forceClean): |
|
|
|
m_clientVersion(_clientVersion), |
|
|
|
m_vc(_dbPath), |
|
|
|
m_bc(_dbPath, !m_vc.ok() || _forceClean), |
|
|
|
m_stateDB(State::openDB(_dbPath, !m_vc.ok() || _forceClean)), |
|
|
|
m_preMine(_us, m_stateDB), |
|
|
|
m_postMine(_us, m_stateDB) |
|
|
|
{ |
|
|
|
setMiningThreads(); |
|
|
|
if (_dbPath.size()) |
|
|
|
Defaults::setDBPath(_dbPath); |
|
|
|
m_vc.setOk(); |
|
|
|
work(); |
|
|
|
} |
|
|
|
|
|
|
|
Client::Client(p2p::Host* _extNet, std::string const& _dbPath, bool _forceClean, u256 _networkId): |
|
|
|
m_vc(_dbPath), |
|
|
|
m_bc(_dbPath, !m_vc.ok() || _forceClean), |
|
|
@ -107,7 +92,15 @@ Client::~Client() |
|
|
|
m_work->join(); |
|
|
|
m_work.reset(nullptr); |
|
|
|
} |
|
|
|
stopNetwork(); |
|
|
|
if (m_workNet) |
|
|
|
{ |
|
|
|
if (m_workNetState.load(std::memory_order_acquire) == Active) |
|
|
|
m_workNetState.store(Deleting, std::memory_order_release); |
|
|
|
while (m_workNetState.load(std::memory_order_acquire) != Deleted) |
|
|
|
this_thread::sleep_for(chrono::milliseconds(10)); |
|
|
|
m_workNet->join(); |
|
|
|
m_workNet.reset(nullptr); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void Client::ensureWorking() |
|
|
@ -143,21 +136,23 @@ void Client::killChain() |
|
|
|
|
|
|
|
void Client::clearPending() |
|
|
|
{ |
|
|
|
WriteGuard l(x_stateDB); |
|
|
|
if (!m_postMine.pending().size()) |
|
|
|
return; |
|
|
|
h256Set changeds; |
|
|
|
for (unsigned i = 0; i < m_postMine.pending().size(); ++i) |
|
|
|
appendFromNewPending(m_postMine.bloom(i), changeds); |
|
|
|
changeds.insert(PendingChangedFilter); |
|
|
|
m_postMine = m_preMine; |
|
|
|
{ |
|
|
|
WriteGuard l(x_stateDB); |
|
|
|
if (!m_postMine.pending().size()) |
|
|
|
return; |
|
|
|
for (unsigned i = 0; i < m_postMine.pending().size(); ++i) |
|
|
|
appendFromNewPending(m_postMine.bloom(i), changeds); |
|
|
|
changeds.insert(PendingChangedFilter); |
|
|
|
m_postMine = m_preMine; |
|
|
|
} |
|
|
|
|
|
|
|
if (!m_extHost.lock()) |
|
|
|
{ |
|
|
|
ReadGuard l(x_miners); |
|
|
|
for (auto& m: m_miners) |
|
|
|
m.noteStateChange(); |
|
|
|
} |
|
|
|
|
|
|
|
noteChanged(changeds); |
|
|
|
} |
|
|
|
|
|
|
@ -228,117 +223,14 @@ void Client::appendFromNewBlock(h256 _block, h256Set& o_changed) const |
|
|
|
o_changed.insert(i.first); |
|
|
|
} |
|
|
|
|
|
|
|
void Client::startNetwork(unsigned short _listenPort, std::string const& _seedHost, unsigned short _port, NodeMode _mode, unsigned _peers, string const& _publicIP, bool _upnp, u256 _networkId) |
|
|
|
{ |
|
|
|
static const char* c_threadName = "net"; |
|
|
|
|
|
|
|
{ |
|
|
|
UpgradableGuard l(x_net); |
|
|
|
if (m_net.get()) |
|
|
|
return; |
|
|
|
{ |
|
|
|
UpgradeGuard ul(l); |
|
|
|
|
|
|
|
if (!m_workNet) |
|
|
|
m_workNet.reset(new thread([&]() |
|
|
|
{ |
|
|
|
setThreadName(c_threadName); |
|
|
|
m_workNetState.store(Active, std::memory_order_release); |
|
|
|
while (m_workNetState.load(std::memory_order_acquire) != Deleting) |
|
|
|
workNet(); |
|
|
|
m_workNetState.store(Deleted, std::memory_order_release); |
|
|
|
})); |
|
|
|
|
|
|
|
if (!m_extHost.lock()) |
|
|
|
{ |
|
|
|
m_net.reset(new Host(m_clientVersion, NetworkPreferences(_listenPort, _publicIP, _upnp, false))); |
|
|
|
if (_mode == NodeMode::Full) |
|
|
|
m_net->registerCapability(new EthereumHost(m_bc, _networkId)); |
|
|
|
} |
|
|
|
} |
|
|
|
m_net->setIdealPeerCount(_peers); |
|
|
|
} |
|
|
|
|
|
|
|
if (!m_extHost.lock()) |
|
|
|
if (_seedHost.size()) |
|
|
|
connect(_seedHost, _port); |
|
|
|
|
|
|
|
ensureWorking(); |
|
|
|
} |
|
|
|
|
|
|
|
void Client::stopNetwork() |
|
|
|
{ |
|
|
|
UpgradableGuard l(x_net); |
|
|
|
|
|
|
|
if (m_workNet) |
|
|
|
{ |
|
|
|
if (m_workNetState.load(std::memory_order_acquire) == Active) |
|
|
|
m_workNetState.store(Deleting, std::memory_order_release); |
|
|
|
while (m_workNetState.load(std::memory_order_acquire) != Deleted) |
|
|
|
this_thread::sleep_for(chrono::milliseconds(10)); |
|
|
|
m_workNet->join(); |
|
|
|
} |
|
|
|
if (m_net) |
|
|
|
{ |
|
|
|
UpgradeGuard ul(l); |
|
|
|
m_net.reset(nullptr); |
|
|
|
m_workNet.reset(nullptr); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void Client::setNetworkId(u256 _n) |
|
|
|
{ |
|
|
|
if (auto h = m_extHost.lock()) |
|
|
|
h->setNetworkId(_n); |
|
|
|
} |
|
|
|
|
|
|
|
std::vector<PeerInfo> Client::peers() |
|
|
|
{ |
|
|
|
ReadGuard l(x_net); |
|
|
|
return m_net ? m_net->peers() : std::vector<PeerInfo>(); |
|
|
|
} |
|
|
|
|
|
|
|
size_t Client::peerCount() const |
|
|
|
{ |
|
|
|
ReadGuard l(x_net); |
|
|
|
return m_net ? m_net->peerCount() : 0; |
|
|
|
} |
|
|
|
|
|
|
|
void Client::setIdealPeerCount(size_t _n) const |
|
|
|
{ |
|
|
|
ReadGuard l(x_net); |
|
|
|
if (m_net) |
|
|
|
return m_net->setIdealPeerCount(_n); |
|
|
|
} |
|
|
|
|
|
|
|
bytes Client::savePeers() |
|
|
|
{ |
|
|
|
ReadGuard l(x_net); |
|
|
|
if (m_net) |
|
|
|
return m_net->savePeers(); |
|
|
|
return bytes(); |
|
|
|
} |
|
|
|
|
|
|
|
void Client::restorePeers(bytesConstRef _saved) |
|
|
|
{ |
|
|
|
ReadGuard l(x_net); |
|
|
|
if (m_net) |
|
|
|
return m_net->restorePeers(_saved); |
|
|
|
} |
|
|
|
|
|
|
|
void Client::connect(std::string const& _seedHost, unsigned short _port) |
|
|
|
{ |
|
|
|
ReadGuard l(x_net); |
|
|
|
if (!m_net.get()) |
|
|
|
return; |
|
|
|
m_net->connect(_seedHost, _port); |
|
|
|
} |
|
|
|
|
|
|
|
void Client::setMiningThreads(unsigned _threads) |
|
|
|
{ |
|
|
|
if (m_extHost.lock()) |
|
|
|
return; |
|
|
|
|
|
|
|
stopMining(); |
|
|
|
|
|
|
|
auto t = _threads ? _threads : thread::hardware_concurrency(); |
|
|
@ -353,8 +245,6 @@ void Client::setMiningThreads(unsigned _threads) |
|
|
|
MineProgress Client::miningProgress() const |
|
|
|
{ |
|
|
|
MineProgress ret; |
|
|
|
if (m_extHost.lock()) |
|
|
|
return ret; |
|
|
|
ReadGuard l(x_miners); |
|
|
|
for (auto& m: m_miners) |
|
|
|
ret.combine(m.miningProgress()); |
|
|
@ -364,8 +254,6 @@ MineProgress Client::miningProgress() const |
|
|
|
std::list<MineInfo> Client::miningHistory() |
|
|
|
{ |
|
|
|
std::list<MineInfo> ret; |
|
|
|
if (m_extHost.lock()) |
|
|
|
return ret; |
|
|
|
|
|
|
|
ReadGuard l(x_miners); |
|
|
|
if (m_miners.empty()) |
|
|
@ -479,23 +367,6 @@ void Client::workNet() |
|
|
|
// Process network events.
|
|
|
|
// Synchronise block chain with network.
|
|
|
|
// Will broadcast any of our (new) transactions and blocks, and collect & add any of their (new) transactions and blocks.
|
|
|
|
{ |
|
|
|
ReadGuard l(x_net); |
|
|
|
if (m_net) |
|
|
|
{ |
|
|
|
cwork << "NETWORK"; |
|
|
|
m_net->process(); // must be in guard for now since it uses the blockchain.
|
|
|
|
|
|
|
|
// returns h256Set as block hashes, once for each block that has come in/gone out.
|
|
|
|
if (m_net->cap<EthereumHost>()) |
|
|
|
{ |
|
|
|
cwork << "NET <==> TQ ; CHAIN ==> NET ==> BQ"; |
|
|
|
m_net->cap<EthereumHost>()->sync(m_tq, m_bq); |
|
|
|
cwork << "TQ:" << m_tq.items() << "; BQ:" << m_bq.items(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (auto h = m_extHost.lock()) |
|
|
|
h->sync(m_tq, m_bq); |
|
|
|
|
|
|
@ -509,7 +380,6 @@ void Client::work() |
|
|
|
cworkin << "WORK"; |
|
|
|
h256Set changeds; |
|
|
|
|
|
|
|
if (!m_extHost.lock()) |
|
|
|
{ |
|
|
|
ReadGuard l(x_miners); |
|
|
|
for (auto& m: m_miners) |
|
|
@ -580,7 +450,7 @@ void Client::work() |
|
|
|
rsm = true; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!m_extHost.lock() && rsm) |
|
|
|
if (rsm) |
|
|
|
{ |
|
|
|
ReadGuard l(x_miners); |
|
|
|
for (auto& m: m_miners) |
|
|
|