Skip to content

update gossip #300

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions cmake/Hunter/config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,9 @@
# CMAKE_ARGS "CMAKE_VARIABLE=value"
# )

hunter_config(
soralog
VERSION 0.2.5
URL https://github.com/qdrvm/soralog/archive/refs/tags/v0.2.5.tar.gz
SHA1 1dafdb9e1921b4069f9e1dad0d0acfae24166bd2
KEEP_PACKAGE_SOURCES
)

hunter_config(
ZLIB
VERSION 1.3.0-p0
URL https://github.com/cpp-pm/zlib/archive/refs/tags/v1.3.0-p0.tar.gz
SHA1 311ca59e20cbbfe9d9e05196c12c6ae109093987
)

hunter_config(
qtils
VERSION 0.1.0
URL https://github.com/qdrvm/qtils/archive/refs/tags/v0.1.0.tar.gz
SHA1 acc28902af7dc5d74ac33d486ad2261906716f5e
CMAKE_ARGS
FORMAT_ERROR_WITH_FULLTYPE=ON
KEEP_PACKAGE_SOURCES
)
4 changes: 2 additions & 2 deletions cmake/Hunter/init.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ set(
include(${CMAKE_CURRENT_LIST_DIR}/HunterGate.cmake)

HunterGate(
URL https://github.com/qdrvm/hunter/archive/refs/tags/v0.25.3-qdrvm28.tar.gz
SHA1 a4f1b0f42464e07790b7f90b783a822d71be6c6d
URL https://github.com/qdrvm/hunter/archive/86e53c752977bf5a5efb6590c26941ed3fec8187.zip
SHA1 7121f2cbf052cc6cb0a526a89e9b4aca5bf3cd54
LOCAL
)
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ namespace libp2p::basic {
}
}

private:
void callDeferred();

private:
/// Current time, set manually
std::chrono::milliseconds current_clock_;

Expand Down
24 changes: 24 additions & 0 deletions include/libp2p/connection/stream_pair.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Copyright Quadrivium LLC
* All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <libp2p/peer/peer_id.hpp>

namespace libp2p::basic {
class Scheduler;
} // namespace libp2p::basic

namespace libp2p::connection {
struct Stream;

/**
* Create pair of connected bidirectional read-writers
* implementing `Stream` interface.
*/
std::pair<std::shared_ptr<Stream>, std::shared_ptr<Stream>> streamPair(
std::shared_ptr<basic::Scheduler> post, PeerId peer1, PeerId peer2);
} // namespace libp2p::connection
4 changes: 4 additions & 0 deletions include/libp2p/peer/protocol.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ namespace libp2p::peer {
std::string;

} // namespace libp2p::peer

namespace libp2p {
using peer::ProtocolName;
} // namespace libp2p
18 changes: 18 additions & 0 deletions include/libp2p/protocol/gossip/explicit_peers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Copyright Quadrivium LLC
* All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <libp2p/peer/peer_id.hpp>

namespace libp2p::protocol::gossip {
class ExplicitPeers {
public:
bool contains(const PeerId &) const {
return false;
}
};
} // namespace libp2p::protocol::gossip
145 changes: 128 additions & 17 deletions include/libp2p/protocol/gossip/gossip.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,18 @@
#include <functional>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>

#include <boost/optional.hpp>

#include <libp2p/common/byteutil.hpp>
#include <libp2p/multi/multiaddress.hpp>
#include <libp2p/peer/peer_id.hpp>
#include <libp2p/peer/protocol.hpp>
#include <libp2p/protocol/common/subscription.hpp>
#include <libp2p/protocol/gossip/peer_kind.hpp>
#include <libp2p/protocol/gossip/score_config.hpp>

namespace libp2p {
struct Host;
Expand All @@ -41,36 +45,37 @@ namespace libp2p::protocol::gossip {
struct Config {
/// Network density factors for gossip meshes
size_t D_min = 5;
size_t D_lazy = 6;
size_t D = 6;
size_t D_max = 10;

/// Affects how peers are selected when pruning a mesh due to over
/// subscription.
///
/// At least `retain_scores` of the retained peers will be high-scoring,
/// while the remainder
/// are chosen randomly (D_score in the spec, default is 4).
size_t retain_scores = 4;

/// Affects how many peers we will emit gossip to at each heartbeat.
///
/// We will send gossip to `gossip_factor * (total number of non-mesh
/// peers)`, or `gossip_lazy`, whichever is greater. The default is 0.25.
double gossip_factor = 0.25;

/// Ideal number of connected peers to support the network
size_t ideal_connections_num = 100;

/// Maximum number of simultaneous connections after which new
/// incoming peers will be rejected
size_t max_connections_num = 1000;

/// Forward messages to all subscribers not in mesh
/// (floodsub mode compatibility)
bool floodsub_forward_mode = false;

/// Forward local message to local subscribers
bool echo_forward_mode = false;

/// Read or write timeout per whole network operation
std::chrono::milliseconds rw_timeout_msec{std::chrono::seconds(10)};

/// Lifetime of a message in message cache
std::chrono::milliseconds message_cache_lifetime_msec{
std::chrono::minutes(2)};

/// Topic's message seen cache lifetime
std::chrono::milliseconds seen_cache_lifetime_msec{
message_cache_lifetime_msec * 3 / 4};

/// Topic's seen cache limit
unsigned seen_cache_limit = 100;

/// Heartbeat interval
std::chrono::milliseconds heartbeat_interval_msec{1000};

Expand All @@ -86,11 +91,117 @@ namespace libp2p::protocol::gossip {
/// Max RPC message size
size_t max_message_size = 1 << 24;

/// Protocol version
std::string protocol_version = "/meshsub/1.0.0";
/// Protocol versions
std::unordered_map<ProtocolName, PeerKind> protocol_versions{
{"/floodsub/1.0.0", PeerKind::Floodsub},
{"/meshsub/1.0.0", PeerKind::Gossipsub},
{"/meshsub/1.1.0", PeerKind::Gossipsubv1_1},
{"/meshsub/1.2.0", PeerKind::Gossipsubv1_2},
};

/// Sign published messages
bool sign_messages = false;

/// Number of heartbeats to keep in the `memcache`
size_t history_length{5};

/// Number of past heartbeats to gossip about (default is 3).
size_t history_gossip{3};

/// Time to live for fanout peers (default is 60 seconds).
std::chrono::seconds fanout_ttl{60};

/// Duplicates are prevented by storing message id's of known messages in an
/// LRU time cache. This settings sets the time period that messages are
/// stored in the cache. Duplicates can be received if duplicate messages
/// are sent at a time greater than this setting apart. The default is 1
/// minute.
std::chrono::seconds duplicate_cache_time{60};

/// Controls the backoff time for pruned peers. This is how long
/// a peer must wait before attempting to graft into our mesh again after
/// being pruned. When pruning a peer, we send them our value of
/// `prune_backoff` so they know the minimum time to wait. Peers running
/// older versions may not send a backoff time, so if we receive a prune
/// message without one, we will wait at least `prune_backoff` before
/// attempting to re-graft. The default is one minute.
std::chrono::seconds prune_backoff{60};

/// Controls the backoff time when unsubscribing from a topic.
///
/// This is how long to wait before resubscribing to the topic. A short
/// backoff period in case of an unsubscribe event allows reaching a healthy
/// mesh in a more timely manner. The default is 10 seconds.
std::chrono::seconds unsubscribe_backoff{10};

/// Number of heartbeat slots considered as slack for backoffs. This
/// guarantees that we wait at least backoff_slack heartbeats after a
/// backoff is over before we try to graft. This solves problems occurring
/// through high latencies. In particular if `backoff_slack *
/// heartbeat_interval` is longer than any latencies between processing
/// prunes on our side and processing prunes on the receiving side this
/// guarantees that we get not punished for too early grafting. The default
/// is 1.
size_t backoff_slack = 1;

/// Whether to do flood publishing or not. If enabled newly created messages
/// will always be
/// sent to all peers that are subscribed to the topic and have a good
/// enough score. The default is true.
bool flood_publish = true;

/// If a GRAFT comes before `graft_flood_threshold` has elapsed since the
/// last PRUNE, then there is an extra score penalty applied to the peer
/// through P7.
std::chrono::milliseconds graft_flood_threshold = std::chrono::seconds{10};

/// Minimum number of outbound peers in the mesh network before adding more
/// (D_out in the spec). This value must be smaller or equal than `mesh_n /
/// 2` and smaller than `mesh_n_low`. The default is 2.
size_t mesh_outbound_min = 2;

/// Number of heartbeat ticks that specify the interval in which
/// opportunistic grafting is applied. Every `opportunistic_graft_ticks` we
/// will attempt to select some high-scoring mesh peers to replace
/// lower-scoring ones, if the median score of our mesh peers falls below a
/// threshold (see
/// <https://godoc.org/github.com/libp2p/go-libp2p-pubsub#PeerScoreThresholds>).
/// The default is 60.
size_t opportunistic_graft_ticks = 60;

/// The maximum number of new peers to graft to during opportunistic
/// grafting. The default is 2.
size_t opportunistic_graft_peers = 2;

/// The maximum number of messages to include in an IHAVE message.
/// Also controls the maximum number of IHAVE ids we will accept and request
/// with IWANT from a peer within a heartbeat, to protect from IHAVE floods.
/// You should adjust this value from the default if your system is pushing
/// more than 5000 messages in GossipSubHistoryGossip heartbeats; with the
/// defaults this is 1666 messages/s. The default is 5000.
size_t max_ihave_length = 5000;

/// Time to wait for a message requested through IWANT following an IHAVE
/// advertisement. If the message is not received within this window, a
/// broken promise is declared and the router may apply behavioural
/// penalties. The default is 3 seconds.
std::chrono::milliseconds iwant_followup_time = std::chrono::seconds{3};

/// The message size threshold for which IDONTWANT messages are sent.
/// Sending IDONTWANT messages for small messages can have a negative effect
/// to the overall traffic and CPU load. This acts as a lower bound cutoff
/// for the message size to which IDONTWANT won't be sent to peers. Only
/// works if the peers support Gossipsub1.2 (see
/// <https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.2.md#idontwant-message>)
/// default is 1kB
size_t idontwant_message_size_threshold = 1000;

/// Send IDONTWANT messages after publishing message on gossip. This is an
/// optimisation to avoid bandwidth consumption by downloading the published
/// message over gossip. By default it is false.
bool idontwant_on_publish = false;

ScoreConfig score;
};

using TopicId = std::string;
Expand Down
19 changes: 19 additions & 0 deletions include/libp2p/protocol/gossip/peer_kind.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Copyright Quadrivium LLC
* All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <cstdint>

namespace libp2p::protocol::gossip {
enum class PeerKind : uint8_t {
NotSupported,
Floodsub,
Gossipsub,
Gossipsubv1_1,
Gossipsubv1_2,
};
} // namespace libp2p::protocol::gossip
Loading
Loading