Browse Source

Version bump. New protocol. Network stuff slightly more robust.

cl-refactor
Gav Wood 11 years ago
parent
commit
0b283fac40
  1. 2
      libethcore/CommonEth.cpp
  2. 2
      libethential/Common.cpp
  3. 26
      libethereum/BlockChain.cpp
  4. 25
      libethereum/EthereumHost.cpp
  5. 2
      libethereum/EthereumHost.h
  6. 47
      libethereum/EthereumSession.cpp
  7. 6
      libethereum/EthereumSession.h
  8. 2
      libethereum/Transaction.cpp

2
libethcore/CommonEth.cpp

@ -29,7 +29,7 @@ using namespace eth;
//#define ETH_ADDRESS_DEBUG 1 //#define ETH_ADDRESS_DEBUG 1
const unsigned eth::c_protocolVersion = 28; const unsigned eth::c_protocolVersion = 29;
const unsigned eth::c_databaseVersion = 1; const unsigned eth::c_databaseVersion = 1;
static const vector<pair<u256, string>> g_units = static const vector<pair<u256, string>> g_units =

2
libethential/Common.cpp

@ -27,6 +27,6 @@ using namespace eth;
namespace eth namespace eth
{ {
char const* EthVersion = "0.6.6"; char const* EthVersion = "0.6.7";
} }

26
libethereum/BlockChain.cpp

@ -165,6 +165,16 @@ bool contains(T const& _t, V const& _v)
return false; return false;
} }
inline string toString(h256s const& _bs)
{
ostringstream out;
out << "[ ";
for (auto i: _bs)
out << i.abridged() << ", ";
out << "]";
return out.str();
}
h256s BlockChain::sync(BlockQueue& _bq, OverlayDB const& _stateDB, unsigned _max) h256s BlockChain::sync(BlockQueue& _bq, OverlayDB const& _stateDB, unsigned _max)
{ {
vector<bytes> blocks; vector<bytes> blocks;
@ -320,20 +330,18 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
m_lastBlockHash = newHash; m_lastBlockHash = newHash;
} }
m_extrasDB->Put(m_writeOptions, ldb::Slice("best"), ldb::Slice((char const*)&newHash, 32)); m_extrasDB->Put(m_writeOptions, ldb::Slice("best"), ldb::Slice((char const*)&newHash, 32));
clog(BlockChainNote) << " Imported and best. Has" << (details(bi.parentHash).children.size() - 1) << "siblings. Route:"; clog(BlockChainNote) << " Imported and best" << td << ". Has" << (details(bi.parentHash).children.size() - 1) << "siblings. Route:" << toString(ret);
for (auto r: ret)
clog(BlockChainNote) << r.abridged();
} }
else else
{ {
clog(BlockChainNote) << " Imported but not best (oTD:" << details(last).totalDifficulty << ", TD:" << td << ")"; clog(BlockChainNote) << " Imported but not best (oTD:" << details(last).totalDifficulty << " > TD:" << td << ")";
} }
return ret; return ret;
} }
h256s BlockChain::treeRoute(h256 _from, h256 _to, h256* o_common, bool _pre, bool _post) const h256s BlockChain::treeRoute(h256 _from, h256 _to, h256* o_common, bool _pre, bool _post) const
{ {
cdebug << "treeRoute" << _from.abridged() << "..." << _to.abridged(); // cdebug << "treeRoute" << _from.abridged() << "..." << _to.abridged();
if (!_from || !_to) if (!_from || !_to)
{ {
return h256s(); return h256s();
@ -342,14 +350,14 @@ h256s BlockChain::treeRoute(h256 _from, h256 _to, h256* o_common, bool _pre, boo
h256s back; h256s back;
unsigned fn = details(_from).number; unsigned fn = details(_from).number;
unsigned tn = details(_to).number; unsigned tn = details(_to).number;
cdebug << "treeRoute" << fn << "..." << tn; // cdebug << "treeRoute" << fn << "..." << tn;
while (fn > tn) while (fn > tn)
{ {
if (_pre) if (_pre)
ret.push_back(_from); ret.push_back(_from);
_from = details(_from).parent; _from = details(_from).parent;
fn--; fn--;
cdebug << "from:" << fn << _from.abridged(); // cdebug << "from:" << fn << _from.abridged();
} }
while (fn < tn) while (fn < tn)
{ {
@ -357,7 +365,7 @@ h256s BlockChain::treeRoute(h256 _from, h256 _to, h256* o_common, bool _pre, boo
back.push_back(_to); back.push_back(_to);
_to = details(_to).parent; _to = details(_to).parent;
tn--; tn--;
cdebug << "to:" << tn << _to.abridged(); // cdebug << "to:" << tn << _to.abridged();
} }
while (_from != _to) while (_from != _to)
{ {
@ -371,7 +379,7 @@ h256s BlockChain::treeRoute(h256 _from, h256 _to, h256* o_common, bool _pre, boo
back.push_back(_to); back.push_back(_to);
fn--; fn--;
tn--; tn--;
cdebug << "from:" << fn << _from.abridged() << "; to:" << tn << _to.abridged(); // cdebug << "from:" << fn << _from.abridged() << "; to:" << tn << _to.abridged();
} }
if (o_common) if (o_common)
*o_common = _from; *o_common = _from;

25
libethereum/EthereumHost.cpp

@ -367,22 +367,27 @@ void EthereumHost::connect(bi::tcp::endpoint const& _ep)
}); });
} }
h256Set EthereumHost::neededBlocks() h256Set EthereumHost::neededBlocks(h256Set const& _exclude)
{ {
Guard l(x_blocksNeeded); Guard l(x_blocksNeeded);
h256Set ret; h256Set ret;
if (m_blocksNeeded.size()) if (m_blocksNeeded.size())
{ {
while (ret.size() < c_maxBlocksAsk && m_blocksNeeded.size()) int s = m_blocksNeeded.size() - 1;
{ for (; ret.size() < c_maxBlocksAsk && s < m_blocksNeeded.size(); --s)
ret.insert(m_blocksNeeded.back()); if (!_exclude.count(m_blocksNeeded[s]))
m_blocksOnWay.insert(m_blocksNeeded.back()); {
m_blocksNeeded.pop_back(); auto it = m_blocksNeeded.begin() + s;
} ret.insert(*it);
m_blocksOnWay.insert(*it);
m_blocksNeeded.erase(it);
}
} }
else else
for (auto i = m_blocksOnWay.begin(); ret.size() < c_maxBlocksAsk && i != m_blocksOnWay.end(); ++i) for (auto i = m_blocksOnWay.begin(); ret.size() < c_maxBlocksAsk && i != m_blocksOnWay.end() && !_exclude.count(*i); ++i)
ret.insert(*i); ret.insert(*i);
clog(NetMessageSummary) << "Asking for" << ret.size() << "blocks that we don't yet have." << m_blocksNeeded.size() << "blocks still needed," << m_blocksOnWay.size() << "blocks on way.";
return ret; return ret;
} }
@ -574,7 +579,7 @@ void EthereumHost::noteHaveChain(std::shared_ptr<EthereumSession> const& _from)
if (_from->m_neededBlocks.empty()) if (_from->m_neededBlocks.empty())
return; return;
clog(NetNote) << "Hash-chain COMPLETE:" << log2((double)_from->m_totalDifficulty) << "vs" << log2((double)m_chain->details().totalDifficulty) << "," << log2((double)m_totalDifficultyOfNeeded) << ";" << _from->m_neededBlocks.size() << " blocks, ends" << _from->m_neededBlocks.back().abridged(); clog(NetNote) << "Hash-chain COMPLETE:" << _from->m_totalDifficulty << "vs" << m_chain->details().totalDifficulty << "," << m_totalDifficultyOfNeeded << ";" << _from->m_neededBlocks.size() << " blocks, ends" << _from->m_neededBlocks.back().abridged();
if ((m_totalDifficultyOfNeeded && td < m_totalDifficultyOfNeeded) || td < m_chain->details().totalDifficulty) if ((m_totalDifficultyOfNeeded && td < m_totalDifficultyOfNeeded) || td < m_chain->details().totalDifficulty)
{ {
@ -596,7 +601,7 @@ void EthereumHost::noteHaveChain(std::shared_ptr<EthereumSession> const& _from)
Guard l(x_peers); Guard l(x_peers);
for (auto const& i: m_peers) for (auto const& i: m_peers)
if (shared_ptr<EthereumSession> p = i.second.lock()) if (shared_ptr<EthereumSession> p = i.second.lock())
p->ensureGettingChain(); p->restartGettingChain();
} }
} }

2
libethereum/EthereumHost.h

@ -129,7 +129,7 @@ private:
/// Get a bunch of needed blocks. /// Get a bunch of needed blocks.
/// Removes them from our list of needed blocks. /// Removes them from our list of needed blocks.
/// @returns empty if there's no more blocks left to fetch, otherwise the blocks to fetch. /// @returns empty if there's no more blocks left to fetch, otherwise the blocks to fetch.
h256Set neededBlocks(); h256Set neededBlocks(h256Set const& _exclude);
/// Check to see if the network peer-state initialisation has happened. /// Check to see if the network peer-state initialisation has happened.
virtual bool isInitialised() const { return m_latestBlockSent; } virtual bool isInitialised() const { return m_latestBlockSent; }

47
libethereum/EthereumSession.cpp

@ -56,7 +56,7 @@ EthereumSession::~EthereumSession()
catch (...){} catch (...){}
} }
string toString(h256s const& _bs) inline string toString(h256s const& _bs)
{ {
ostringstream out; ostringstream out;
out << "[ "; out << "[ ";
@ -75,6 +75,7 @@ void EthereumSession::giveUpOnFetch()
m_server->m_blocksNeeded.reserve(m_server->m_blocksNeeded.size() + m_askedBlocks.size()); m_server->m_blocksNeeded.reserve(m_server->m_blocksNeeded.size() + m_askedBlocks.size());
for (auto i: m_askedBlocks) for (auto i: m_askedBlocks)
{ {
m_failedBlocks.insert(i);
m_server->m_blocksOnWay.erase(i); m_server->m_blocksOnWay.erase(i);
m_server->m_blocksNeeded.push_back(i); m_server->m_blocksNeeded.push_back(i);
} }
@ -109,8 +110,9 @@ bool EthereumSession::interpret(RLP const& _r)
m_id = _r[6].toHash<h512>(); m_id = _r[6].toHash<h512>();
m_totalDifficulty = _r[7].toInt<u256>(); m_totalDifficulty = _r[7].toInt<u256>();
m_latestHash = _r[8].toHash<h256>(); m_latestHash = _r[8].toHash<h256>();
auto genesisHash = _r[9].toHash<h256>();
clogS(NetMessageSummary) << "Hello: " << clientVersion << "V[" << m_protocolVersion << "/" << m_networkId << "]" << m_id.abridged() << showbase << hex << m_caps << dec << m_listenPort; clogS(NetMessageSummary) << "Hello: " << clientVersion << "V[" << m_protocolVersion << "/" << m_networkId << "/" << genesisHash.abridged() << "]" << m_id.abridged() << showbase << hex << m_caps << dec << m_listenPort;
if (m_server->havePeer(m_id)) if (m_server->havePeer(m_id))
{ {
@ -120,6 +122,12 @@ bool EthereumSession::interpret(RLP const& _r)
return false; return false;
} }
if (genesisHash != m_server->m_chain->genesisHash())
{
disconnect(WrongGenesis);
return false;
}
if (m_protocolVersion != EthereumHost::protocolVersion() || m_networkId != m_server->networkId() || !m_id) if (m_protocolVersion != EthereumHost::protocolVersion() || m_networkId != m_server->networkId() || !m_id)
{ {
disconnect(IncompatibleProtocol); disconnect(IncompatibleProtocol);
@ -301,12 +309,12 @@ bool EthereumSession::interpret(RLP const& _r)
break; break;
clogS(NetMessageSummary) << "Blocks (" << dec << (_r.itemCount() - 1) << " entries)"; clogS(NetMessageSummary) << "Blocks (" << dec << (_r.itemCount() - 1) << " entries)";
if (_r.itemCount() == 1) if (_r.itemCount() == 1 && !m_askedBlocksChanged)
{ {
// Couldn't get any from last batch - probably got to this peer's latest block - just give up. // Couldn't get any from last batch - probably got to this peer's latest block - just give up.
giveUpOnFetch(); giveUpOnFetch();
break;
} }
m_askedBlocksChanged = false;
unsigned used = 0; unsigned used = 0;
for (unsigned i = 1; i < _r.itemCount(); ++i) for (unsigned i = 1; i < _r.itemCount(); ++i)
@ -339,7 +347,7 @@ bool EthereumSession::interpret(RLP const& _r)
} }
} }
clogS(NetMessageSummary) << dec << knownParents << " known parents, " << unknownParents << "unknown, " << used << "used."; clogS(NetMessageSummary) << dec << knownParents << " known parents, " << unknownParents << "unknown, " << used << "used.";
ensureGettingChain(); continueGettingChain();
break; break;
} }
case GetTransactionsPacket: case GetTransactionsPacket:
@ -355,10 +363,30 @@ bool EthereumSession::interpret(RLP const& _r)
return true; return true;
} }
void EthereumSession::restartGettingChain()
{
if (m_askedBlocks.size())
{
m_askedBlocksChanged = true; // So that we continue even if the Ask's reply is empty.
m_askedBlocks.clear(); // So that we restart once we get the Ask's reply.
m_failedBlocks.clear();
}
else
ensureGettingChain();
}
void EthereumSession::ensureGettingChain() void EthereumSession::ensureGettingChain()
{
if (m_askedBlocks.size())
return; // Already asked & waiting for some.
continueGettingChain();
}
void EthereumSession::continueGettingChain()
{ {
if (!m_askedBlocks.size()) if (!m_askedBlocks.size())
m_askedBlocks = m_server->neededBlocks(); m_askedBlocks = m_server->neededBlocks(m_failedBlocks);
if (m_askedBlocks.size()) if (m_askedBlocks.size())
{ {
@ -370,7 +398,7 @@ void EthereumSession::ensureGettingChain()
sealAndSend(s); sealAndSend(s);
} }
else else
clogS(NetMessageSummary) << "No blocks left to get."; clogS(NetMessageSummary) << "No blocks left to get. Peer doesn't seem to have " << m_failedBlocks.size() << "of our needed blocks.";
} }
void EthereumSession::ping() void EthereumSession::ping()
@ -513,7 +541,7 @@ void EthereumSession::start()
{ {
RLPStream s; RLPStream s;
prep(s); prep(s);
s.appendList(9) << HelloPacket s.appendList(10) << HelloPacket
<< (uint)EthereumHost::protocolVersion() << (uint)EthereumHost::protocolVersion()
<< m_server->networkId() << m_server->networkId()
<< m_server->m_clientVersion << m_server->m_clientVersion
@ -521,7 +549,8 @@ void EthereumSession::start()
<< m_server->m_public.port() << m_server->m_public.port()
<< m_server->m_key.pub() << m_server->m_key.pub()
<< m_server->m_chain->details().totalDifficulty << m_server->m_chain->details().totalDifficulty
<< m_server->m_chain->currentHash(); << m_server->m_chain->currentHash()
<< m_server->m_chain->genesisHash();
sealAndSend(s); sealAndSend(s);
ping(); ping();
getPeers(); getPeers();

6
libethereum/EthereumSession.h

@ -60,6 +60,10 @@ private:
/// Ensure that we are waiting for a bunch of blocks from our peer. /// Ensure that we are waiting for a bunch of blocks from our peer.
void ensureGettingChain(); void ensureGettingChain();
/// Ensure that we are waiting for a bunch of blocks from our peer.
void continueGettingChain();
/// Now getting a different chain so we need to make sure we restart.
void restartGettingChain();
void giveUpOnFetch(); void giveUpOnFetch();
@ -97,8 +101,10 @@ private:
h256 m_latestHash; ///< Peer's latest block's hash. h256 m_latestHash; ///< Peer's latest block's hash.
u256 m_totalDifficulty; ///< Peer's latest block's total difficulty. u256 m_totalDifficulty; ///< Peer's latest block's total difficulty.
h256s m_neededBlocks; ///< The blocks that we should download from this peer. h256s m_neededBlocks; ///< The blocks that we should download from this peer.
h256Set m_failedBlocks; ///< Blocks that the peer doesn't seem to have.
h256Set m_askedBlocks; ///< The blocks for which we sent the last GetBlocks for but haven't received a corresponding Blocks. h256Set m_askedBlocks; ///< The blocks for which we sent the last GetBlocks for but haven't received a corresponding Blocks.
bool m_askedBlocksChanged = true;
std::chrono::steady_clock::time_point m_ping; std::chrono::steady_clock::time_point m_ping;
std::chrono::steady_clock::time_point m_connect; std::chrono::steady_clock::time_point m_connect;

2
libethereum/Transaction.cpp

@ -27,7 +27,7 @@
using namespace std; using namespace std;
using namespace eth; using namespace eth;
#define ETH_ADDRESS_DEBUG 1 #define ETH_ADDRESS_DEBUG 0
Transaction::Transaction(bytesConstRef _rlpData, bool _checkSender) Transaction::Transaction(bytesConstRef _rlpData, bool _checkSender)
{ {

Loading…
Cancel
Save