fix #1976: Add support for configurable pinning only on untrusted peers

This commit is contained in:
Jonas Michel 2023-09-22 17:50:58 -05:00
parent d1c6ba9346
commit 90fd8c0f51
3 changed files with 76 additions and 39 deletions

View File

@ -136,8 +136,10 @@ func (c *Cluster) filterMetrics(ctx context.Context, mSet api.MetricsSet, numMet
// discard blacklisted peers // discard blacklisted peers
continue continue
case c.config.PinOnlyOnTrustedPeers && !c.consensus.IsTrustedPeer(ctx, m.Peer): case c.config.PinOnlyOnTrustedPeers && !c.consensus.IsTrustedPeer(ctx, m.Peer):
// discard peer that are not trusted when // discard peers that are not trusted
// configured. continue
case c.config.PinOnlyOnUntrustedPeers && c.consensus.IsTrustedPeer(ctx, m.Peer):
// discard peers that are trusted
continue continue
case containsPeer(currentAllocs, m.Peer): case containsPeer(currentAllocs, m.Peer):
curPeersMap[m.Peer] = append(curPeersMap[m.Peer], m) curPeersMap[m.Peer] = append(curPeersMap[m.Peer], m)

View File

@ -29,22 +29,23 @@ var DefaultListenAddrs = []string{
// Configuration defaults // Configuration defaults
const ( const (
DefaultEnableRelayHop = true DefaultEnableRelayHop = true
DefaultStateSyncInterval = 5 * time.Minute DefaultStateSyncInterval = 5 * time.Minute
DefaultPinRecoverInterval = 12 * time.Minute DefaultPinRecoverInterval = 12 * time.Minute
DefaultMonitorPingInterval = 15 * time.Second DefaultMonitorPingInterval = 15 * time.Second
DefaultPeerWatchInterval = 5 * time.Second DefaultPeerWatchInterval = 5 * time.Second
DefaultReplicationFactor = -1 DefaultReplicationFactor = -1
DefaultLeaveOnShutdown = false DefaultLeaveOnShutdown = false
DefaultPinOnlyOnTrustedPeers = false DefaultPinOnlyOnTrustedPeers = false
DefaultDisableRepinning = true DefaultPinOnlyOnUntrustedPeers = false
DefaultPeerstoreFile = "peerstore" DefaultDisableRepinning = true
DefaultConnMgrHighWater = 400 DefaultPeerstoreFile = "peerstore"
DefaultConnMgrLowWater = 100 DefaultConnMgrHighWater = 400
DefaultConnMgrGracePeriod = 2 * time.Minute DefaultConnMgrLowWater = 100
DefaultDialPeerTimeout = 3 * time.Second DefaultConnMgrGracePeriod = 2 * time.Minute
DefaultFollowerMode = false DefaultDialPeerTimeout = 3 * time.Second
DefaultMDNSInterval = 10 * time.Second DefaultFollowerMode = false
DefaultMDNSInterval = 10 * time.Second
) )
// ConnMgrConfig configures the libp2p host connection manager. // ConnMgrConfig configures the libp2p host connection manager.
@ -141,6 +142,9 @@ type Config struct {
// PinOnlyOnTrustedPeers limits allocations to trusted peers only. // PinOnlyOnTrustedPeers limits allocations to trusted peers only.
PinOnlyOnTrustedPeers bool PinOnlyOnTrustedPeers bool
// PinOnlyOnUntrustedPeers limits allocations to untrusted peers only.
PinOnlyOnUntrustedPeers bool
// If true, DisableRepinning, ensures that no repinning happens // If true, DisableRepinning, ensures that no repinning happens
// when a node goes down. // when a node goes down.
// This is useful when doing certain types of maintenance, or simply // This is useful when doing certain types of maintenance, or simply
@ -169,27 +173,28 @@ type Config struct {
// saved using JSON. Most configuration keys are converted into simple types // saved using JSON. Most configuration keys are converted into simple types
// like strings, and key names aim to be self-explanatory for the user. // like strings, and key names aim to be self-explanatory for the user.
type configJSON struct { type configJSON struct {
ID string `json:"id,omitempty"` ID string `json:"id,omitempty"`
Peername string `json:"peername"` Peername string `json:"peername"`
PrivateKey string `json:"private_key,omitempty" hidden:"true"` PrivateKey string `json:"private_key,omitempty" hidden:"true"`
Secret string `json:"secret" hidden:"true"` Secret string `json:"secret" hidden:"true"`
LeaveOnShutdown bool `json:"leave_on_shutdown"` LeaveOnShutdown bool `json:"leave_on_shutdown"`
ListenMultiaddress config.Strings `json:"listen_multiaddress"` ListenMultiaddress config.Strings `json:"listen_multiaddress"`
EnableRelayHop bool `json:"enable_relay_hop"` EnableRelayHop bool `json:"enable_relay_hop"`
ConnectionManager *connMgrConfigJSON `json:"connection_manager"` ConnectionManager *connMgrConfigJSON `json:"connection_manager"`
DialPeerTimeout string `json:"dial_peer_timeout"` DialPeerTimeout string `json:"dial_peer_timeout"`
StateSyncInterval string `json:"state_sync_interval"` StateSyncInterval string `json:"state_sync_interval"`
PinRecoverInterval string `json:"pin_recover_interval"` PinRecoverInterval string `json:"pin_recover_interval"`
ReplicationFactorMin int `json:"replication_factor_min"` ReplicationFactorMin int `json:"replication_factor_min"`
ReplicationFactorMax int `json:"replication_factor_max"` ReplicationFactorMax int `json:"replication_factor_max"`
MonitorPingInterval string `json:"monitor_ping_interval"` MonitorPingInterval string `json:"monitor_ping_interval"`
PeerWatchInterval string `json:"peer_watch_interval"` PeerWatchInterval string `json:"peer_watch_interval"`
MDNSInterval string `json:"mdns_interval"` MDNSInterval string `json:"mdns_interval"`
PinOnlyOnTrustedPeers bool `json:"pin_only_on_trusted_peers"` PinOnlyOnTrustedPeers bool `json:"pin_only_on_trusted_peers"`
DisableRepinning bool `json:"disable_repinning"` PinOnlyOnUntrustedPeers bool `json:"pin_only_on_untrusted_peers"`
FollowerMode bool `json:"follower_mode,omitempty"` DisableRepinning bool `json:"disable_repinning"`
PeerstoreFile string `json:"peerstore_file,omitempty"` FollowerMode bool `json:"follower_mode,omitempty"`
PeerAddresses []string `json:"peer_addresses"` PeerstoreFile string `json:"peerstore_file,omitempty"`
PeerAddresses []string `json:"peer_addresses"`
} }
// connMgrConfigJSON configures the libp2p host connection manager. // connMgrConfigJSON configures the libp2p host connection manager.
@ -287,6 +292,10 @@ func (cfg *Config) Validate() error {
return errors.New("cluster.peer_watch_interval is invalid") return errors.New("cluster.peer_watch_interval is invalid")
} }
if cfg.PinOnlyOnTrustedPeers && cfg.PinOnlyOnUntrustedPeers {
return errors.New("cluster.pin_only_on_trusted_peers and pin_only_on_untrusted_peers cannot both be true")
}
rfMax := cfg.ReplicationFactorMax rfMax := cfg.ReplicationFactorMax
rfMin := cfg.ReplicationFactorMin rfMin := cfg.ReplicationFactorMin
@ -379,6 +388,7 @@ func (cfg *Config) setDefaults() {
cfg.PeerWatchInterval = DefaultPeerWatchInterval cfg.PeerWatchInterval = DefaultPeerWatchInterval
cfg.MDNSInterval = DefaultMDNSInterval cfg.MDNSInterval = DefaultMDNSInterval
cfg.PinOnlyOnTrustedPeers = DefaultPinOnlyOnTrustedPeers cfg.PinOnlyOnTrustedPeers = DefaultPinOnlyOnTrustedPeers
cfg.PinOnlyOnUntrustedPeers = DefaultPinOnlyOnUntrustedPeers
cfg.DisableRepinning = DefaultDisableRepinning cfg.DisableRepinning = DefaultDisableRepinning
cfg.FollowerMode = DefaultFollowerMode cfg.FollowerMode = DefaultFollowerMode
cfg.PeerstoreFile = "" // empty so it gets omitted. cfg.PeerstoreFile = "" // empty so it gets omitted.
@ -469,6 +479,7 @@ func (cfg *Config) applyConfigJSON(jcfg *configJSON) error {
cfg.PeerAddresses = peerAddrs cfg.PeerAddresses = peerAddrs
cfg.LeaveOnShutdown = jcfg.LeaveOnShutdown cfg.LeaveOnShutdown = jcfg.LeaveOnShutdown
cfg.PinOnlyOnTrustedPeers = jcfg.PinOnlyOnTrustedPeers cfg.PinOnlyOnTrustedPeers = jcfg.PinOnlyOnTrustedPeers
cfg.PinOnlyOnUntrustedPeers = jcfg.PinOnlyOnUntrustedPeers
cfg.DisableRepinning = jcfg.DisableRepinning cfg.DisableRepinning = jcfg.DisableRepinning
cfg.FollowerMode = jcfg.FollowerMode cfg.FollowerMode = jcfg.FollowerMode
@ -520,6 +531,7 @@ func (cfg *Config) toConfigJSON() (jcfg *configJSON, err error) {
jcfg.PeerWatchInterval = cfg.PeerWatchInterval.String() jcfg.PeerWatchInterval = cfg.PeerWatchInterval.String()
jcfg.MDNSInterval = cfg.MDNSInterval.String() jcfg.MDNSInterval = cfg.MDNSInterval.String()
jcfg.PinOnlyOnTrustedPeers = cfg.PinOnlyOnTrustedPeers jcfg.PinOnlyOnTrustedPeers = cfg.PinOnlyOnTrustedPeers
jcfg.PinOnlyOnUntrustedPeers = cfg.PinOnlyOnUntrustedPeers
jcfg.DisableRepinning = cfg.DisableRepinning jcfg.DisableRepinning = cfg.DisableRepinning
jcfg.PeerstoreFile = cfg.PeerstoreFile jcfg.PeerstoreFile = cfg.PeerstoreFile
jcfg.PeerAddresses = []string{} jcfg.PeerAddresses = []string{}

View File

@ -213,6 +213,22 @@ func TestLoadJSON(t *testing.T) {
t.Error("default conn manager values not set") t.Error("default conn manager values not set")
} }
}) })
t.Run("expected pin_only_on_untrusted_peers", func(t *testing.T) {
cfg, err := loadJSON2(
t,
func(j *configJSON) {
j.PinOnlyOnTrustedPeers = false
j.PinOnlyOnUntrustedPeers = true
},
)
if err != nil {
t.Fatal(err)
}
if !cfg.PinOnlyOnUntrustedPeers {
t.Error("expected pin_only_on_untrusted_peers to be true")
}
})
} }
func TestToJSON(t *testing.T) { func TestToJSON(t *testing.T) {
@ -283,4 +299,11 @@ func TestValidate(t *testing.T) {
if cfg.Validate() == nil { if cfg.Validate() == nil {
t.Fatal("expected error validating") t.Fatal("expected error validating")
} }
cfg.Default()
cfg.PinOnlyOnTrustedPeers = true
cfg.PinOnlyOnUntrustedPeers = true
if cfg.Validate() == nil {
t.Fatal("expected error validating")
}
} }