Browse Source

Manage GetBlocks properly; should work for when > 256 blocks away.

Use GetTransactions on connect & respect it. DONE
cl-refactor
Gav Wood 11 years ago
parent
commit
0fc422a160
  1. 8
      TODO
  2. 4
      alephzero/MainWin.cpp
  3. 2
      eth/main.cpp
  4. 4
      libethereum/BlockChain.cpp
  5. 4
      libethereum/BlockInfo.cpp
  6. 2
      libethereum/Common.cpp
  7. 3
      libethereum/Common.h
  8. 17
      libethereum/Dagger.cpp
  9. 4
      libethereum/MemTrie.cpp
  10. 257
      libethereum/PeerNetwork.cpp
  11. 8
      libethereum/PeerNetwork.h
  12. 2
      libethereum/RLP.cpp
  13. 2
      libethereum/TrieCommon.h
  14. 6
      libethereum/TrieHash.cpp
  15. 6
      test/crypto.cpp

8
TODO

@ -18,6 +18,10 @@ Network:
CLI client CLI client
- Implement CLI option "--help". - Implement CLI option "--help".
General:
- Better logging.
- Colours.
- Time/thread/channel stamp.
### GAV ### GAV
@ -25,9 +29,9 @@ FOR ALPHA:
Network: Network:
* Manage GetBlocks properly; should work for when > 256 blocks away. * Manage GetBlocks properly; should work for when > 256 blocks away.
- configurable (lower) mine times, configurable (reduced) max blocks to be sent then check. * NotInChain will be very bad for new peers - it'll run through until the genesis.
* Respect and handle capabilities. * Respect and handle capabilities.
* Use GetTransactions on connect & respect it. * Use GetTransactions on connect & respect it. DONE
UI: UI:
* State panel shouldn't show pending (i.e. post-mined) transactions. * State panel shouldn't show pending (i.e. post-mined) transactions.

4
alephzero/MainWin.cpp

@ -22,6 +22,7 @@ Main::Main(QWidget *parent) :
connect(m_refresh, SIGNAL(timeout()), SLOT(refresh())); connect(m_refresh, SIGNAL(timeout()), SLOT(refresh()));
m_refresh->start(1000); m_refresh->start(1000);
#if NDEBUG
connect(&m_webCtrl, &QNetworkAccessManager::finished, [&](QNetworkReply* _r) connect(&m_webCtrl, &QNetworkAccessManager::finished, [&](QNetworkReply* _r)
{ {
m_servers = QString::fromUtf8(_r->readAll()).split("\n", QString::SkipEmptyParts); m_servers = QString::fromUtf8(_r->readAll()).split("\n", QString::SkipEmptyParts);
@ -30,6 +31,9 @@ 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"); 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); m_webCtrl.get(r);
srand(time(0)); srand(time(0));
#else
m_servers.append("192.168.0.10:30301");
#endif
} }
Main::~Main() Main::~Main()

2
eth/main.cpp

@ -189,7 +189,7 @@ int main(int argc, char** argv)
eth::uint n = c.blockChain().details().number; eth::uint n = c.blockChain().details().number;
while (true) while (true)
{ {
if (c.blockChain().details().number - n > mining) if (c.blockChain().details().number - n >= mining)
c.stopMining(); c.stopMining();
else else
c.startMining(); c.startMining();

4
libethereum/BlockChain.cpp

@ -85,7 +85,7 @@ BlockChain::BlockChain(std::string _path, bool _killExisting)
if (!details(m_genesisHash)) if (!details(m_genesisHash))
{ {
// Insert details of genesis block. // Insert details of genesis block.
m_details[m_genesisHash] = BlockDetails(0, (u256)1 << 32, h256(), {}); m_details[m_genesisHash] = BlockDetails(0, c_genesisDifficulty, h256(), {});
auto r = m_details[m_genesisHash].rlp(); auto r = m_details[m_genesisHash].rlp();
m_detailsDB->Put(m_writeOptions, ldb::Slice((char const*)&m_genesisHash, 32), (ldb::Slice)eth::ref(r)); m_detailsDB->Put(m_writeOptions, ldb::Slice((char const*)&m_genesisHash, 32), (ldb::Slice)eth::ref(r));
} }
@ -96,6 +96,8 @@ BlockChain::BlockChain(std::string _path, bool _killExisting)
std::string l; std::string l;
m_detailsDB->Get(m_readOptions, ldb::Slice("best"), &l); m_detailsDB->Get(m_readOptions, ldb::Slice("best"), &l);
m_lastBlockHash = l.empty() ? m_genesisHash : *(h256*)l.data(); m_lastBlockHash = l.empty() ? m_genesisHash : *(h256*)l.data();
cout << "Opened blockchain db. Latest: " << m_lastBlockHash << endl;
} }
BlockChain::~BlockChain() BlockChain::~BlockChain()

4
libethereum/BlockInfo.cpp

@ -42,7 +42,7 @@ bytes BlockInfo::createGenesisBlock()
{ {
RLPStream block(3); RLPStream block(3);
auto sha3EmptyList = sha3(RLPEmptyList); auto sha3EmptyList = sha3(RLPEmptyList);
block.appendList(9) << h256() << sha3EmptyList << h160() << sha3(RLPNull) << sha3EmptyList << ((uint)1 << 32) << (uint)0 << string() << (uint)0; block.appendList(9) << h256() << sha3EmptyList << h160() << sha3(RLPNull) << sha3EmptyList << c_genesisDifficulty << (uint)0 << string() << (uint)0;
block.appendRaw(RLPEmptyList); block.appendRaw(RLPEmptyList);
block.appendRaw(RLPEmptyList); block.appendRaw(RLPEmptyList);
return block.out(); return block.out();
@ -109,7 +109,7 @@ void BlockInfo::verifyInternals(bytesConstRef _block) const
u256 BlockInfo::calculateDifficulty(BlockInfo const& _parent) const u256 BlockInfo::calculateDifficulty(BlockInfo const& _parent) const
{ {
if (!parentHash) if (!parentHash)
return (u256)1 << 32; return c_genesisDifficulty;
else else
return timestamp >= _parent.timestamp + 42 ? _parent.difficulty - (_parent.difficulty >> 10) : (_parent.difficulty + (_parent.difficulty >> 10)); return timestamp >= _parent.timestamp + 42 ? _parent.difficulty - (_parent.difficulty >> 10) : (_parent.difficulty + (_parent.difficulty >> 10));
} }

2
libethereum/Common.cpp

@ -36,6 +36,8 @@
using namespace std; using namespace std;
using namespace eth; using namespace eth;
u256 const eth::c_genesisDifficulty = (u256)1 << 20;
std::string eth::escaped(std::string const& _s, bool _all) std::string eth::escaped(std::string const& _s, bool _all)
{ {
std::string ret; std::string ret;

3
libethereum/Common.h

@ -61,6 +61,8 @@ using u160s = std::vector<u160>;
using u256Set = std::set<u256>; using u256Set = std::set<u256>;
using u160Set = std::set<u160>; using u160Set = std::set<u160>;
extern const u256 c_genesisDifficulty;
template <class T, class Out> inline void toBigEndian(T _val, Out& o_out); template <class T, class Out> inline void toBigEndian(T _val, Out& o_out);
template <class T, class In> inline T fromBigEndian(In const& _bytes); template <class T, class In> inline T fromBigEndian(In const& _bytes);
@ -113,6 +115,7 @@ inline std::ostream& operator<<(std::ostream& _out, FixedHash<N> const& _h)
_out << std::noshowbase << std::hex << std::setfill('0'); _out << std::noshowbase << std::hex << std::setfill('0');
for (unsigned i = 0; i < N; ++i) for (unsigned i = 0; i < N; ++i)
_out << std::setw(2) << (int)_h[i]; _out << std::setw(2) << (int)_h[i];
_out << std::dec;
return _out; return _out;
} }

17
libethereum/Dagger.cpp

@ -28,20 +28,27 @@ MineInfo Dagger::mine(u256& o_solution, h256 const& _root, u256 const& _difficul
static std::mt19937_64 s_eng((time(0))); static std::mt19937_64 s_eng((time(0)));
o_solution = std::uniform_int_distribution<uint>(0, ~(uint)0)(s_eng); o_solution = std::uniform_int_distribution<uint>(0, ~(uint)0)(s_eng);
u256 d = (u256)(((bigint)1 << 256) / _difficulty); bigint d = (bigint(1) << 256) / _difficulty;
ret.requirement = toLog2(d); ret.requirement = toLog2((u256)d);
// 2^ 0 32 64 128 256 // 2^ 0 32 64 128 256
// [--------*-------------------------] // [--------*-------------------------]
// //
// evaluate until we run out of time // evaluate until we run out of time
for (auto startTime = steady_clock::now(); (steady_clock::now() - startTime) < milliseconds(_msTimeout) && _continue && !ret.completed; o_solution += 1) for (auto startTime = steady_clock::now(); (steady_clock::now() - startTime) < milliseconds(_msTimeout) && _continue; o_solution += 1)
{ {
auto e = (u256)eval(_root, o_solution); auto e = (bigint)(u256)eval(_root, o_solution);
ret.best = max(ret.best, toLog2(e)); ret.best = max(ret.best, toLog2((u256)e));
if (e <= d) if (e <= d)
{
ret.completed = true; ret.completed = true;
break;
}
} }
if (ret.completed)
assert(verify(_root, o_solution, _difficulty));
return ret; return ret;
} }

4
libethereum/MemTrie.cpp

@ -48,7 +48,7 @@ public:
void putRLP(RLPStream& _parentStream) const; void putRLP(RLPStream& _parentStream) const;
#if ENABLE_DEBUG_PRINT #if ENABLE_DEBUG_PRINT
void debugPrint(std::string const& _indent = "") const { std::cerr << std::hex << hash256() << ":" << std::endl; debugPrintBody(_indent); } void debugPrint(std::string const& _indent = "") const { std::cerr << std::hex << hash256() << ":" << std::dec << std::endl; debugPrintBody(_indent); }
#endif #endif
/// 256-bit hash of the node - this is a SHA-3/256 hash of the RLP of the node. /// 256-bit hash of the node - this is a SHA-3/256 hash of the RLP of the node.
@ -115,7 +115,7 @@ public:
for (auto i = 0; i < 16; ++i) for (auto i = 0; i < 16; ++i)
if (m_nodes[i]) if (m_nodes[i])
{ {
std::cerr << _indent << std::hex << i << ": "; std::cerr << _indent << std::hex << i << ": " << std::dec;
m_nodes[i]->debugPrint(_indent + " "); m_nodes[i]->debugPrint(_indent + " ");
} }
} }

257
libethereum/PeerNetwork.cpp

@ -25,11 +25,16 @@
#include <chrono> #include <chrono>
#include "Common.h" #include "Common.h"
#include "BlockChain.h" #include "BlockChain.h"
#include "BlockInfo.h"
#include "TransactionQueue.h" #include "TransactionQueue.h"
#include "PeerNetwork.h" #include "PeerNetwork.h"
using namespace std; using namespace std;
using namespace eth; using namespace eth;
static const eth::uint c_maxHashes = 4; ///< Maximum number of hashes GetChain will ever send.
static const eth::uint c_maxBlocks = 4; ///< Maximum number of blocks Blocks will ever send.
static const eth::uint c_maxBlocksAsk = 256; ///< Maximum number of blocks we ask to receive in Blocks (when using GetChain).
PeerSession::PeerSession(PeerServer* _s, bi::tcp::socket _socket, uint _rNId): PeerSession::PeerSession(PeerServer* _s, bi::tcp::socket _socket, uint _rNId):
m_server(_s), m_server(_s),
m_socket(std::move(_socket)), m_socket(std::move(_socket)),
@ -47,14 +52,19 @@ PeerSession::~PeerSession()
bi::tcp::endpoint PeerSession::endpoint() const bi::tcp::endpoint PeerSession::endpoint() const
{ {
return bi::tcp::endpoint(m_socket.remote_endpoint().address(), m_listenPort); if (m_socket.is_open())
try {
return bi::tcp::endpoint(m_socket.remote_endpoint().address(), m_listenPort);
} catch (...){}
return bi::tcp::endpoint();
} }
// TODO: BUG! 256 -> work out why things start to break with big packet sizes -> g.t. ~370 blocks. // TODO: BUG! 256 -> work out why things start to break with big packet sizes -> g.t. ~370 blocks.
bool PeerSession::interpret(RLP const& _r) bool PeerSession::interpret(RLP const& _r)
{ {
if (m_server->m_verbosity >= 4) if (m_server->m_verbosity >= 8)
cout << ">>> " << _r << endl; cout << ">>> " << _r << endl;
switch (_r[0].toInt<unsigned>()) switch (_r[0].toInt<unsigned>())
{ {
@ -82,14 +92,18 @@ bool PeerSession::interpret(RLP const& _r)
// Grab their block chain off them. // Grab their block chain off them.
{ {
unsigned count = std::min<unsigned>(256, m_server->m_chain->details(m_server->m_latestBlockSent).number); unsigned count = std::min<unsigned>(c_maxHashes, m_server->m_chain->details(m_server->m_latestBlockSent).number + 1);
RLPStream s; RLPStream s;
prep(s).appendList(2 + count); prep(s).appendList(2 + count);
s << (uint)GetChain; s << (uint)GetChain;
auto h = m_server->m_chain->details(m_server->m_latestBlockSent).parent; auto h = m_server->m_latestBlockSent;
for (unsigned i = 0; i < count; ++i, h = m_server->m_chain->details(h).parent) for (unsigned i = 0; i < count; ++i, h = m_server->m_chain->details(h).parent)
s << h; s << h;
s << 256; s << c_maxBlocksAsk;
sealAndSend(s);
s.clear();
prep(s).appendList(1);
s << GetTransactions;
sealAndSend(s); sealAndSend(s);
} }
break; break;
@ -150,6 +164,9 @@ bool PeerSession::interpret(RLP const& _r)
if (shared_ptr<PeerSession> p = i.lock()) if (shared_ptr<PeerSession> p = i.lock())
if (p->m_socket.is_open() && p->endpoint() == ep) if (p->m_socket.is_open() && p->endpoint() == ep)
goto CONTINUE; goto CONTINUE;
for (auto i: m_server->m_incomingPeers)
if (i == ep)
goto CONTINUE;
m_server->m_incomingPeers.push_back(ep); m_server->m_incomingPeers.push_back(ep);
if (m_server->m_verbosity >= 3) if (m_server->m_verbosity >= 3)
cout << "New peer: " << ep << endl; cout << "New peer: " << ep << endl;
@ -179,13 +196,23 @@ bool PeerSession::interpret(RLP const& _r)
m_server->m_incomingBlocks.push_back(_r[i].data().toBytes()); m_server->m_incomingBlocks.push_back(_r[i].data().toBytes());
m_knownBlocks.insert(sha3(_r[i].data())); m_knownBlocks.insert(sha3(_r[i].data()));
} }
if (_r[1].itemCount()) // we received some - check if there's any more if (m_server->m_verbosity >= 3)
for (unsigned i = 1; i < _r.itemCount(); ++i)
{
auto h = sha3(_r[i].data());
BlockInfo bi(_r[i].data());
if (!m_server->m_chain->details(bi.parentHash) && !m_knownBlocks.count(bi.parentHash))
cerr << "*** Unknown parent " << bi.parentHash << " of block " << h << endl;
else
cerr << "--- Known parent " << bi.parentHash << " of block " << h << endl;
}
if (_r.itemCount() > 1) // we received some - check if there's any more
{ {
RLPStream s; RLPStream s;
prep(s).appendList(3); prep(s).appendList(3);
s << (uint)GetChain; s << (uint)GetChain;
s << sha3(_r[1][0].data()); s << sha3(_r[1].data());
s << 256; s << c_maxBlocksAsk;
sealAndSend(s); sealAndSend(s);
} }
break; break;
@ -199,10 +226,12 @@ bool PeerSession::interpret(RLP const& _r)
parents.reserve(_r.itemCount() - 2); parents.reserve(_r.itemCount() - 2);
for (unsigned i = 1; i < _r.itemCount() - 1; ++i) for (unsigned i = 1; i < _r.itemCount() - 1; ++i)
parents.push_back(_r[i].toHash<h256>()); parents.push_back(_r[i].toHash<h256>());
if (m_server->m_verbosity >= 2)
cout << std::setw(2) << m_socket.native_handle() << " | GetChain (" << (_r.itemCount() - 2) << " hashes, " << (_r[_r.itemCount() - 1].toInt<bigint>()) << ")" << endl;
if (_r.itemCount() == 2) if (_r.itemCount() == 2)
break; break;
// return 2048 block max. // return 2048 block max.
uint baseCount = (uint)min<bigint>(_r[_r.itemCount() - 1].toInt<bigint>(), 256); uint baseCount = (uint)min<bigint>(_r[_r.itemCount() - 1].toInt<bigint>(), c_maxBlocks);
if (m_server->m_verbosity >= 2) if (m_server->m_verbosity >= 2)
cout << std::setw(2) << m_socket.native_handle() << " | GetChain (" << baseCount << " max, from " << parents.front() << " to " << parents.back() << ")" << endl; cout << std::setw(2) << m_socket.native_handle() << " | GetChain (" << baseCount << " max, from " << parents.front() << " to " << parents.back() << ")" << endl;
for (auto parent: parents) for (auto parent: parents)
@ -218,31 +247,32 @@ bool PeerSession::interpret(RLP const& _r)
latestNumber = m_server->m_chain->details(latest).number; latestNumber = m_server->m_chain->details(latest).number;
parentNumber = m_server->m_chain->details(parent).number; parentNumber = m_server->m_chain->details(parent).number;
uint count = min<uint>(latestNumber - parentNumber, baseCount); uint count = min<uint>(latestNumber - parentNumber, baseCount);
// cout << "Requires " << dec << (latestNumber - parentNumber) << " blocks from " << latestNumber << " to " << parentNumber << endl; if (m_server->m_verbosity >= 6)
// cout << latest << " - " << parent << endl; cout << "Requires " << dec << (latestNumber - parentNumber) << " blocks from " << latestNumber << " to " << parentNumber << endl
<< latest << " - " << parent << endl;
prep(s); prep(s);
s.appendList(1 + count) << (uint)Blocks; s.appendList(1 + count) << (uint)Blocks;
uint endNumber = m_server->m_chain->details(parent).number; uint endNumber = m_server->m_chain->details(parent).number;
uint startNumber = endNumber + count; uint startNumber = endNumber + count;
// cout << "Sending " << dec << count << " blocks from " << startNumber << " to " << endNumber << endl; if (m_server->m_verbosity >= 6)
cout << "Sending " << dec << count << " blocks from " << startNumber << " to " << endNumber << endl;
uint n = latestNumber; uint n = latestNumber;
for (; n > startNumber; n--, h = m_server->m_chain->details(h).parent) {} for (; n > startNumber; n--, h = m_server->m_chain->details(h).parent) {}
for (uint i = 0; h != parent && n > endNumber && i < count; ++i, --n, h = m_server->m_chain->details(h).parent) for (uint i = 0; h != parent && n > endNumber && i < count; ++i, --n, h = m_server->m_chain->details(h).parent)
{ {
// cout << " " << dec << i << " " << h << endl; if (m_server->m_verbosity >= 6)
cout << " " << dec << i << " " << h << endl;
s.appendRaw(m_server->m_chain->block(h)); s.appendRaw(m_server->m_chain->block(h));
} }
// cout << "Parent: " << h << endl; if (m_server->m_verbosity >= 6)
cout << "Parent: " << h << endl;
} }
else if (parent != parents.back()) else if (parent != parents.back())
continue; continue;
if (h == parent) if (h != parent)
{
}
else
{ {
// not in the blockchain; // not in the blockchain;
if (parent == parents.back()) if (parent == parents.back())
@ -272,19 +302,31 @@ bool PeerSession::interpret(RLP const& _r)
h256 noGood = _r[1].toHash<h256>(); h256 noGood = _r[1].toHash<h256>();
if (m_server->m_verbosity >= 2) if (m_server->m_verbosity >= 2)
cout << std::setw(2) << m_socket.native_handle() << " | NotInChain (" << noGood << ")" << endl; cout << std::setw(2) << m_socket.native_handle() << " | NotInChain (" << noGood << ")" << endl;
if (noGood != m_server->m_chain->genesisHash()) if (noGood == m_server->m_chain->genesisHash())
{ {
unsigned count = std::min<unsigned>(256, m_server->m_chain->details(noGood).number); if (m_server->m_verbosity)
cout << std::setw(2) << m_socket.native_handle() << " | Discordance over genesis block! Disconnect." << endl;
disconnect();
}
else
{
unsigned count = std::min<unsigned>(c_maxHashes, m_server->m_chain->details(noGood).number);
RLPStream s; RLPStream s;
prep(s).appendList(2 + count); prep(s).appendList(2 + count);
s << (uint)GetChain; s << (uint)GetChain;
auto h = m_server->m_chain->details(noGood).parent; auto h = m_server->m_chain->details(noGood).parent;
for (unsigned i = 0; i < count; ++i, h = m_server->m_chain->details(h).parent) for (unsigned i = 0; i < count; ++i, h = m_server->m_chain->details(h).parent)
s << h; s << h;
s << 256; s << c_maxBlocksAsk;
sealAndSend(s); sealAndSend(s);
} }
// else our peer obviously knows nothing if they're unable to give the descendents of the genesis! break;
}
case GetTransactions:
{
if (m_server->m_mode == NodeMode::PeerServer)
break;
m_requireTransactions = true;
break; break;
} }
default: default:
@ -307,7 +349,7 @@ RLPStream& PeerSession::prep(RLPStream& _s)
void PeerServer::seal(bytes& _b) void PeerServer::seal(bytes& _b)
{ {
if (m_verbosity >= 5) if (m_verbosity >= 9)
cout << "<<< " << RLP(bytesConstRef(&_b).cropped(8)) << endl; cout << "<<< " << RLP(bytesConstRef(&_b).cropped(8)) << endl;
_b[0] = 0x22; _b[0] = 0x22;
_b[1] = 0x40; _b[1] = 0x40;
@ -361,7 +403,9 @@ void PeerSession::dropped()
if (m_server->m_verbosity >= 1) if (m_server->m_verbosity >= 1)
{ {
if (m_socket.is_open()) if (m_socket.is_open())
cout << "Closing " << m_socket.remote_endpoint() << endl; try {
cout << "Closing " << m_socket.remote_endpoint() << endl;
}catch (...){}
} }
m_socket.close(); m_socket.close();
for (auto i = m_server->m_peers.begin(); i != m_server->m_peers.end(); ++i) for (auto i = m_server->m_peers.begin(); i != m_server->m_peers.end(); ++i)
@ -389,7 +433,9 @@ void PeerSession::disconnect()
if (m_server->m_verbosity >= 1) if (m_server->m_verbosity >= 1)
{ {
if (m_socket.is_open()) if (m_socket.is_open())
cout << "Closing " << m_socket.remote_endpoint() << endl; try {
cout << "Closing " << m_socket.remote_endpoint() << endl;
} catch (...){}
else else
cout << "Remote closed on" << m_socket.native_handle() << endl; cout << "Remote closed on" << m_socket.native_handle() << endl;
} }
@ -428,7 +474,7 @@ void PeerSession::doRead()
if (m_incoming[0] != 0x22 || m_incoming[1] != 0x40 || m_incoming[2] != 0x08 || m_incoming[3] != 0x91) if (m_incoming[0] != 0x22 || m_incoming[1] != 0x40 || m_incoming[2] != 0x08 || m_incoming[3] != 0x91)
{ {
if (m_server->m_verbosity) if (m_server->m_verbosity)
cerr << std::setw(2) << m_socket.native_handle() << " | Out of alignment. Skipping: " << hex << showbase << (int)m_incoming[0] << endl; cerr << std::setw(2) << m_socket.native_handle() << " | Out of alignment. Skipping: " << hex << showbase << (int)m_incoming[0] << dec << endl;
memmove(m_incoming.data(), m_incoming.data() + 1, m_incoming.size() - 1); memmove(m_incoming.data(), m_incoming.data() + 1, m_incoming.size() - 1);
m_incoming.resize(m_incoming.size() - 1); m_incoming.resize(m_incoming.size() - 1);
} }
@ -471,6 +517,8 @@ PeerServer::PeerServer(std::string const& _clientVersion, BlockChain const& _ch,
{ {
populateAddresses(); populateAddresses();
ensureAccepting(); ensureAccepting();
if (m_verbosity)
cout << "Genesis: " << m_chain->genesisHash() << endl;
} }
PeerServer::PeerServer(std::string const& _clientVersion, uint _networkId): PeerServer::PeerServer(std::string const& _clientVersion, uint _networkId):
@ -481,6 +529,8 @@ PeerServer::PeerServer(std::string const& _clientVersion, uint _networkId):
{ {
// populate addresses. // populate addresses.
populateAddresses(); populateAddresses();
if (m_verbosity)
cout << "Genesis: " << m_chain->genesisHash() << endl;
} }
PeerServer::~PeerServer() PeerServer::~PeerServer()
@ -544,7 +594,9 @@ void PeerServer::ensureAccepting()
try try
{ {
if (m_verbosity >= 1) if (m_verbosity >= 1)
cout << "Accepted connection from " << m_socket.remote_endpoint() << std::endl; try {
cout << "Accepted connection from " << m_socket.remote_endpoint() << std::endl;
} catch (...){}
auto p = std::make_shared<PeerSession>(this, std::move(m_socket), m_requiredNetworkId); auto p = std::make_shared<PeerSession>(this, std::move(m_socket), m_requiredNetworkId);
m_peers.push_back(p); m_peers.push_back(p);
p->start(); p->start();
@ -644,6 +696,9 @@ bool PeerServer::process(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o)
{ {
// First time - just initialise. // First time - just initialise.
m_latestBlockSent = _bc.currentHash(); m_latestBlockSent = _bc.currentHash();
if (m_verbosity)
cout << "Initialising: latest=" << m_latestBlockSent << endl;
for (auto const& i: _tq.transactions()) for (auto const& i: _tq.transactions())
m_transactionsSent.insert(i.first); m_transactionsSent.insert(i.first);
m_lastPeersRequest = chrono::steady_clock::time_point::min(); m_lastPeersRequest = chrono::steady_clock::time_point::min();
@ -657,90 +712,94 @@ bool PeerServer::process(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o)
if (process(_bc)) if (process(_bc))
ret = true; ret = true;
for (auto it = m_incomingTransactions.begin(); it != m_incomingTransactions.end(); ++it) if (m_mode == NodeMode::Full)
if (_tq.import(*it))
ret = true;
else
m_transactionsSent.insert(sha3(*it)); // if we already had the transaction, then don't bother sending it on.
m_incomingTransactions.clear();
// Send any new transactions.
if (fullProcess)
for (auto j: m_peers)
if (auto p = j.lock())
{
bytes b;
uint n = 0;
for (auto const& i: _tq.transactions())
if (!m_transactionsSent.count(i.first) && !p->m_knownTransactions.count(i.first))
{
b += i.second;
++n;
m_transactionsSent.insert(i.first);
}
if (n)
{
RLPStream ts;
PeerSession::prep(ts);
ts.appendList(2) << Transactions;
ts.appendList(n).appendRaw(b).swapOut(b);
seal(b);
p->send(&b);
}
p->m_knownTransactions.clear();
}
// Send any new blocks.
if (fullProcess)
{ {
auto h = _bc.currentHash(); for (auto it = m_incomingTransactions.begin(); it != m_incomingTransactions.end(); ++it)
if (h != m_latestBlockSent) if (_tq.import(*it))
{ ret = true;
// TODO: find where they diverge and send complete new branch. else
RLPStream ts; m_transactionsSent.insert(sha3(*it)); // if we already had the transaction, then don't bother sending it on.
PeerSession::prep(ts); m_incomingTransactions.clear();
ts.appendList(2) << Blocks;
bytes b; // Send any new transactions.
ts.appendList(1).appendRaw(_bc.block(_bc.currentHash())).swapOut(b); if (fullProcess)
seal(b);
for (auto j: m_peers) for (auto j: m_peers)
if (auto p = j.lock()) if (auto p = j.lock())
{ {
if (!p->m_knownBlocks.count(_bc.currentHash())) bytes b;
uint n = 0;
for (auto const& i: _tq.transactions())
if ((!m_transactionsSent.count(i.first) && !p->m_knownTransactions.count(i.first)) || p->m_requireTransactions)
{
b += i.second;
++n;
m_transactionsSent.insert(i.first);
}
if (n)
{
RLPStream ts;
PeerSession::prep(ts);
ts.appendList(n + 1) << Transactions;
ts.appendRaw(b).swapOut(b);
seal(b);
p->send(&b); p->send(&b);
p->m_knownBlocks.clear(); }
p->m_knownTransactions.clear();
p->m_requireTransactions = false;
} }
}
m_latestBlockSent = h;
}
if (fullProcess) // Send any new blocks.
for (bool accepted = 1; accepted;) if (fullProcess)
{ {
accepted = 0; auto h = _bc.currentHash();
if (m_incomingBlocks.size()) if (h != m_latestBlockSent)
for (auto it = prev(m_incomingBlocks.end());; --it) {
{ // TODO: find where they diverge and send complete new branch.
try RLPStream ts;
{ PeerSession::prep(ts);
_bc.import(*it, _o); ts.appendList(2) << Blocks;
it = m_incomingBlocks.erase(it); bytes b;
++accepted; ts.appendRaw(_bc.block(_bc.currentHash())).swapOut(b);
ret = true; seal(b);
} for (auto j: m_peers)
catch (UnknownParent) if (auto p = j.lock())
{ {
// Don't (yet) know its parent. Leave it for later. if (!p->m_knownBlocks.count(_bc.currentHash()))
p->send(&b);
p->m_knownBlocks.clear();
} }
catch (...) }
m_latestBlockSent = h;
}
if (fullProcess)
for (bool accepted = 1; accepted;)
{
accepted = 0;
if (m_incomingBlocks.size())
for (auto it = prev(m_incomingBlocks.end());; --it)
{ {
// Some other error - erase it. try
it = m_incomingBlocks.erase(it); {
_bc.import(*it, _o);
it = m_incomingBlocks.erase(it);
++accepted;
ret = true;
}
catch (UnknownParent)
{
// Don't (yet) know its parent. Leave it for later.
}
catch (...)
{
// Some other error - erase it.
it = m_incomingBlocks.erase(it);
}
if (it == m_incomingBlocks.begin())
break;
} }
}
if (it == m_incomingBlocks.begin())
break;
}
} }
// platform for consensus of social contract. // platform for consensus of social contract.

8
libethereum/PeerNetwork.h

@ -48,7 +48,8 @@ enum PacketType
Transactions, Transactions,
Blocks, Blocks,
GetChain, GetChain,
NotInChain NotInChain,
GetTransactions
}; };
class PeerServer; class PeerServer;
@ -103,6 +104,7 @@ private:
std::chrono::steady_clock::time_point m_disconnect; std::chrono::steady_clock::time_point m_disconnect;
unsigned m_rating; unsigned m_rating;
bool m_requireTransactions;
std::set<h256> m_knownBlocks; std::set<h256> m_knownBlocks;
std::set<h256> m_knownTransactions; std::set<h256> m_knownTransactions;
@ -167,9 +169,9 @@ private:
* 1: Accepting/connecting/connected & one-off info. * 1: Accepting/connecting/connected & one-off info.
* 2: Messages summary. * 2: Messages summary.
* 3: Messages detail. * 3: Messages detail.
* 4: Received raw.
* 5: Sent raw.
* 6: Debug details. * 6: Debug details.
* 8: Received raw.
* 9: Sent raw.
*/ */
unsigned m_verbosity = 4; unsigned m_verbosity = 4;

2
libethereum/RLP.cpp

@ -233,7 +233,7 @@ std::ostream& eth::operator<<(std::ostream& _out, eth::RLP const& _d)
if (_d.isNull()) if (_d.isNull())
_out << "null"; _out << "null";
else if (_d.isInt()) else if (_d.isInt())
_out << std::showbase << std::hex << std::nouppercase << _d.toBigInt(RLP::LaisezFaire); _out << std::showbase << std::hex << std::nouppercase << _d.toBigInt(RLP::LaisezFaire) << dec;
else if (_d.isString()) else if (_d.isString())
_out << eth::escaped(_d.toString(), false); _out << eth::escaped(_d.toString(), false);
else if (_d.isList()) else if (_d.isList())

2
libethereum/TrieCommon.h

@ -58,7 +58,7 @@ struct NibbleSlice
inline std::ostream& operator<<(std::ostream& _out, NibbleSlice const& _m) inline std::ostream& operator<<(std::ostream& _out, NibbleSlice const& _m)
{ {
for (uint i = 0; i < _m.size(); ++i) for (uint i = 0; i < _m.size(); ++i)
_out << std::hex << (int)_m[i]; _out << std::hex << (int)_m[i] << std::dec;
return _out; return _out;
} }

6
libethereum/TrieHash.cpp

@ -85,7 +85,7 @@ void hash256rlp(HexMap const& _s, HexMap::const_iterator _begin, HexMap::const_i
hash256aux(_s, _begin, _end, (unsigned)sharedPre, _rlp); hash256aux(_s, _begin, _end, (unsigned)sharedPre, _rlp);
#if ENABLE_DEBUG_PRINT #if ENABLE_DEBUG_PRINT
if (g_hashDebug) if (g_hashDebug)
std::cerr << s_indent << "= " << hex << sha3(_rlp.out()) << std::endl; std::cerr << s_indent << "= " << hex << sha3(_rlp.out()) << dec << std::endl;
#endif #endif
} }
else else
@ -111,7 +111,7 @@ void hash256rlp(HexMap const& _s, HexMap::const_iterator _begin, HexMap::const_i
{ {
#if ENABLE_DEBUG_PRINT #if ENABLE_DEBUG_PRINT
if (g_hashDebug) if (g_hashDebug)
std::cerr << s_indent << std::hex << i << ": " << std::endl; std::cerr << s_indent << std::hex << i << ": " << std::dec << std::endl;
#endif #endif
hash256aux(_s, b, n, _preLen + 1, _rlp); hash256aux(_s, b, n, _preLen + 1, _rlp);
} }
@ -124,7 +124,7 @@ void hash256rlp(HexMap const& _s, HexMap::const_iterator _begin, HexMap::const_i
#if ENABLE_DEBUG_PRINT #if ENABLE_DEBUG_PRINT
if (g_hashDebug) if (g_hashDebug)
std::cerr << s_indent << "= " << hex << sha3(_rlp.out()) << std::endl; std::cerr << s_indent << "= " << hex << sha3(_rlp.out()) << dec << std::endl;
#endif #endif
} }
} }

6
test/crypto.cpp

@ -35,7 +35,7 @@ int cryptoTest()
cout << "TX: " << RLP(tx) << endl; cout << "TX: " << RLP(tx) << endl;
Transaction t2(tx); Transaction t2(tx);
cout << "SENDER: " << hex << t2.sender() << endl; cout << "SENDER: " << hex << t2.sender() << dec << endl;
secp256k1_start(); secp256k1_start();
@ -76,7 +76,7 @@ int cryptoTest()
int v = 0; int v = 0;
cout << asHex(hmsg) << endl; cout << asHex(hmsg) << endl;
cout << asHex(privkey) << endl; cout << asHex(privkey) << endl;
cout << hex << nonce << endl; cout << hex << nonce << dec << endl;
int ret = secp256k1_ecdsa_sign_compact((byte const*)hmsg.data(), hmsg.size(), sig.data(), privkey.data(), (byte const*)&nonce, &v); int ret = secp256k1_ecdsa_sign_compact((byte const*)hmsg.data(), hmsg.size(), sig.data(), privkey.data(), (byte const*)&nonce, &v);
cout << "MYSIG: " << dec << ret << " " << sig.size() << " " << asHex(sig) << " " << v << endl; cout << "MYSIG: " << dec << ret << " " << sig.size() << " " << asHex(sig) << " " << v << endl;
@ -93,7 +93,7 @@ int cryptoTest()
int ret = secp256k1_ecdsa_recover_compact((byte const*)hmsg.data(), hmsg.size(), (byte const*)sig64.data(), pubkey.data(), &pubkeylen, 0, (int)t.vrs.v - 27); int ret = secp256k1_ecdsa_recover_compact((byte const*)hmsg.data(), hmsg.size(), (byte const*)sig64.data(), pubkey.data(), &pubkeylen, 0, (int)t.vrs.v - 27);
pubkey.resize(pubkeylen); pubkey.resize(pubkeylen);
cout << "RECPUB: " << dec << ret << " " << pubkeylen << " " << asHex(pubkey) << endl; cout << "RECPUB: " << dec << ret << " " << pubkeylen << " " << asHex(pubkey) << endl;
cout << "SENDER: " << hex << low160(eth::sha3(bytesConstRef(&pubkey).cropped(1))) << endl; cout << "SENDER: " << hex << low160(eth::sha3(bytesConstRef(&pubkey).cropped(1))) << dec << endl;
} }
return 0; return 0;
} }

Loading…
Cancel
Save