Browse Source

Beginning of merge into AZ.

cl-refactor
Gav Wood 10 years ago
parent
commit
484279c548
  1. 11
      alethzero/MainWin.cpp
  2. 2
      alethzero/MainWin.h
  3. 2
      exp/main.cpp
  4. 29
      libethereum/Client.cpp
  5. 2
      libethereum/Client.h
  6. 3
      libethereum/EthereumHost.cpp
  7. 3
      libethereum/EthereumHost.h
  8. 85
      libp2p/Host.cpp
  9. 27
      libp2p/Host.h
  10. 1
      libp2p/HostCapability.h
  11. 2
      libp2p/Session.cpp
  12. 42
      libwebthree/WebThree.cpp
  13. 12
      libwebthree/WebThree.h
  14. 2
      test/peer.cpp

11
alethzero/MainWin.cpp

@ -79,7 +79,6 @@ static QString fromRaw(dev::h256 _n, unsigned* _inc = nullptr)
return QString();
}
Address c_config = Address("661005d2720d855f1d9976f88bb10c1a3398c77f");
Main::Main(QWidget *parent) :
@ -142,7 +141,7 @@ Main::Main(QWidget *parent) :
connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved()));
m_webThree.reset(new WebThreeDirect("AlethZero", getDataDir() + "/AlethZero", false));
m_webThree.reset(new WebThreeDirect("AlethZero", getDataDir() + "/AlethZero", false, {"eth", "shh"}));
connect(ui->webView, &QWebView::loadStarted, [this]()
{
@ -191,6 +190,11 @@ Main::~Main()
writeSettings();
}
dev::p2p::NetworkPreferences Main::netPrefs() const
{
return NetworkPreferences(ui->port->value(), ui->forceAddress->text().toStdString(), ui->upnp->isChecked(), false);
}
void Main::onKeysChanged()
{
installBalancesWatch();
@ -1483,6 +1487,9 @@ void Main::on_net_triggered()
{
// TODO: alter network stuff?
//ui->port->value(), string(), 0, NodeMode::Full, ui->idealPeers->value(), ui->forceAddress->text().toStdString(), ui->upnp->isChecked(), m_privateChain.size() ? sha3(m_privateChain.toStdString()) : 0
web3()->setIdealPeerCount(ui->idealPeers->value());
web3()->setNetworkPreferences(netPrefs());
ethereum()->setNetworkId(m_privateChain.size() ? sha3(m_privateChain.toStdString()) : 0);
web3()->startNetwork();
if (m_peers.size() && ui->usePast->isChecked())
web3()->restorePeers(bytesConstRef((byte*)m_peers.data(), m_peers.size()));

2
alethzero/MainWin.h

@ -149,6 +149,8 @@ signals:
void poll();
private:
dev::p2p::NetworkPreferences netPrefs() const;
QString pretty(dev::Address _a) const;
QString prettyU256(dev::u256 _n) const;

2
exp/main.cpp

@ -322,7 +322,7 @@ int main(int argc, char** argv)
remoteHost = argv[i];
}
Host ph("Test", listenPort, "", false, true);
Host ph("Test", NetworkPreferences(listenPort, "", false, true));
ph.registerCapability(new WhisperHost());
auto wh = ph.cap<WhisperHost>();

29
libethereum/Client.cpp

@ -82,6 +82,18 @@ Client::Client(p2p::Host* _extNet, std::string const& _dbPath, bool _forceClean,
Defaults::setDBPath(_dbPath);
m_vc.setOk();
work();
static const char* c_threadName = "ethsync";
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);
}));
ensureWorking();
}
Client::~Client()
@ -239,16 +251,7 @@ void Client::startNetwork(unsigned short _listenPort, std::string const& _seedHo
if (!m_extHost.lock())
{
try
{
m_net.reset(new Host(m_clientVersion, _listenPort, _publicIP, _upnp));
}
catch (std::exception const&)
{
// Probably already have the port open.
cwarn << "Could not initialize with specified/default port. Trying system-assigned port";
m_net.reset(new Host(m_clientVersion, 0, _publicIP, _upnp));
}
m_net.reset(new Host(m_clientVersion, NetworkPreferences(_listenPort, _publicIP, _upnp, false)));
if (_mode == NodeMode::Full)
m_net->registerCapability(new EthereumHost(m_bc, _networkId));
}
@ -283,6 +286,12 @@ void Client::stopNetwork()
}
}
void Client::setNetworkId(u256 _n)
{
if (auto h = m_extHost.lock())
h->setNetworkId(_n);
}
std::vector<PeerInfo> Client::peers()
{
ReadGuard l(x_net);

2
libethereum/Client.h

@ -259,6 +259,8 @@ public:
// Debug stuff:
/// Sets the network id.
void setNetworkId(u256 _n);
/// Clears pending transactions. Just for debug use.
void clearPending();
/// Kills the blockchain. Just for debug use.

3
libethereum/EthereumHost.cpp

@ -44,6 +44,7 @@ EthereumHost::EthereumHost(BlockChain const& _ch, u256 _networkId):
m_chain (&_ch),
m_networkId (_networkId)
{
m_latestBlockSent = _ch.currentHash();
}
EthereumHost::~EthereumHost()
@ -78,7 +79,7 @@ h256Set EthereumHost::neededBlocks(h256Set const& _exclude)
bool EthereumHost::ensureInitialised(TransactionQueue& _tq)
{
if (m_latestBlockSent == h256())
if (!m_latestBlockSent)
{
// First time - just initialise.
m_latestBlockSent = m_chain->currentHash();

3
libethereum/EthereumHost.h

@ -62,6 +62,7 @@ public:
unsigned protocolVersion() const { return c_protocolVersion; }
u256 networkId() const { return m_networkId; }
void setNetworkId(u256 _n) { m_networkId = _n; }
/// Sync with the BlockChain. It might contain one of our mined blocks, we might have new candidates from the network.
bool sync(TransactionQueue&, BlockQueue& _bc);
@ -84,7 +85,7 @@ private:
h256Set neededBlocks(h256Set const& _exclude);
/// Check to see if the network peer-state initialisation has happened.
virtual bool isInitialised() const { return m_latestBlockSent; }
bool isInitialised() const { return m_latestBlockSent; }
/// Initialises the network peer-state, doing the stuff that needs to be once-only. @returns true if it really was first.
bool ensureInitialised(TransactionQueue& _tq);

85
libp2p/Host.cpp

@ -54,55 +54,69 @@ static const set<bi::address> c_rejectAddresses = {
{bi::address_v6::from_string("::")}
};
Host::Host(std::string const& _clientVersion, unsigned short _port, string const& _publicAddress, bool _upnp, bool _localNetworking):
Host::Host(std::string const& _clientVersion, NetworkPreferences const& _n, bool _start):
m_clientVersion(_clientVersion),
m_listenPort(_port),
m_localNetworking(_localNetworking),
m_acceptor(m_ioService, bi::tcp::endpoint(bi::tcp::v4(), _port)),
m_netPrefs(_n),
m_acceptor(m_ioService),
m_socket(m_ioService),
m_id(h512::random())
{
populateAddresses();
determinePublic(_publicAddress, _upnp);
ensureAccepting();
m_lastPeersRequest = chrono::steady_clock::time_point::min();
clog(NetNote) << "Id:" << m_id.abridged();
if (_start)
start();
}
Host::Host(std::string const& _clientVersion, string const& _publicAddress, bool _upnp, bool _localNetworking):
m_clientVersion(_clientVersion),
m_listenPort(0),
m_localNetworking(_localNetworking),
m_acceptor(m_ioService, bi::tcp::endpoint(bi::tcp::v4(), 0)),
m_socket(m_ioService),
m_id(h512::random())
Host::~Host()
{
m_listenPort = m_acceptor.local_endpoint().port();
// populate addresses.
populateAddresses();
determinePublic(_publicAddress, _upnp);
ensureAccepting();
m_lastPeersRequest = chrono::steady_clock::time_point::min();
clog(NetNote) << "Id:" << m_id.abridged();
disconnectPeers();
stop();
}
Host::Host(std::string const& _clientVersion):
m_clientVersion(_clientVersion),
m_listenPort(0),
m_acceptor(m_ioService, bi::tcp::endpoint(bi::tcp::v4(), 0)),
m_socket(m_ioService),
m_id(h512::random())
void Host::start()
{
// populate addresses.
populateAddresses();
stop();
for (unsigned i = 0; i < 2; ++i)
{
bi::tcp::endpoint endpoint(bi::tcp::v4(), i ? 0 : m_netPrefs.listenPort);
try
{
m_acceptor.open(endpoint.protocol());
m_acceptor.set_option(ba::socket_base::reuse_address(true));
m_acceptor.bind(endpoint);
m_acceptor.listen();
}
catch (...)
{
if (i)
{
cwarn << "Couldn't start accepting connections on host. Something very wrong with network?";
return;
}
m_acceptor.close();
continue;
}
}
m_listenPort = m_acceptor.local_endpoint().port();
determinePublic(m_netPrefs.publicIP, m_netPrefs.upnp);
ensureAccepting();
m_lastPeersRequest = chrono::steady_clock::time_point::min();
clog(NetNote) << "Id:" << m_id.abridged();
}
Host::~Host()
void Host::stop()
{
disconnectPeers();
if (m_acceptor.is_open())
{
if (m_accepting)
m_acceptor.cancel();
m_acceptor.close();
m_accepting = false;
}
if (m_socket.is_open())
m_socket.close();
}
unsigned Host::protocolVersion() const
@ -284,7 +298,7 @@ std::map<h512, bi::tcp::endpoint> Host::potentialPeers()
{
auto ep = j->endpoint();
// Skip peers with a listen port of zero or are on a private network
bool peerOnNet = (j->m_listenPort != 0 && (!isPrivateAddress(ep.address()) || m_localNetworking));
bool peerOnNet = (j->m_listenPort != 0 && (!isPrivateAddress(ep.address()) || m_netPrefs.localNetworking));
if (peerOnNet && ep.port() && j->m_id)
ret.insert(make_pair(i.first, ep));
}
@ -293,7 +307,7 @@ std::map<h512, bi::tcp::endpoint> Host::potentialPeers()
void Host::ensureAccepting()
{
if (m_accepting == false)
if (!m_accepting)
{
clog(NetConnect) << "Listening on local port " << m_listenPort << " (public: " << m_public << ")";
m_accepting = true;
@ -315,7 +329,7 @@ void Host::ensureAccepting()
clog(NetWarn) << "ERROR: " << _e.what();
}
m_accepting = false;
if (ec.value() != 1)
if (ec.value() < 1)
ensureAccepting();
});
}
@ -459,9 +473,6 @@ std::vector<PeerInfo> Host::peers(bool _updatePing) const
void Host::process()
{
for (auto const& i: m_capabilities)
if (!i.second->isInitialised())
return;
growPeers();
prunePeers();
m_ioService.poll();

27
libp2p/Host.h

@ -41,6 +41,16 @@ class RLPStream;
namespace p2p
{
struct NetworkPreferences
{
NetworkPreferences(unsigned short p = 30303, std::string i = std::string(), bool u = true, bool l = false): listenPort(p), publicIP(i), upnp(u), localNetworking(l) {}
unsigned short listenPort = 30303;
std::string publicIP;
bool upnp = true;
bool localNetworking = false;
};
/**
* @brief The Host class
* Capabilities should be registered prior to startNetwork, since m_capabilities is not thread-safe.
@ -52,11 +62,7 @@ class Host
public:
/// Start server, listening for connections on the given port.
Host(std::string const& _clientVersion, unsigned short _port, std::string const& _publicAddress = std::string(), bool _upnp = true, bool _localNetworking = false);
/// Start server, listening for connections on a system-assigned port.
Host(std::string const& _clientVersion, std::string const& _publicAddress = std::string(), bool _upnp = true, bool _localNetworking = false);
/// Start server, but don't listen.
Host(std::string const& _clientVersion);
Host(std::string const& _clientVersion, NetworkPreferences const& _n = NetworkPreferences(), bool _start = false);
/// Will block on network process events.
virtual ~Host();
@ -107,6 +113,11 @@ public:
/// Deserialise the data and populate the set of known peers.
void restorePeers(bytesConstRef _b);
void setNetworkPreferences(NetworkPreferences const& _p) { stop(); m_netPrefs = _p; start(); }
void start();
void stop();
h512 id() const { return m_id; }
void registerPeer(std::shared_ptr<Session> _s, std::vector<std::string> const& _caps);
@ -127,8 +138,10 @@ protected:
std::string m_clientVersion;
unsigned short m_listenPort;
bool m_localNetworking = false;
NetworkPreferences m_netPrefs;
static const int NetworkStopped = -1;
int m_listenPort = NetworkStopped;
ba::io_service m_ioService;
bi::tcp::acceptor m_acceptor;

1
libp2p/HostCapability.h

@ -48,7 +48,6 @@ public:
protected:
virtual std::string name() const = 0;
virtual Capability* newPeerCapability(Session* _s) = 0;
virtual bool isInitialised() const { return true; }
void seal(bytes& _b);

2
libp2p/Session.cpp

@ -159,7 +159,7 @@ bool Session::interpret(RLP const& _r)
bi::address_v4 peerAddress(_r[i][0].toHash<FixedHash<4>>().asArray());
auto ep = bi::tcp::endpoint(peerAddress, _r[i][1].toInt<short>());
h512 id = _r[i][2].toHash<h512>();
if (isPrivateAddress(peerAddress) && !m_server->m_localNetworking)
if (isPrivateAddress(peerAddress) && !m_server->m_netPrefs.localNetworking)
goto CONTINUE;
clogS(NetAllDetail) << "Checking: " << ep << "(" << id.abridged() << ")";

42
libwebthree/WebThree.cpp

@ -35,20 +35,30 @@ using namespace dev::p2p;
using namespace dev::eth;
using namespace dev::shh;
WebThreeDirect::WebThreeDirect(std::string const& _clientVersion, std::string const& _dbPath, bool _forceClean, std::set<std::string> const& _interfaces, unsigned short _listenPort, std::string const& _publicIP, bool _upnp, dev::u256 _networkId, bool _localNetworking):
WebThreeDirect::WebThreeDirect(std::string const& _clientVersion, std::string const& _dbPath, bool _forceClean, std::set<std::string> const& _interfaces, NetworkPreferences const& _n):
m_clientVersion(_clientVersion),
m_net(m_clientVersion, _listenPort, _publicIP, _upnp, _localNetworking)
m_net(_clientVersion, _n)
{
if (_dbPath.size())
Defaults::setDBPath(_dbPath);
if (_interfaces.count("eth"))
m_ethereum.reset(new eth::Client(&m_net, _dbPath, _forceClean, _networkId));
m_ethereum.reset(new eth::Client(&m_net, _dbPath, _forceClean));
// if (_interfaces.count("shh"))
// m_whisper = new eth::Whisper(m_net.get());
}
WebThreeDirect::~WebThreeDirect()
{
stopNetwork();
}
void WebThreeDirect::startNetwork()
{
static const char* c_threadName = "p2p";
static const char* c_threadName = "net";
m_net.start();
UpgradableGuard l(x_work);
{
@ -60,15 +70,20 @@ WebThreeDirect::WebThreeDirect(std::string const& _clientVersion, std::string co
setThreadName(c_threadName);
m_workState.store(Active, std::memory_order_release);
while (m_workState.load(std::memory_order_acquire) != Deleting)
workNet();
{
this_thread::sleep_for(chrono::milliseconds(1));
ReadGuard l(x_work);
m_net.process(); // must be in guard for now since it uses the blockchain.
}
m_workState.store(Deleted, std::memory_order_release);
}));
}
}
WebThreeDirect::~WebThreeDirect()
void WebThreeDirect::stopNetwork()
{
m_net.stop();
UpgradableGuard l(x_work);
if (m_work)
@ -121,16 +136,3 @@ void WebThreeDirect::connect(std::string const& _seedHost, unsigned short _port)
ReadGuard l(x_work);
m_net.connect(_seedHost, _port);
}
void WebThreeDirect::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_work);
m_net.process(); // must be in guard for now since it uses the blockchain.
}
this_thread::sleep_for(chrono::milliseconds(1));
}

12
libwebthree/WebThree.h

@ -66,7 +66,7 @@ class WebThreeDirect
public:
/// Constructor for private instance. If there is already another process on the machine using @a _dbPath, then this will throw an exception.
/// ethereum() may be safely static_cast()ed to a eth::Client*.
WebThreeDirect(std::string const& _clientVersion, std::string const& _dbPath, bool _forceClean = false, std::set<std::string> const& _interfaces = {"eth", "shh"}, unsigned short _listenPort = 30303, std::string const& _publicIP = std::string(), bool _upnp = true, dev::u256 _networkId = 0, bool _localNetworking = false);
WebThreeDirect(std::string const& _clientVersion, std::string const& _dbPath, bool _forceClean = false, std::set<std::string> const& _interfaces = {"eth", "shh"}, p2p::NetworkPreferences const& _n = p2p::NetworkPreferences());
/// Destructor.
~WebThreeDirect();
@ -104,16 +104,15 @@ public:
/// Sets the ideal number of peers.
void setIdealPeerCount(size_t _n);
void setNetworkPreferences(p2p::NetworkPreferences const& _n) { stopNetwork(); m_netPrefs = _n; startNetwork(); }
/// Start the network subsystem.
void startNetwork() { setIdealPeerCount(5); }
void startNetwork();
/// Stop the network subsystem.
void stopNetwork() { setIdealPeerCount(0); }
void stopNetwork();
private:
/// Do some work on the network.
void workNet();
std::string m_clientVersion; ///< Our end-application client's name/version.
std::unique_ptr<eth::Client> m_ethereum; ///< Main interface for Ethereum ("eth") protocol.
@ -123,6 +122,7 @@ private:
std::unique_ptr<std::thread> m_work; ///< The network thread.
mutable boost::shared_mutex x_work; ///< Lock for the network existance.
std::atomic<WorkState> m_workState;
p2p::NetworkPreferences m_netPrefs;
};

2
test/peer.cpp

@ -46,7 +46,7 @@ int peerTest(int argc, char** argv)
remoteHost = argv[i];
}
Host ph("Test", listenPort);
Host ph("Test", NetworkPreferences(listenPort));
if (!remoteHost.empty())
ph.connect(remoteHost, remotePort);

Loading…
Cancel
Save