From 022581d50b53da45cbb4f24e3a3b48e2fe385995 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Mon, 16 Dec 2019 22:51:41 -0800 Subject: [PATCH] add routine to tag miners peer IDs as high value in connection manager --- chain/stmgr/utils.go | 15 +++++++ go.mod | 2 + go.sum | 10 +++++ node/builder.go | 2 + node/impl/common.go | 7 +++- node/impl/full/state.go | 13 +----- node/modules/lp2p/host.go | 3 +- node/modules/lp2p/libp2p.go | 19 +++++++++ node/peers/miners.go | 84 +++++++++++++++++++++++++++++++++++++ 9 files changed, 140 insertions(+), 15 deletions(-) create mode 100644 node/peers/miners.go diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 85a43cc0d..b6dcfe335 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -270,6 +270,21 @@ func GetStorageDeal(ctx context.Context, sm *StateManager, dealId uint64, ts *ty return &ocd, nil } +func ListMinerActors(ctx context.Context, sm *StateManager, ts *types.TipSet) ([]address.Address, error) { + var state actors.StoragePowerState + if _, err := sm.LoadActorState(ctx, actors.StoragePowerAddress, &state, ts); err != nil { + return nil, err + } + + cst := hamt.CSTFromBstore(sm.ChainStore().Blockstore()) + miners, err := actors.MinerSetList(ctx, cst, state.Miners) + if err != nil { + return nil, err + } + + return miners, nil +} + func LoadSectorsFromSet(ctx context.Context, bs blockstore.Blockstore, ssc cid.Cid) ([]*api.ChainSectorInfo, error) { blks := amt.WrapBlockstore(bs) a, err := amt.LoadAMT(blks, ssc) diff --git a/go.mod b/go.mod index c618ae8df..49cff8ea1 100644 --- a/go.mod +++ b/go.mod @@ -52,6 +52,7 @@ require ( github.com/libp2p/go-libp2p-connmgr v0.1.0 github.com/libp2p/go-libp2p-core v0.2.4 github.com/libp2p/go-libp2p-discovery v0.2.0 + github.com/libp2p/go-libp2p-host v0.0.1 github.com/libp2p/go-libp2p-kad-dht v0.1.1 github.com/libp2p/go-libp2p-mplex v0.2.1 github.com/libp2p/go-libp2p-peer v0.2.0 @@ -83,6 +84,7 @@ require ( github.com/opentracing/opentracing-go v1.1.0 github.com/otiai10/copy v1.0.2 github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a + github.com/prometheus/common v0.2.0 github.com/smartystreets/assertions v1.0.1 // indirect github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect github.com/stretchr/testify v1.4.0 diff --git a/go.sum b/go.sum index f0d9ed228..a7d254ed4 100644 --- a/go.sum +++ b/go.sum @@ -23,7 +23,9 @@ github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/akavel/rsrc v0.8.0 h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/apache/thrift v0.12.0 h1:pODnxUFNcjP9UTLZGTdeh+j16A8lJbRvD3rOtrk/7bs= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= @@ -327,7 +329,9 @@ github.com/libp2p/go-libp2p-discovery v0.1.0 h1:j+R6cokKcGbnZLf4kcNwpx6mDEUPF3N6 github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g= github.com/libp2p/go-libp2p-discovery v0.2.0 h1:1p3YSOq7VsgaL+xVHPi8XAmtGyas6D2J6rWBEfz/aiY= github.com/libp2p/go-libp2p-discovery v0.2.0/go.mod h1:s4VGaxYMbw4+4+tsoQTqh7wfxg97AEdo4GYBt6BadWg= +github.com/libp2p/go-libp2p-host v0.0.1 h1:dnqusU+DheGcdxrE718kG4XgHNuL2n9eEv8Rg5zy8hQ= github.com/libp2p/go-libp2p-host v0.0.1/go.mod h1:qWd+H1yuU0m5CwzAkvbSjqKairayEHdR5MMl7Cwa7Go= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.1 h1:Q9EkNSLAOF+u90L88qmE9z/fTdjLh8OsJwGw74mkwk4= github.com/libp2p/go-libp2p-interface-connmgr v0.0.1/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= github.com/libp2p/go-libp2p-interface-pnet v0.0.1/go.mod h1:el9jHpQAXK5dnTpKA4yfCNBZXvrzdOU75zz+C6ryp3k= github.com/libp2p/go-libp2p-kad-dht v0.1.1 h1:IH6NQuoUv5w5e1O8Jc3KyVDtr0rNd0G9aaADpLI1xVo= @@ -342,6 +346,7 @@ github.com/libp2p/go-libp2p-mplex v0.2.1 h1:E1xaJBQnbSiTHGI1gaBKmKhu1TUKkErKJnE8 github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= github.com/libp2p/go-libp2p-nat v0.0.4 h1:+KXK324yaY701On8a0aGjTnw8467kW3ExKcqW2wwmyw= github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= +github.com/libp2p/go-libp2p-net v0.0.1 h1:xJ4Vh4yKF/XKb8fd1Ev0ebAGzVjMxXzrxG2kjtU+F5Q= github.com/libp2p/go-libp2p-net v0.0.1/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8EgNU9DrCcR8c= github.com/libp2p/go-libp2p-netutil v0.1.0 h1:zscYDNVEcGxyUpMd0JReUZTrpMfia8PmLKcKF72EAMQ= github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= @@ -354,6 +359,7 @@ github.com/libp2p/go-libp2p-peerstore v0.1.3 h1:wMgajt1uM2tMiqf4M+4qWKVyyFc8SfA+ github.com/libp2p/go-libp2p-peerstore v0.1.3/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI= github.com/libp2p/go-libp2p-pnet v0.1.0 h1:kRUES28dktfnHNIRW4Ro78F7rKBHBiw5MJpl0ikrLIA= github.com/libp2p/go-libp2p-pnet v0.1.0/go.mod h1:ZkyZw3d0ZFOex71halXRihWf9WH/j3OevcJdTmD0lyE= +github.com/libp2p/go-libp2p-protocol v0.0.1 h1:+zkEmZ2yFDi5adpVE3t9dqh/N9TbpFWywowzeEzBbLM= github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= github.com/libp2p/go-libp2p-pubsub v0.2.3 h1:qJRnRnM7Z4xnHb4i6EBb3DKQXRPgtFWlKP4AmfJudLQ= github.com/libp2p/go-libp2p-pubsub v0.2.3/go.mod h1:Jscj3fk23R5mCrOwb625xjVs5ZEyTZcx/OlTwMDqU+g= @@ -407,6 +413,7 @@ github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FW github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-stream-muxer v0.0.1 h1:Ce6e2Pyu+b5MC1k3eeFtAax0pW4gc6MosYSLV05UeLw= github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROmAFwUHpeRidG+q7LTQOg= github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= @@ -530,6 +537,7 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -537,6 +545,7 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqn github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/shirou/gopsutil v2.18.12+incompatible h1:1eaJvGomDnH74/5cF4CTmTbLHAriGFsTZppLXDX93OM= github.com/shirou/gopsutil v2.18.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= @@ -723,6 +732,7 @@ google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRn google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= diff --git a/node/builder.go b/node/builder.go index ba7a7daa0..0dfb2ff35 100644 --- a/node/builder.go +++ b/node/builder.go @@ -40,6 +40,7 @@ import ( "github.com/filecoin-project/lotus/node/modules/helpers" "github.com/filecoin-project/lotus/node/modules/lp2p" "github.com/filecoin-project/lotus/node/modules/testing" + "github.com/filecoin-project/lotus/node/peers" "github.com/filecoin-project/lotus/node/repo" "github.com/filecoin-project/lotus/paych" "github.com/filecoin-project/lotus/peermgr" @@ -234,6 +235,7 @@ func Online() Option { Override(new(*paych.Store), paych.NewStore), Override(new(*paych.Manager), paych.NewManager), Override(new(*market.FundMgr), market.NewFundMgr), + Override(new(*peers.PeerTagger), lp2p.TagMiners), ), // Storage miner diff --git a/node/impl/common.go b/node/impl/common.go index 990a46a8a..941a05a23 100644 --- a/node/impl/common.go +++ b/node/impl/common.go @@ -2,6 +2,7 @@ package impl import ( "context" + "github.com/gbrlsnchs/jwt/v3" "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/network" @@ -13,13 +14,15 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/node/modules/dtypes" + "github.com/filecoin-project/lotus/node/peers" ) type CommonAPI struct { fx.In - APISecret *dtypes.APIAlg - Host host.Host + APISecret *dtypes.APIAlg + Host host.Host + PeerTagger *peers.PeerTagger // TODO: this needs a better home } type jwtPayload struct { diff --git a/node/impl/full/state.go b/node/impl/full/state.go index a5d680d4d..db39df009 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -223,18 +223,7 @@ func (a *StateAPI) StateGetReceipt(ctx context.Context, msg cid.Cid, ts *types.T } func (a *StateAPI) StateListMiners(ctx context.Context, ts *types.TipSet) ([]address.Address, error) { - var state actors.StoragePowerState - if _, err := a.StateManager.LoadActorState(ctx, actors.StoragePowerAddress, &state, ts); err != nil { - return nil, err - } - - cst := hamt.CSTFromBstore(a.StateManager.ChainStore().Blockstore()) - miners, err := actors.MinerSetList(ctx, cst, state.Miners) - if err != nil { - return nil, err - } - - return miners, nil + return stmgr.ListMinerActors(ctx, a.StateManager, ts) } func (a *StateAPI) StateListActors(ctx context.Context, ts *types.TipSet) ([]address.Address, error) { diff --git a/node/modules/lp2p/host.go b/node/modules/lp2p/host.go index 5abff7803..5ae7ef8f3 100644 --- a/node/modules/lp2p/host.go +++ b/node/modules/lp2p/host.go @@ -16,6 +16,7 @@ import ( mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" "go.uber.org/fx" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/modules/helpers" ) @@ -41,7 +42,7 @@ func Host(mctx helpers.MetricsCtx, lc fx.Lifecycle, params P2PHostIn) (RawHost, return nil, fmt.Errorf("missing private key for node ID: %s", params.ID.Pretty()) } - opts := []libp2p.Option{libp2p.Identity(pkey), libp2p.Peerstore(params.Peerstore), libp2p.NoListenAddrs} + opts := []libp2p.Option{libp2p.Identity(pkey), libp2p.Peerstore(params.Peerstore), libp2p.NoListenAddrs, libp2p.UserAgent("lotus-" + build.Version)} for _, o := range params.Opts { opts = append(opts, o...) } diff --git a/node/modules/lp2p/libp2p.go b/node/modules/lp2p/libp2p.go index ab616ce59..c02906af6 100644 --- a/node/modules/lp2p/libp2p.go +++ b/node/modules/lp2p/libp2p.go @@ -1,16 +1,20 @@ package lp2p import ( + "context" "crypto/rand" "time" + "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/node/peers" "golang.org/x/xerrors" logging "github.com/ipfs/go-log" "github.com/libp2p/go-libp2p" connmgr "github.com/libp2p/go-libp2p-connmgr" "github.com/libp2p/go-libp2p-core/crypto" + host "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peerstore" "go.uber.org/fx" @@ -95,3 +99,18 @@ func simpleOpt(opt libp2p.Option) func() (opts Libp2pOpts, err error) { return } } + +func TagMiners(lc fx.Lifecycle, h host.Host, stmgr *stmgr.StateManager) *peers.PeerTagger { + pt := peers.NewPeerTagger(h, stmgr) + lc.Append(fx.Hook{ + OnStart: func(ctx context.Context) error { + pt.Run() + return nil + }, + OnStop: func(ctx context.Context) error { + return pt.Close() + }, + }) + + return pt +} diff --git a/node/peers/miners.go b/node/peers/miners.go new file mode 100644 index 000000000..630dd109f --- /dev/null +++ b/node/peers/miners.go @@ -0,0 +1,84 @@ +package peers + +import ( + "context" + "time" + + "github.com/filecoin-project/lotus/chain/stmgr" + host "github.com/libp2p/go-libp2p-core/host" + "github.com/prometheus/common/log" + "go.opencensus.io/trace" +) + +// PeerTagger uses information from the chain to tag peer connections to +// prevent them from being closed by the connection manager +type PeerTagger struct { + h host.Host + st *stmgr.StateManager + + closing chan struct{} +} + +func NewPeerTagger(h host.Host, st *stmgr.StateManager) *PeerTagger { + log.Error("NEW PEER TAGGER") + return &PeerTagger{ + h: h, + st: st, + closing: make(chan struct{}), + } +} + +func (pt *PeerTagger) Run() { + go pt.loop() +} + +func (pt *PeerTagger) loop() { + tick := time.NewTimer(time.Second) + for { + select { + case <-tick.C: + if err := pt.tagMiners(context.TODO()); err != nil { + log.Warn("failed to run tag miners: ", err) + } + + tick.Reset(time.Minute * 2) + + case <-pt.closing: + log.Warn("peer tagger shutting down") + return + } + } +} + +func (pt *PeerTagger) tagMiners(ctx context.Context) error { + _, span := trace.StartSpan(ctx, "tagMiners") + defer span.End() + + ts := pt.st.ChainStore().GetHeaviestTipSet() + mactors, err := stmgr.ListMinerActors(context.TODO(), pt.st, ts) + if err != nil { + return err + } + + for _, m := range mactors { + mpow, _, err := stmgr.GetPower(context.TODO(), pt.st, ts, m) + if err != nil { + log.Warn("failed to get miners power: ", err) + continue + } + if !mpow.IsZero() { + pid, err := stmgr.GetMinerPeerID(context.TODO(), pt.st, ts, m) + if err != nil { + log.Warn("failed to get peer ID for miner: ", err) + continue + } + pt.h.ConnManager().TagPeer(pid, "miner", 10) + } + } + return nil +} + +func (pt *PeerTagger) Close() error { + close(pt.closing) + return nil +}