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
const unsigned eth::c_protocolVersion = 28;
const unsigned eth::c_protocolVersion = 29;
const unsigned eth::c_databaseVersion = 1;
static const vector<pair<u256, string>> g_units =

2
libethential/Common.cpp

@ -27,6 +27,6 @@ using 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;
}
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)
{
vector<bytes> blocks;
@ -320,20 +330,18 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
m_lastBlockHash = newHash;
}
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:";
for (auto r: ret)
clog(BlockChainNote) << r.abridged();
clog(BlockChainNote) << " Imported and best" << td << ". Has" << (details(bi.parentHash).children.size() - 1) << "siblings. Route:" << toString(ret);
}
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;
}
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)
{
return h256s();
@ -342,14 +350,14 @@ h256s BlockChain::treeRoute(h256 _from, h256 _to, h256* o_common, bool _pre, boo
h256s back;
unsigned fn = details(_from).number;
unsigned tn = details(_to).number;
cdebug << "treeRoute" << fn << "..." << tn;
// cdebug << "treeRoute" << fn << "..." << tn;
while (fn > tn)
{
if (_pre)
ret.push_back(_from);
_from = details(_from).parent;
fn--;
cdebug << "from:" << fn << _from.abridged();
// cdebug << "from:" << fn << _from.abridged();
}
while (fn < tn)
{
@ -357,7 +365,7 @@ h256s BlockChain::treeRoute(h256 _from, h256 _to, h256* o_common, bool _pre, boo
back.push_back(_to);
_to = details(_to).parent;
tn--;
cdebug << "to:" << tn << _to.abridged();
// cdebug << "to:" << tn << _to.abridged();
}
while (_from != _to)
{
@ -371,7 +379,7 @@ h256s BlockChain::treeRoute(h256 _from, h256 _to, h256* o_common, bool _pre, boo
back.push_back(_to);
fn--;
tn--;
cdebug << "from:" << fn << _from.abridged() << "; to:" << tn << _to.abridged();
// cdebug << "from:" << fn << _from.abridged() << "; to:" << tn << _to.abridged();
}
if (o_common)
*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);
h256Set ret;
if (m_blocksNeeded.size())
{
while (ret.size() < c_maxBlocksAsk && m_blocksNeeded.size())
{
ret.insert(m_blocksNeeded.back());
m_blocksOnWay.insert(m_blocksNeeded.back());
m_blocksNeeded.pop_back();
}
int s = m_blocksNeeded.size() - 1;
for (; ret.size() < c_maxBlocksAsk && s < m_blocksNeeded.size(); --s)
if (!_exclude.count(m_blocksNeeded[s]))
{
auto it = m_blocksNeeded.begin() + s;
ret.insert(*it);
m_blocksOnWay.insert(*it);
m_blocksNeeded.erase(it);
}
}
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);
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;
}
@ -574,7 +579,7 @@ void EthereumHost::noteHaveChain(std::shared_ptr<EthereumSession> const& _from)
if (_from->m_neededBlocks.empty())
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)
{
@ -596,7 +601,7 @@ void EthereumHost::noteHaveChain(std::shared_ptr<EthereumSession> const& _from)
Guard l(x_peers);
for (auto const& i: m_peers)
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.
/// Removes them from our list of needed blocks.
/// @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.
virtual bool isInitialised() const { return m_latestBlockSent; }

47
libethereum/EthereumSession.cpp

@ -56,7 +56,7 @@ EthereumSession::~EthereumSession()
catch (...){}
}
string toString(h256s const& _bs)
inline string toString(h256s const& _bs)
{
ostringstream out;
out << "[ ";
@ -75,6 +75,7 @@ void EthereumSession::giveUpOnFetch()
m_server->m_blocksNeeded.reserve(m_server->m_blocksNeeded.size() + m_askedBlocks.size());
for (auto i: m_askedBlocks)
{
m_failedBlocks.insert(i);
m_server->m_blocksOnWay.erase(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_totalDifficulty = _r[7].toInt<u256>();
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))
{
@ -120,6 +122,12 @@ bool EthereumSession::interpret(RLP const& _r)
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)
{
disconnect(IncompatibleProtocol);
@ -301,12 +309,12 @@ bool EthereumSession::interpret(RLP const& _r)
break;
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.
giveUpOnFetch();
break;
}
m_askedBlocksChanged = false;
unsigned used = 0;
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.";
ensureGettingChain();
continueGettingChain();
break;
}
case GetTransactionsPacket:
@ -355,10 +363,30 @@ bool EthereumSession::interpret(RLP const& _r)
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()
{
if (m_askedBlocks.size())
return; // Already asked & waiting for some.
continueGettingChain();
}
void EthereumSession::continueGettingChain()
{
if (!m_askedBlocks.size())
m_askedBlocks = m_server->neededBlocks();
m_askedBlocks = m_server->neededBlocks(m_failedBlocks);
if (m_askedBlocks.size())
{
@ -370,7 +398,7 @@ void EthereumSession::ensureGettingChain()
sealAndSend(s);
}
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()
@ -513,7 +541,7 @@ void EthereumSession::start()
{
RLPStream s;
prep(s);
s.appendList(9) << HelloPacket
s.appendList(10) << HelloPacket
<< (uint)EthereumHost::protocolVersion()
<< m_server->networkId()
<< m_server->m_clientVersion
@ -521,7 +549,8 @@ void EthereumSession::start()
<< m_server->m_public.port()
<< m_server->m_key.pub()
<< m_server->m_chain->details().totalDifficulty
<< m_server->m_chain->currentHash();
<< m_server->m_chain->currentHash()
<< m_server->m_chain->genesisHash();
sealAndSend(s);
ping();
getPeers();

6
libethereum/EthereumSession.h

@ -60,6 +60,10 @@ private:
/// Ensure that we are waiting for a bunch of blocks from our peer.
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();
@ -97,8 +101,10 @@ private:
h256 m_latestHash; ///< Peer's latest block's hash.
u256 m_totalDifficulty; ///< Peer's latest block's total difficulty.
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.
bool m_askedBlocksChanged = true;
std::chrono::steady_clock::time_point m_ping;
std::chrono::steady_clock::time_point m_connect;

2
libethereum/Transaction.cpp

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

Loading…
Cancel
Save