2019-07-02 12:40:25 +00:00
|
|
|
package lp2p
|
2019-07-01 09:09:48 +00:00
|
|
|
|
|
|
|
import (
|
2019-11-19 23:31:55 +00:00
|
|
|
"context"
|
2020-04-29 13:41:44 +00:00
|
|
|
"time"
|
2019-11-19 23:31:55 +00:00
|
|
|
|
2019-07-01 09:09:48 +00:00
|
|
|
host "github.com/libp2p/go-libp2p-core/host"
|
2019-11-19 23:31:55 +00:00
|
|
|
peer "github.com/libp2p/go-libp2p-core/peer"
|
2019-07-01 09:09:48 +00:00
|
|
|
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
2019-11-19 23:31:55 +00:00
|
|
|
ma "github.com/multiformats/go-multiaddr"
|
2019-07-01 09:09:48 +00:00
|
|
|
"go.uber.org/fx"
|
|
|
|
|
2020-04-29 13:41:44 +00:00
|
|
|
"github.com/filecoin-project/lotus/build"
|
|
|
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
2019-10-18 04:47:41 +00:00
|
|
|
"github.com/filecoin-project/lotus/node/modules/helpers"
|
2019-07-01 09:09:48 +00:00
|
|
|
)
|
|
|
|
|
2020-04-29 14:09:39 +00:00
|
|
|
func init() {
|
|
|
|
// configure larger overlay parameters
|
|
|
|
pubsub.GossipSubD = 8
|
|
|
|
pubsub.GossipSubDscore = 6
|
|
|
|
pubsub.GossipSubDlo = 6
|
|
|
|
pubsub.GossipSubDhi = 12
|
|
|
|
pubsub.GossipSubDlazy = 12
|
|
|
|
}
|
|
|
|
|
2019-11-20 20:31:00 +00:00
|
|
|
type PubsubOpt func(host.Host) pubsub.Option
|
2019-11-19 23:31:55 +00:00
|
|
|
|
2019-11-20 20:31:00 +00:00
|
|
|
func PubsubTracer() PubsubOpt {
|
|
|
|
return func(host host.Host) pubsub.Option {
|
|
|
|
pi, err := peer.AddrInfoFromP2pAddr(ma.StringCast("/ip4/147.75.67.199/tcp/4001/p2p/QmTd6UvR47vUidRNZ1ZKXHrAFhqTJAD27rKL9XYghEKgKX"))
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
tr, err := pubsub.NewRemoteTracer(context.TODO(), host, *pi)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2019-11-19 23:31:55 +00:00
|
|
|
|
2019-11-20 20:31:00 +00:00
|
|
|
return pubsub.WithEventTracer(tr)
|
|
|
|
}
|
2019-11-19 23:31:55 +00:00
|
|
|
}
|
|
|
|
|
2019-11-20 20:31:00 +00:00
|
|
|
func GossipSub(pubsubOptions ...PubsubOpt) interface{} {
|
2020-04-29 14:03:41 +00:00
|
|
|
return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, nn dtypes.NetworkName, bp dtypes.BootstrapPeers) (service *pubsub.PubSub, err error) {
|
|
|
|
bootstrappers := make(map[peer.ID]struct{})
|
|
|
|
for _, pi := range bp {
|
|
|
|
bootstrappers[pi.ID] = struct{}{}
|
|
|
|
}
|
|
|
|
_, isBootstrapNode := bootstrappers[host.ID()]
|
|
|
|
|
2020-04-29 13:41:44 +00:00
|
|
|
v11Options := []pubsub.Option{
|
|
|
|
// Gossipsubv1.1 configuration
|
|
|
|
pubsub.WithFloodPublish(true),
|
|
|
|
pubsub.WithPeerScore(
|
|
|
|
&pubsub.PeerScoreParams{
|
2020-04-29 14:03:41 +00:00
|
|
|
AppSpecificScore: func(p peer.ID) float64 {
|
|
|
|
// return a heavy positive score for bootstrappers so that we don't unilaterally prune
|
|
|
|
// them and accept PX from them.
|
|
|
|
// we don't do that in the bootstrappers themselves to avoid creating a closed mesh
|
|
|
|
// between them (however we might want to consider doing just that)
|
|
|
|
_, ok := bootstrappers[p]
|
2020-04-29 15:56:58 +00:00
|
|
|
if ok && !isBootstrapNode {
|
2020-04-29 14:03:41 +00:00
|
|
|
return 2500
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: we want to plug the application specific score to the node itself in order
|
|
|
|
// to provide feedback to the pubsub system based on observed behaviour
|
|
|
|
return 0
|
|
|
|
},
|
2020-04-29 13:41:44 +00:00
|
|
|
AppSpecificWeight: 1,
|
|
|
|
|
|
|
|
// This sets the IP colocation threshold to 1 peer per
|
|
|
|
IPColocationFactorThreshold: 1,
|
|
|
|
IPColocationFactorWeight: -100,
|
|
|
|
// TODO we want to whitelist IPv6 /64s that belong to datacenters etc
|
|
|
|
// IPColocationFactorWhitelist: map[string]struct{}{},
|
|
|
|
|
2020-04-29 19:50:51 +00:00
|
|
|
DecayInterval: pubsub.DefaultDecayInterval,
|
|
|
|
DecayToZero: pubsub.DefaultDecayToZero,
|
2020-04-29 13:41:44 +00:00
|
|
|
|
|
|
|
// this retains non-positive scores for 6 hours
|
|
|
|
RetainScore: 6 * time.Hour,
|
|
|
|
|
|
|
|
// topic parameters
|
|
|
|
Topics: map[string]*pubsub.TopicScoreParams{
|
2020-04-29 16:01:45 +00:00
|
|
|
build.BlocksTopic(nn): {
|
2020-04-29 13:41:44 +00:00
|
|
|
// expected 10 blocks/min
|
2020-04-29 20:15:29 +00:00
|
|
|
TopicWeight: 0.1, // max is 50, max mesh penalty is -10, single invalid message is -100
|
2020-04-29 13:41:44 +00:00
|
|
|
|
|
|
|
// 1 tick per second, maxes at 1 after 1 hour
|
|
|
|
TimeInMeshWeight: 0.00027, // ~1/3600
|
|
|
|
TimeInMeshQuantum: time.Second,
|
|
|
|
TimeInMeshCap: 1,
|
|
|
|
|
|
|
|
// deliveries decay after 1 hour, cap at 100 blocks
|
2020-04-29 20:15:29 +00:00
|
|
|
FirstMessageDeliveriesWeight: 5, // max value is 500
|
2020-04-29 19:50:51 +00:00
|
|
|
FirstMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Hour),
|
2020-04-29 20:15:29 +00:00
|
|
|
FirstMessageDeliveriesCap: 100, // 100 blocks in an hour
|
2020-04-29 13:41:44 +00:00
|
|
|
|
2020-04-29 20:15:29 +00:00
|
|
|
// tracks deliveries in the last minute
|
|
|
|
// penalty activates at 1 minute and expects ~0.4 blocks
|
2020-04-29 19:50:51 +00:00
|
|
|
MeshMessageDeliveriesWeight: -576, // max penalty is -100
|
2020-04-29 20:15:29 +00:00
|
|
|
MeshMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Minute),
|
|
|
|
MeshMessageDeliveriesCap: 10, // 10 blocks in a minute
|
|
|
|
MeshMessageDeliveriesThreshold: 0.41666, // 10/12/2 blocks/min
|
2020-04-29 13:41:44 +00:00
|
|
|
MeshMessageDeliveriesWindow: 10 * time.Millisecond,
|
|
|
|
MeshMessageDeliveriesActivation: time.Minute,
|
|
|
|
|
|
|
|
// decays after 15 min
|
|
|
|
MeshFailurePenaltyWeight: -576,
|
2020-04-29 19:50:51 +00:00
|
|
|
MeshFailurePenaltyDecay: pubsub.ScoreParameterDecay(15 * time.Minute),
|
2020-04-29 13:41:44 +00:00
|
|
|
|
|
|
|
// invalid messages decay after 1 hour
|
|
|
|
InvalidMessageDeliveriesWeight: -1000,
|
2020-04-29 19:50:51 +00:00
|
|
|
InvalidMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Hour),
|
2020-04-29 13:41:44 +00:00
|
|
|
},
|
2020-04-29 16:01:45 +00:00
|
|
|
build.MessagesTopic(nn): {
|
2020-04-29 13:41:44 +00:00
|
|
|
// expected > 1 tx/second
|
2020-04-29 20:15:29 +00:00
|
|
|
TopicWeight: 0.05, // max is 25, max mesh penalty is -5, single invalid message is -100
|
2020-04-29 13:41:44 +00:00
|
|
|
|
|
|
|
// 1 tick per second, maxes at 1 hour
|
|
|
|
TimeInMeshWeight: 0.0002778, // ~1/3600
|
|
|
|
TimeInMeshQuantum: time.Second,
|
|
|
|
TimeInMeshCap: 1,
|
|
|
|
|
|
|
|
// deliveries decay after 10min, cap at 1000 tx
|
2020-04-29 20:15:29 +00:00
|
|
|
FirstMessageDeliveriesWeight: 0.5, // max value is 500
|
2020-04-29 19:50:51 +00:00
|
|
|
FirstMessageDeliveriesDecay: pubsub.ScoreParameterDecay(10 * time.Minute),
|
2020-04-29 13:41:44 +00:00
|
|
|
FirstMessageDeliveriesCap: 1000,
|
|
|
|
|
2020-04-29 20:15:29 +00:00
|
|
|
// tracks deliveries in the last minute
|
|
|
|
// penalty activates at 1 min and expects 2.5 txs
|
|
|
|
MeshMessageDeliveriesWeight: -16, // max penalty is -100
|
|
|
|
MeshMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Minute),
|
|
|
|
MeshMessageDeliveriesCap: 100, // 100 txs in a minute
|
|
|
|
MeshMessageDeliveriesThreshold: 2.5, // 60/12/2 txs/minute
|
2020-04-29 13:41:44 +00:00
|
|
|
MeshMessageDeliveriesWindow: 10 * time.Millisecond,
|
|
|
|
MeshMessageDeliveriesActivation: time.Minute,
|
|
|
|
|
|
|
|
// decays after 5min
|
2020-04-29 20:15:29 +00:00
|
|
|
MeshFailurePenaltyWeight: -16,
|
2020-04-29 19:50:51 +00:00
|
|
|
MeshFailurePenaltyDecay: pubsub.ScoreParameterDecay(5 * time.Minute),
|
2020-04-29 13:41:44 +00:00
|
|
|
|
|
|
|
// invalid messages decay after 1 hour
|
2020-04-29 20:15:29 +00:00
|
|
|
InvalidMessageDeliveriesWeight: -2000,
|
2020-04-29 19:50:51 +00:00
|
|
|
InvalidMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Hour),
|
2020-04-29 13:41:44 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
&pubsub.PeerScoreThresholds{
|
|
|
|
GossipThreshold: -500,
|
|
|
|
PublishThreshold: -1000,
|
|
|
|
GraylistThreshold: -2500,
|
|
|
|
AcceptPXThreshold: 1000,
|
|
|
|
OpportunisticGraftThreshold: 2.5,
|
|
|
|
},
|
|
|
|
),
|
|
|
|
}
|
|
|
|
|
2020-04-29 14:03:41 +00:00
|
|
|
// enable Peer eXchange on bootstrappers
|
|
|
|
if isBootstrapNode {
|
|
|
|
v11Options = append(v11Options, pubsub.WithPeerExchange(true))
|
|
|
|
}
|
2020-04-29 13:41:44 +00:00
|
|
|
|
|
|
|
// TODO: we want to hook the peer score inspector so that we can gain visibility
|
2020-04-29 14:03:41 +00:00
|
|
|
// in peer scores for debugging purposes -- this might be trigged by metrics collection
|
2020-04-29 13:41:44 +00:00
|
|
|
// v11Options = append(v11Options, pubsub.WithPeerScoreInspect(XXX, time.Second))
|
|
|
|
|
|
|
|
options := append(v11Options, paresOpts(host, pubsubOptions)...)
|
|
|
|
|
|
|
|
return pubsub.NewGossipSub(helpers.LifecycleCtx(mctx, lc), host, options...)
|
2019-07-01 09:09:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-20 20:31:00 +00:00
|
|
|
func paresOpts(host host.Host, in []PubsubOpt) []pubsub.Option {
|
|
|
|
out := make([]pubsub.Option, len(in))
|
|
|
|
for k, v := range in {
|
|
|
|
out[k] = v(host)
|
2019-07-01 09:09:48 +00:00
|
|
|
}
|
2019-11-20 20:31:00 +00:00
|
|
|
return out
|
2019-07-01 09:09:48 +00:00
|
|
|
}
|