const& _h)
{
- return (*this |= _h.template bloom());
+ return (*this |= _h.template bloomPart
());
}
template inline bool containsBloom(FixedHash const& _h)
{
- return contains(_h.template bloom());
+ return contains(_h.template bloomPart
());
}
- template inline FixedHash bloom() const
+ template inline FixedHash bloomPart() const
{
+ static_assert((M & (M - 1)) == 0, "M must be power-of-two");
static const unsigned c_bloomBits = M * 8;
unsigned mask = c_bloomBits - 1;
unsigned bloomBytes = (dev::toLog2(c_bloomBits) + 7) / 8;
diff --git a/libethash-cl/ethash_cl_miner.cpp b/libethash-cl/ethash_cl_miner.cpp
index 6c2f8269a..b160cdd94 100644
--- a/libethash-cl/ethash_cl_miner.cpp
+++ b/libethash-cl/ethash_cl_miner.cpp
@@ -429,7 +429,8 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook
};
queue pending;
- static uint32_t const c_zero = 0;
+ // this can't be a static because in MacOSX OpenCL implementation a segfault occurs when a static is passed to OpenCL functions
+ uint32_t const c_zero = 0;
// update header constant buffer
m_queue.enqueueWriteBuffer(m_header, false, 0, 32, header);
diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp
index 1482719c6..a0d8e1297 100644
--- a/libp2p/Host.cpp
+++ b/libp2p/Host.cpp
@@ -326,7 +326,8 @@ void Host::onNodeTableEvent(NodeId const& _n, NodeTableEventType const& _e)
{
clog(NetP2PNote) << "p2p.host.nodeTable.events.NodeEntryDropped " << _n;
RecursiveGuard l(x_sessions);
- m_peers.erase(_n);
+ if (m_peers.count(_n) && !m_peers[_n]->required)
+ m_peers.erase(_n);
}
}
@@ -637,27 +638,40 @@ void Host::run(boost::system::error_code const&)
// updated. // disconnectLatePeers();
// todo: update peerSlotsAvailable()
- unsigned pendingCount = 0;
- DEV_GUARDED(x_pendingNodeConns)
- pendingCount = m_pendingPeerConns.size();
- int openSlots = m_idealPeerCount - peerCount() - pendingCount;
- if (openSlots > 0)
+
+ list> toConnect;
+ unsigned reqConn = 0;
{
- list> toConnect;
+ RecursiveGuard l(x_sessions);
+ for (auto const& p: m_peers)
{
- RecursiveGuard l(x_sessions);
- for (auto p: m_peers)
- if (p.second->shouldReconnect() && !havePeerSession(p.second->id))
- toConnect.push_back(p.second);
+ bool haveSession = havePeerSession(p.second->id);
+ bool required = p.second->required;
+ if (haveSession && required)
+ reqConn++;
+ else if (!haveSession && p.second->shouldReconnect() && (!m_netPrefs.pin || required))
+ toConnect.push_back(p.second);
}
+ }
+
+ for (auto p: toConnect)
+ if (p->required && reqConn++ < m_idealPeerCount)
+ connect(p);
+
+ if (!m_netPrefs.pin)
+ {
+ unsigned pendingCount = 0;
+ DEV_GUARDED(x_pendingNodeConns)
+ pendingCount = m_pendingPeerConns.size();
+ int openSlots = m_idealPeerCount - peerCount() - pendingCount + reqConn;
+ if (openSlots > 0)
+ {
+ for (auto p: toConnect)
+ if (!p->required && openSlots--)
+ connect(p);
- for (auto p: toConnect)
- if (openSlots--)
- connect(p);
- else
- break;
-
- m_nodeTable->discover();
+ m_nodeTable->discover();
+ }
}
auto runcb = [this](boost::system::error_code const& error) { run(error); };
@@ -698,7 +712,7 @@ void Host::startedWorking()
else
clog(NetP2PNote) << "p2p.start.notice id:" << id() << "TCP Listen port is invalid or unavailable.";
- shared_ptr nodeTable(new NodeTable(m_ioService, m_alias, NodeIPEndpoint(bi::address::from_string(listenAddress()), listenPort(), listenPort())));
+ shared_ptr nodeTable(new NodeTable(m_ioService, m_alias, NodeIPEndpoint(bi::address::from_string(listenAddress()), listenPort(), listenPort()), m_netPrefs.discovery));
nodeTable->setEventHandler(new HostNodeTableHandler(*this));
m_nodeTable = nodeTable;
restoreNetwork(&m_restoreNetwork);
diff --git a/libp2p/Network.h b/libp2p/Network.h
index d02ce3cbe..e70dd89ea 100644
--- a/libp2p/Network.h
+++ b/libp2p/Network.h
@@ -52,6 +52,8 @@ struct NetworkPreferences
std::string listenIPAddress;
unsigned short listenPort = 30303;
bool traverseNAT = true;
+ bool discovery = true; // Discovery is activated with network.
+ bool pin = false; // Only connect to trusted ("required") peers.
};
/**
diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp
index 6344dc263..1a0b11734 100644
--- a/libp2p/NodeTable.cpp
+++ b/libp2p/NodeTable.cpp
@@ -40,14 +40,15 @@ const char* NodeTableIngress::name() { return "<connect();
- doRefreshBuckets(boost::system::error_code());
+ if (!m_disabled)
+ {
+ m_socketPointer->connect();
+ doRefreshBuckets(boost::system::error_code());
+ }
}
NodeTable::~NodeTable()
diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h
index 0ec13c828..d31a356ef 100644
--- a/libp2p/NodeTable.h
+++ b/libp2p/NodeTable.h
@@ -130,7 +130,7 @@ public:
enum NodeRelation { Unknown = 0, Known };
/// Constructor requiring host for I/O, credentials, and IP Address and port to listen on.
- NodeTable(ba::io_service& _io, KeyPair const& _alias, NodeIPEndpoint const& _endpoint);
+ NodeTable(ba::io_service& _io, KeyPair const& _alias, NodeIPEndpoint const& _endpoint, bool _enabled = true);
~NodeTable();
/// Returns distance based on xor metric two node ids. Used by NodeEntry and NodeTable.
@@ -271,6 +271,8 @@ private:
boost::asio::deadline_timer m_bucketRefreshTimer; ///< Timer which schedules and enacts bucket refresh.
boost::asio::deadline_timer m_evictionCheckTimer; ///< Timer for handling node evictions.
+
+ bool m_disabled; ///< Disable discovery.
};
inline std::ostream& operator<<(std::ostream& _out, NodeTable const& _nodeTable)
diff --git a/libp2p/Peer.cpp b/libp2p/Peer.cpp
index 6f368a4b4..a8b4a993d 100644
--- a/libp2p/Peer.cpp
+++ b/libp2p/Peer.cpp
@@ -38,6 +38,8 @@ bool Peer::shouldReconnect() const
unsigned Peer::fallbackSeconds() const
{
+ if (required)
+ return 5;
switch (m_lastDisconnect)
{
case BadProtocol:
diff --git a/test/libevm/vm.cpp b/test/libevm/vm.cpp
index 5bbab2e1c..ea9339f05 100644
--- a/test/libevm/vm.cpp
+++ b/test/libevm/vm.cpp
@@ -323,6 +323,7 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
fev.thisTxCode = get<3>(fev.addresses.at(fev.myAddress));
fev.code = fev.thisTxCode;
}
+ fev.codeHash = sha3(fev.code);
bytes output;
bool vmExceptionOccured = false;