Browse Source

Respect and handle capabilities.

- Peer-servers should never kick eachother off.
cl-refactor
Gav Wood 11 years ago
parent
commit
3d5e8cdc59
  1. 7
      TODO
  2. 6
      alephzero/MainWin.cpp
  3. 2
      alephzero/alephzero.pro
  4. 2
      libethereum/Common.cpp
  5. 95
      libethereum/PeerNetwork.cpp
  6. 3
      libethereum/PeerNetwork.h

7
TODO

@ -28,17 +28,12 @@ General:
FOR ALPHA:
Network:
* Manage GetBlocks properly; should work for when > 256 blocks away.
* NotInChain will be very bad for new peers - it'll run through until the genesis.
* Respect and handle capabilities.
* Use GetTransactions on connect & respect it. DONE
* UPnP is needed.
UI:
* State panel shouldn't show pending (i.e. post-mined) transactions.
PoW:
* Minute mine times. DONE (ish)
### ERIC

6
alephzero/MainWin.cpp

@ -22,7 +22,9 @@ Main::Main(QWidget *parent) :
connect(m_refresh, SIGNAL(timeout()), SLOT(refresh()));
m_refresh->start(1000);
#if NDEBUG
#if ETH_DEBUG
m_servers.append("192.168.0.10:30301");
#else
connect(&m_webCtrl, &QNetworkAccessManager::finished, [&](QNetworkReply* _r)
{
m_servers = QString::fromUtf8(_r->readAll()).split("\n", QString::SkipEmptyParts);
@ -31,8 +33,6 @@ Main::Main(QWidget *parent) :
r.setHeader(QNetworkRequest::UserAgentHeader, "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1712.0 Safari/537.36");
m_webCtrl.get(r);
srand(time(0));
#else
m_servers.append("192.168.0.10:30301");
#endif
}

2
alephzero/alephzero.pro

@ -10,6 +10,8 @@ QT += core gui widgets network
TARGET = alephzero
TEMPLATE = app
CONFIG(debug, debug|release): DEFINES += ETH_DEBUG
QMAKE_CXXFLAGS += -std=c++11
QMAKE_LIBDIR += ../../cpp-ethereum-build/libethereum ../../secp256k1 ../../cryptopp562
LIBS += -Wl,-rpath,../../cpp-ethereum-build/libethereum -Wl,-rpath,../../secp256k1 -Wl,-rpath,../../cryptopp562 -lethereum -lsecp256k1 -lleveldb -lcryptopp -lgmp -lboost_filesystem -lboost_system

2
libethereum/Common.cpp

@ -39,7 +39,7 @@ using namespace eth;
#if NDEBUG
u256 const eth::c_genesisDifficulty = (u256)1 << 32;
#else
u256 const eth::c_genesisDifficulty = (u256)1 << 28; // should be << 32
u256 const eth::c_genesisDifficulty = (u256)1 << 32; // should be << 32
#endif
std::string eth::escaped(std::string const& _s, bool _all)

95
libethereum/PeerNetwork.cpp

@ -76,7 +76,9 @@ bool PeerSession::interpret(RLP const& _r)
if (m_server->m_verbosity >= 2)
cout << std::setw(2) << m_socket.native_handle() << " | Hello: " << clientVersion << endl;
m_listenPort = _r.itemCount() > 4 ? _r[4].toInt<short>() : -1;
m_caps = _r.itemCount() > 4 ? _r[4].toInt<uint>() : 0x07;
m_listenPort = _r.itemCount() > 5 ? _r[5].toInt<short>() : -1;
if (m_protocolVersion != 0 || m_networkId != m_reqNetworkId)
{
disconnect();
@ -448,7 +450,7 @@ void PeerSession::start()
{
RLPStream s;
prep(s);
s.appendList(5) << (uint)Hello << (uint)0 << (uint)0 << m_server->m_clientVersion << m_server->m_acceptor.local_endpoint().port();
s.appendList(5) << (uint)Hello << (uint)0 << (uint)0 << m_server->m_clientVersion << (m_server->m_mode == NodeMode::Full ? 0x07 : m_server->m_mode == NodeMode::PeerServer ? 0x01 : 0) << m_server->m_acceptor.local_endpoint().port();
sealAndSend(s);
ping();
@ -800,58 +802,63 @@ bool PeerServer::process(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o)
break;
}
}
// Connect to additional peers
if (fullProcess)
{
while (m_peers.size() < m_idealPeerCount)
{
if (m_incomingPeers.empty())
{
if (chrono::steady_clock::now() > m_lastPeersRequest + chrono::seconds(10))
{
RLPStream s;
bytes b;
(PeerSession::prep(s).appendList(1) << GetPeers).swapOut(b);
seal(b);
for (auto const& i: m_peers)
if (auto p = i.lock())
p->send(&b);
m_lastPeersRequest = chrono::steady_clock::now();
}
if (!m_accepting)
ensureAccepting();
break;
}
connect(m_incomingPeers.back());
m_incomingPeers.pop_back();
}
}
}
// platform for consensus of social contract.
// restricts your freedom but does so fairly. and that's the value proposition.
// guarantees that everyone else respect the rules of the system. (i.e. obeys laws).
// Connect to additional peers
if (fullProcess)
{
while (m_peers.size() < m_idealPeerCount)
{
if (m_incomingPeers.empty())
// We'll keep at most twice as many as is ideal, halfing what counts as "too young to kill" until we get there.
for (uint old = 15000; m_peers.size() > m_idealPeerCount * 2 && old > 100; old /= 2)
while (m_peers.size() > m_idealPeerCount)
{
if (chrono::steady_clock::now() > m_lastPeersRequest + chrono::seconds(10))
{
RLPStream s;
bytes b;
(PeerSession::prep(s).appendList(1) << GetPeers).swapOut(b);
seal(b);
for (auto const& i: m_peers)
if (auto p = i.lock())
p->send(&b);
m_lastPeersRequest = chrono::steady_clock::now();
}
if (!m_accepting)
ensureAccepting();
break;
// look for worst peer to kick off
// first work out how many are old enough to kick off.
shared_ptr<PeerSession> worst;
unsigned agedPeers = 0;
for (auto i: m_peers)
if (auto p = i.lock())
if ((m_mode != NodeMode::PeerServer || p->m_caps != 0x01) && chrono::steady_clock::now() > p->m_connect + chrono::milliseconds(old)) // don't throw off new peers; peer-servers should never kick off other peer-servers.
{
++agedPeers;
if ((!worst || p->m_rating < worst->m_rating || (p->m_rating == worst->m_rating && p->m_connect > worst->m_connect))) // kill older ones
worst = p;
}
if (!worst || agedPeers <= m_idealPeerCount)
break;
worst->disconnect();
}
connect(m_incomingPeers.back());
m_incomingPeers.pop_back();
}
while (m_peers.size() > m_idealPeerCount)
{
// look for worst peer to kick off
// first work out how many are old enough to kick off.
shared_ptr<PeerSession> worst;
unsigned agedPeers = 0;
for (auto i: m_peers)
if (auto p = i.lock())
if (chrono::steady_clock::now() > p->m_connect + chrono::seconds(10))
{
++agedPeers;
if ((!worst || p->m_rating < worst->m_rating || (p->m_rating == worst->m_rating && p->m_connect > worst->m_connect))) // keep younger ones.
worst = p;
}
if (!worst || agedPeers <= m_idealPeerCount)
break;
worst->dropped(); // should really disconnect, but that's no good.
}
}
return ret;

3
libethereum/PeerNetwork.h

@ -75,7 +75,7 @@ public:
void ping();
bi::tcp::endpoint endpoint() const;
bi::tcp::endpoint endpoint() const; ///< for other peers to connect to.
private:
void dropped();
@ -98,6 +98,7 @@ private:
uint m_networkId;
uint m_reqNetworkId;
short m_listenPort; ///< Port that the remote client is listening on for connections. Useful for giving to peers.
uint m_caps;
std::chrono::steady_clock::time_point m_ping;
std::chrono::steady_clock::time_point m_connect;

Loading…
Cancel
Save