diff --git a/Makefile b/Makefile index f1210caecd..77656c0e26 100644 --- a/Makefile +++ b/Makefile @@ -121,6 +121,10 @@ build: $(BUILD_DEPS) rm -f venus $(GO) build -o ./venus $(GOFLAGS) . +debug: $(BUILD_DEPS) + rm -f venus + $(GO) build -o ./venus -gcflags=all="-N -l" $(GOFLAGS) . + .PHONY: docker TAG:=test diff --git a/app/node/node.go b/app/node/node.go index f6f9264e7f..6134eef64a 100644 --- a/app/node/node.go +++ b/app/node/node.go @@ -31,8 +31,9 @@ import ( _ "github.com/filecoin-project/venus/pkg/crypto/bls" // enable bls signatures _ "github.com/filecoin-project/venus/pkg/crypto/delegated" // enable delegated signatures _ "github.com/filecoin-project/venus/pkg/crypto/secp" // enable secp signatures - "github.com/filecoin-project/venus/pkg/metrics" + metricsPKG "github.com/filecoin-project/venus/pkg/metrics" "github.com/filecoin-project/venus/pkg/repo" + "github.com/ipfs-force-community/metrics" "github.com/ipfs-force-community/sophon-auth/jwtclient" cmds "github.com/ipfs/go-ipfs-cmds" cmdhttp "github.com/ipfs/go-ipfs-cmds/http" @@ -46,6 +47,10 @@ import ( var log = logging.Logger("node") // nolint: deadcode +var ( + apiStatusGauge = metrics.NewInt64("api/status", "Status of the API server. 1 is up, 0 is down.", "") +) + // ConfigOpt mutates a node config post initialization type ConfigOpt func(*config.Config) @@ -157,11 +162,11 @@ func (node *Node) OfflineMode() bool { // Start boots up the node. func (node *Node) Start(ctx context.Context) error { var err error - if err = metrics.RegisterPrometheusEndpoint(node.repo.Config().Observability.Metrics); err != nil { + if err = metricsPKG.RegisterPrometheusEndpoint(node.repo.Config().Observability.Metrics); err != nil { return errors.Wrap(err, "failed to setup metrics") } - if node.jaeger, err = metrics.SetupJaegerTracing(node.network.Host.ID().Pretty(), + if node.jaeger, err = metricsPKG.SetupJaegerTracing(node.network.Host.ID().Pretty(), node.repo.Config().Observability.Tracing); err != nil { return errors.Wrap(err, "failed to setup tracing") } @@ -239,7 +244,7 @@ func (node *Node) Stop(ctx context.Context) { } if node.jaeger != nil { - if err := metrics.ShutdownJaeger(ctx, node.jaeger); err != nil { + if err := metricsPKG.ShutdownJaeger(ctx, node.jaeger); err != nil { log.Warnf("error shutdown jaeger-tracing: %w", err) } } @@ -297,8 +302,10 @@ func (node *Node) RunRPCAndWait(ctx context.Context, rootCmdDaemon *cmds.Command } go func() { + apiStatusGauge.Set(ctx, 1) err := apiServ.Serve(netListener) // nolint if err != nil && err != http.ErrServerClosed { + apiStatusGauge.Set(ctx, 0) return } }() @@ -319,6 +326,7 @@ func (node *Node) RunRPCAndWait(ctx context.Context, rootCmdDaemon *cmds.Command if err := apiServ.Shutdown(ctx); err != nil { log.Warnf("failed to shutdown server: %v", err) } + apiStatusGauge.Set(ctx, 0) node.Stop(ctx) memguard.Purge() log.Infof("venus shutdown gracefully ...") diff --git a/app/submodule/chain/chaininfo_api.go b/app/submodule/chain/chaininfo_api.go index 6615d885ec..0a3c5f0483 100644 --- a/app/submodule/chain/chaininfo_api.go +++ b/app/submodule/chain/chaininfo_api.go @@ -18,10 +18,12 @@ import ( acrypto "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/network" miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" + "github.com/ipfs-force-community/metrics" "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" logging "github.com/ipfs/go-log/v2" cbg "github.com/whyrusleeping/cbor-gen" + "go.opencensus.io/tag" "github.com/filecoin-project/venus/pkg/chain" "github.com/filecoin-project/venus/pkg/constants" @@ -41,6 +43,11 @@ type chainInfoAPI struct { //nolint var log = logging.Logger("chain") +var ( + tagKeyRandomnessRequestType = tag.MustNewKey("randomness_request_type") + randomnessRequestStatus = metrics.NewInt64WithCounter("api/randomness_status", "Status of randomness request. 0 = fail, 1 = success", "", tagKeyRandomnessRequestType) +) + // NewChainInfoAPI new chain info api func NewChainInfoAPI(chain *ChainSubmodule) v1api.IChainInfo { return &chainInfoAPI{chain: chain} @@ -379,7 +386,7 @@ func (cia *chainInfoAPI) getNetworkName(ctx context.Context) (string, error) { } // StateGetRandomnessFromTickets is used to sample the chain for randomness. -func (cia *chainInfoAPI) StateGetRandomnessFromTickets(ctx context.Context, personalization acrypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte, tsk types.TipSetKey) (abi.Randomness, error) { +func (cia *chainInfoAPI) StateGetRandomnessFromTickets(ctx context.Context, personalization acrypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte, tsk types.TipSetKey) (rand abi.Randomness, err error) { ts, err := cia.ChainGetTipSet(ctx, tsk) if err != nil { return nil, fmt.Errorf("loading tipset %s: %w", tsk, err) @@ -391,11 +398,18 @@ func (cia *chainInfoAPI) StateGetRandomnessFromTickets(ctx context.Context, pers return nil, fmt.Errorf("getting chain randomness: %w", err) } - return chain.DrawRandomnessFromDigest(digest, personalization, randEpoch, entropy) + ctx, _ = tag.New(ctx, tag.Upsert(tagKeyRandomnessRequestType, utils.Name(personalization))) + ret, err := chain.DrawRandomnessFromDigest(digest, personalization, randEpoch, entropy) + if err != nil { + randomnessRequestStatus.Set(ctx, 0) + return nil, err + } + randomnessRequestStatus.Set(ctx, 1) + return ret, nil } // StateGetRandomnessFromBeacon is used to sample the beacon for randomness. -func (cia *chainInfoAPI) StateGetRandomnessFromBeacon(ctx context.Context, personalization acrypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte, tsk types.TipSetKey) (abi.Randomness, error) { +func (cia *chainInfoAPI) StateGetRandomnessFromBeacon(ctx context.Context, personalization acrypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte, tsk types.TipSetKey) (rand abi.Randomness, err error) { ts, err := cia.ChainGetTipSet(ctx, tsk) if err != nil { return nil, fmt.Errorf("loading tipset %s: %w", tsk, err) @@ -406,7 +420,14 @@ func (cia *chainInfoAPI) StateGetRandomnessFromBeacon(ctx context.Context, perso return nil, fmt.Errorf("getting beacon randomness: %w", err) } - return chain.DrawRandomnessFromDigest(digest, personalization, randEpoch, entropy) + ctx, _ = tag.New(ctx, tag.Upsert(tagKeyRandomnessRequestType, utils.Name(personalization))) + ret, err := chain.DrawRandomnessFromDigest(digest, personalization, randEpoch, entropy) + if err != nil { + randomnessRequestStatus.Set(ctx, 0) + return nil, err + } + randomnessRequestStatus.Set(ctx, 1) + return ret, nil } func (cia *chainInfoAPI) StateGetRandomnessDigestFromTickets(ctx context.Context, randEpoch abi.ChainEpoch, tsk types.TipSetKey) (abi.Randomness, error) { diff --git a/go.mod b/go.mod index c25e3d853d..bb3809b4b0 100644 --- a/go.mod +++ b/go.mod @@ -56,7 +56,7 @@ require ( github.com/hashicorp/golang-lru/arc/v2 v2.0.7 github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c - github.com/ipfs-force-community/metrics v1.0.1-0.20231011024528-8c881d456601 + github.com/ipfs-force-community/metrics v1.0.1-0.20231207081445-30178e706d09 github.com/ipfs-force-community/sophon-auth v1.14.0 github.com/ipfs/boxo v0.10.1 github.com/ipfs/go-cid v0.4.1 @@ -95,7 +95,6 @@ require ( github.com/stretchr/testify v1.8.4 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/whyrusleeping/cbor-gen v0.0.0-20230923211252-36a87e1ba72f - github.com/whyrusleeping/go-logging v0.0.1 github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1 github.com/zyedidia/generic v1.2.1 go.opencensus.io v0.24.0 @@ -124,6 +123,7 @@ require ( github.com/ipfs/go-merkledag v0.11.0 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect + github.com/whyrusleeping/go-logging v0.0.1 // indirect ) require ( diff --git a/go.sum b/go.sum index dc2f31650c..03c31168c0 100644 --- a/go.sum +++ b/go.sum @@ -592,8 +592,8 @@ github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7 github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= github.com/ipfs-force-community/go-jsonrpc v0.1.9 h1:5QavBltfvV6fz/+EbYsCkVxJ1MSJncZm6YuPs1SLdZU= github.com/ipfs-force-community/go-jsonrpc v0.1.9/go.mod h1:jBSvPTl8V1N7gSTuCR4bis8wnQnIjHbRPpROol6iQKM= -github.com/ipfs-force-community/metrics v1.0.1-0.20231011024528-8c881d456601 h1:zxKQ30KAD6KfvSFAx9tuqQXLDsEHyF+eVaUBXXYC2bU= -github.com/ipfs-force-community/metrics v1.0.1-0.20231011024528-8c881d456601/go.mod h1:wM6EmkEcnJgWOFcVytgvK0u15awEmt8He0f2kAdsFDA= +github.com/ipfs-force-community/metrics v1.0.1-0.20231207081445-30178e706d09 h1:qEI6ItxKtgOupMMuGJwqK5zEzztKKPUP1QKq9g+X5bM= +github.com/ipfs-force-community/metrics v1.0.1-0.20231207081445-30178e706d09/go.mod h1:wM6EmkEcnJgWOFcVytgvK0u15awEmt8He0f2kAdsFDA= github.com/ipfs-force-community/sophon-auth v1.14.0 h1:ctBJ6UHkcytEzfVPgiiHo0cW4FGQrE7r1H3Um0FcHbo= github.com/ipfs-force-community/sophon-auth v1.14.0/go.mod h1:d6J6u3zyIwcEajRho5BhVBcoIChEf0K76wP4yJEfEhc= github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= diff --git a/pkg/chainsync/syncer/syncer.go b/pkg/chainsync/syncer/syncer.go index 3a08e5a9f2..d225b755c3 100644 --- a/pkg/chainsync/syncer/syncer.go +++ b/pkg/chainsync/syncer/syncer.go @@ -9,11 +9,14 @@ import ( "github.com/filecoin-project/venus/pkg/consensus" "github.com/filecoin-project/venus/pkg/crypto" + "github.com/filecoin-project/venus/pkg/repo" "github.com/filecoin-project/venus/pkg/statemanger" "github.com/hashicorp/go-multierror" + "github.com/ipfs-force-community/metrics" "golang.org/x/sync/errgroup" + actorsTypes "github.com/filecoin-project/go-state-types/actors" syncTypes "github.com/filecoin-project/venus/pkg/chainsync/types" cbor "github.com/ipfs/go-ipld-cbor" @@ -22,7 +25,6 @@ import ( "github.com/filecoin-project/venus/pkg/clock" "github.com/filecoin-project/venus/pkg/constants" "github.com/filecoin-project/venus/pkg/fork" - "github.com/filecoin-project/venus/pkg/metrics" "github.com/filecoin-project/venus/pkg/metrics/tracing" "github.com/filecoin-project/venus/pkg/net/exchange" "github.com/filecoin-project/venus/venus-shared/actors/policy" @@ -59,15 +61,19 @@ var ( // ErrUnexpectedStoreState indicates that the syncer's chain bsstore is violating expected invariants. ErrUnexpectedStoreState = errors.New("the chain bsstore is in an unexpected state") - logSyncer = logging.Logger("chainsync.syncer") - syncOneTimer *metrics.Float64Timer - reorgCnt *metrics.Int64Counter // nolint + logSyncer = logging.Logger("chainsync.syncer") ) -func init() { - syncOneTimer = metrics.NewTimerMs("syncer/sync_one", "Duration of single tipset validation in milliseconds") - reorgCnt = metrics.NewInt64Counter("chain/reorg_count", "The number of reorgs that have occurred.") -} +// metrics handlers +var ( + // epoch should not use as a label, because it has a lot of values + syncOneTimer = metrics.NewTimerMs("sync/sync_one", "Duration of single tipset validation in milliseconds") + syncStatus = metrics.NewInt64("sync/status", "The current status of the syncer. 0 = sync delay, 1 = sync done", "") + reorgCnt = metrics.NewCounter("chain/reorg_count", "The number of reorgs that have occurred.") // nolint + epochGauge = metrics.NewInt64("chain/epoch", "The current epoch.", "") + netVersionGuage = metrics.NewInt64("chain/net_version", "The current network version.", "") + actorVersionGuage = metrics.NewInt64("chain/actor_version", "The current actor version.", "") +) // StateProcessor does semantic validation on fullblocks. type StateProcessor interface { @@ -195,8 +201,8 @@ func (syncer *Syncer) syncOne(ctx context.Context, parent, next *types.TipSet) e return nil } - stopwatch := syncOneTimer.Start(ctx) - defer stopwatch.Stop(ctx) + stopwatch := syncOneTimer.Start() + defer stopwatch(ctx) var err error @@ -235,6 +241,22 @@ func (syncer *Syncer) syncOne(ctx context.Context, parent, next *types.TipSet) e syncer.chainStore.PersistTipSetKey(ctx, next.Key()) + // chain related metrics + height := next.Height() + epochGauge.Set(ctx, int64(height)) + + timeStamp := next.MinTimestamp() + if timeStamp+repo.Config.NetworkParams.BlockDelay*uint64(time.Second) >= uint64(syncer.clock.Now().Unix()) { + // update to latest + syncStatus.Set(ctx, 1) + } else { + syncStatus.Set(ctx, 0) + } + netVersion := syncer.fork.GetNetworkVersion(ctx, height) + netVersionGuage.Set(ctx, int64(netVersion)) + actorVersion, _ := actorsTypes.VersionForNetwork(netVersion) + actorVersionGuage.Set(ctx, int64(actorVersion)) + return nil } diff --git a/pkg/metrics/counter.go b/pkg/metrics/counter.go deleted file mode 100644 index 91533b186e..0000000000 --- a/pkg/metrics/counter.go +++ /dev/null @@ -1,42 +0,0 @@ -package metrics - -import ( - "context" - - "go.opencensus.io/stats" - "go.opencensus.io/stats/view" -) - -// Int64Counter wraps an opencensus int64 measure that is uses as a counter. -type Int64Counter struct { - measureCt *stats.Int64Measure - view *view.View -} - -// NewInt64Counter creates a new Int64Counter with demensionless units. -func NewInt64Counter(name, desc string) *Int64Counter { - log.Infof("registering int64 counter: %s - %s", name, desc) - iMeasure := stats.Int64(name, desc, stats.UnitDimensionless) - iView := &view.View{ - Name: name, - Measure: iMeasure, - Description: desc, - Aggregation: view.Count(), - } - if err := view.Register(iView); err != nil { - // a panic here indicates a developer error when creating a view. - // Since this method is called in init() methods, this panic when hit - // will cause running the program to fail immediately. - panic(err) - } - - return &Int64Counter{ - measureCt: iMeasure, - view: iView, - } -} - -// Inc increments the counter by value `v`. -func (c *Int64Counter) Inc(ctx context.Context, v int64) { - stats.Record(ctx, c.measureCt.M(v)) -} diff --git a/pkg/metrics/gauge.go b/pkg/metrics/gauge.go deleted file mode 100644 index ffed4dbfd1..0000000000 --- a/pkg/metrics/gauge.go +++ /dev/null @@ -1,45 +0,0 @@ -package metrics - -import ( - "context" - - "go.opencensus.io/stats" - "go.opencensus.io/stats/view" - "go.opencensus.io/tag" -) - -// Int64Gauge wraps an opencensus int64 measure that is uses as a gauge. -type Int64Gauge struct { - measureCt *stats.Int64Measure - view *view.View -} - -// NewInt64Gauge creates a new Int64Gauge with demensionless units. -func NewInt64Gauge(name, desc string, keys ...tag.Key) *Int64Gauge { - log.Infof("registering int64 gauge: %s - %s", name, desc) - iMeasure := stats.Int64(name, desc, stats.UnitDimensionless) - - iView := &view.View{ - Name: name, - Measure: iMeasure, - Description: desc, - Aggregation: view.LastValue(), - TagKeys: keys, - } - if err := view.Register(iView); err != nil { - // a panic here indicates a developer error when creating a view. - // Since this method is called in init() methods, this panic when hit - // will cause running the program to fail immediately. - panic(err) - } - - return &Int64Gauge{ - measureCt: iMeasure, - view: iView, - } -} - -// Set sets the value of the gauge to value `v`. -func (c *Int64Gauge) Set(ctx context.Context, v int64) { - stats.Record(ctx, c.measureCt.M(v)) -} diff --git a/pkg/metrics/log_json_formatter.go b/pkg/metrics/log_json_formatter.go deleted file mode 100644 index fd2b0e4054..0000000000 --- a/pkg/metrics/log_json_formatter.go +++ /dev/null @@ -1,45 +0,0 @@ -package metrics - -import ( - "encoding/json" - "fmt" - "io" - "path/filepath" - "runtime" - "time" - - oldlogging "github.com/whyrusleeping/go-logging" -) - -// JSONFormatter implements go-logging Formatter for JSON encoded logs -type JSONFormatter struct{} - -type logRecord struct { - Timestamp time.Time `json:"timestamp"` - Level string `json:"level"` - System string `json:"system"` - Message string `json:"message"` - File string `json:"file"` -} - -// Format implements go-logging Formatter -func (jf *JSONFormatter) Format(calldepth int, r *oldlogging.Record, w io.Writer) error { - var fileLine string - if calldepth > 0 { - _, file, line, ok := runtime.Caller(calldepth + 1) - if !ok { - fileLine = "???:0" - } else { - fileLine = fmt.Sprintf("%s:%d", filepath.Base(file), line) - } - } - lr := &logRecord{ - Timestamp: r.Time, - Level: r.Level.String(), - System: r.Module, - Message: r.Message(), - File: fileLine, - } - encoder := json.NewEncoder(w) - return encoder.Encode(lr) -} diff --git a/pkg/metrics/timer.go b/pkg/metrics/timer.go deleted file mode 100644 index 095392c203..0000000000 --- a/pkg/metrics/timer.go +++ /dev/null @@ -1,73 +0,0 @@ -package metrics - -import ( - "context" - "time" - - "go.opencensus.io/stats" - "go.opencensus.io/stats/view" - "go.opencensus.io/tag" -) - -// NewTimerMs creates a Float64Timer with units of milliseconds and a default set of aggregation -// bounds for latencies up to a few seconds. -func NewTimerMs(name, desc string, tagKeys ...tag.Key) *Float64Timer { - // [>=0ms, >=25ms, >=50ms, >=75ms, >=100ms, >=200ms, >=400ms, >=600ms, >=800ms, >=1s, >=2s, >=4s, >=8s] - defaultBounds := []float64{25, 50, 75, 100, 200, 400, 600, 800, 1000, 2000, 4000, 8000} - return NewTimerWithBuckets(name, desc, stats.UnitMilliseconds, defaultBounds, tagKeys...) -} - -// NewTimerWithBuckets creates a Float64Timer wrapping an opencensus float64 measurement. -func NewTimerWithBuckets(name, desc, unit string, bounds []float64, tagKeys ...tag.Key) *Float64Timer { - log.Infof("registering timer: %s - %s", name, desc) - fMeasure := stats.Float64(name, desc, unit) - fView := &view.View{ - Name: name, - Measure: fMeasure, - Description: desc, - TagKeys: tagKeys, - Aggregation: view.Distribution(bounds...), - } - if err := view.Register(fView); err != nil { - // a panic here indicates a developer error when creating a view. - // Since this method is called in init() methods, this panic when hit - // will cause running the program to fail immediately. - panic(err) - } - - return &Float64Timer{ - measureMs: fMeasure, - view: fView, - } -} - -// Float64Timer contains a opencensus measurement and view -type Float64Timer struct { - measureMs *stats.Float64Measure - view *view.View -} - -// Start starts a timer and returns a Stopwatch. -func (t *Float64Timer) Start(ctx context.Context) *Stopwatch { - return &Stopwatch{ - ctx: ctx, - start: time.Now(), - recorder: t.measureMs.M, - } -} - -// Stopwatch contains a start time and a recorder, when stopped it record the -// duration since start time began via its recorder function. -type Stopwatch struct { - ctx context.Context - start time.Time - recorder func(v float64) stats.Measurement -} - -// Stop rounds the time since Start was called to milliseconds and records the value -// in the corresponding opencensus view. -func (sw *Stopwatch) Stop(ctx context.Context) time.Duration { - duration := time.Since(sw.start).Round(time.Millisecond) - stats.Record(ctx, sw.recorder(float64(duration)/1e6)) - return duration -} diff --git a/pkg/metrics/timer_test.go b/pkg/metrics/timer_test.go deleted file mode 100644 index a52c0698d0..0000000000 --- a/pkg/metrics/timer_test.go +++ /dev/null @@ -1,68 +0,0 @@ -package metrics - -import ( - "context" - "testing" - - tf "github.com/filecoin-project/venus/pkg/testhelpers/testflags" - "github.com/stretchr/testify/assert" - "go.opencensus.io/stats/view" -) - -func TestTimerSimple(t *testing.T) { - tf.BadUnitTestWithSideEffects(t) - - ctx := context.Background() - - testTimer := NewTimerMs("testName", "testDesc") - // some view state is kept around after tests exit, doing this to clean that up. - // e.g. view will remain registered after a test exits. - defer view.Unregister(testTimer.view) - - assert.Equal(t, "testName", testTimer.view.Name) - assert.Equal(t, "testDesc", testTimer.view.Description) - - sw := testTimer.Start(ctx) - sw.Stop(ctx) - assert.NotEqual(t, 0, sw.start) -} - -func TestDuplicateTimersPanics(t *testing.T) { - tf.BadUnitTestWithSideEffects(t) - - ctx := context.Background() - - defer func() { - if r := recover(); r == nil { - t.Fatal("code should panic when 2 views with same name are registered") - } - // we pass - }() - - NewTimerMs("testName", "testDesc") - testTimer := NewTimerMs("testName", "testDesc") - assert.Equal(t, "testName", testTimer.view.Name) - assert.Equal(t, "testDesc", testTimer.view.Description) - - sw := testTimer.Start(ctx) - sw.Stop(ctx) - assert.NotEqual(t, 0, sw.start) -} - -func TestMultipleTimers(t *testing.T) { - tf.BadUnitTestWithSideEffects(t) - - ctx1 := context.Background() - ctx2 := context.Background() - - tt1 := NewTimerMs("tt1", "ttd1") - tt2 := NewTimerMs("tt2", "ttd2") - - sw1 := tt1.Start(ctx1) - sw2 := tt2.Start(ctx2) - - sw1.Stop(ctx1) - assert.NotEqual(t, 0, sw1.start) - sw2.Stop(ctx2) - assert.NotEqual(t, 0, sw2.start) -} diff --git a/pkg/net/blocksub/validator.go b/pkg/net/blocksub/validator.go index be8edf5171..a84ec1f34c 100644 --- a/pkg/net/blocksub/validator.go +++ b/pkg/net/blocksub/validator.go @@ -8,13 +8,13 @@ import ( pubsub "github.com/libp2p/go-libp2p-pubsub" "github.com/libp2p/go-libp2p/core/peer" - "github.com/filecoin-project/venus/pkg/metrics" "github.com/filecoin-project/venus/venus-shared/types" + "github.com/ipfs-force-community/metrics" ) var ( blockTopicLogger = log.Logger("net/block_validator") - mDecodeBlkFail = metrics.NewInt64Counter("net/pubsub_block_decode_failure", "Number of blocks that fail to decode seen on block pubsub channel") + mDecodeBlkFail = metrics.NewCounter("net/pubsub_block_decode_failure", "Number of blocks that fail to decode seen on block pubsub channel") ) // BlockTopicValidator may be registered on go-libp2p-pubsub to validate blocksub messages. @@ -36,7 +36,7 @@ func NewBlockTopicValidator(bv BlockHeaderValidator, opts ...pubsub.ValidatorOpt err := bm.UnmarshalCBOR(bytes.NewReader(msg.GetData())) if err != nil { blockTopicLogger.Warnf("failed to decode blocksub payload from peer %s: %s", p.String(), err.Error()) - mDecodeBlkFail.Inc(ctx, 1) + mDecodeBlkFail.Tick(ctx) return pubsub.ValidationIgnore } diff --git a/pkg/net/helloprotocol/hello_protocol.go b/pkg/net/helloprotocol/hello_protocol.go index 3281f413ee..5862840d8e 100644 --- a/pkg/net/helloprotocol/hello_protocol.go +++ b/pkg/net/helloprotocol/hello_protocol.go @@ -20,7 +20,7 @@ import ( net "github.com/libp2p/go-libp2p/core/network" ma "github.com/multiformats/go-multiaddr" - "github.com/filecoin-project/venus/pkg/metrics" + "github.com/ipfs-force-community/metrics" ) var log = logging.Logger("/fil/hello") @@ -29,8 +29,8 @@ var log = logging.Logger("/fil/hello") const helloProtocolID = "/fil/hello/1.0.0" var ( - genesisErrCt = metrics.NewInt64Counter("hello_genesis_error", "Number of errors encountered in hello protocol due to incorrect genesis block") - helloMsgErrCt = metrics.NewInt64Counter("hello_message_error", "Number of errors encountered in hello protocol due to malformed message") + genesisErrCt = metrics.NewCounter("hello_genesis_error", "Number of errors encountered in hello protocol due to incorrect genesis block") + helloMsgErrCt = metrics.NewCounter("hello_message_error", "Number of errors encountered in hello protocol due to malformed message") ) // HelloMessage is the data structure of a single message in the hello protocol. @@ -114,7 +114,7 @@ func (h *HelloProtocolHandler) handleNewStream(s net.Stream) { hello, err := h.receiveHello(ctx, s) if err != nil { - helloMsgErrCt.Inc(ctx, 1) + helloMsgErrCt.Tick(ctx) log.Debugf("failed to receive hello message:%s", err) // can't process a hello received in error, but leave this connection // open because we connections are innocent until proven guilty @@ -127,7 +127,7 @@ func (h *HelloProtocolHandler) handleNewStream(s net.Stream) { from := s.Conn().RemotePeer() if !hello.GenesisHash.Equals(h.genesis) { log.Debugf("peer genesis cid: %s does not match ours: %s, disconnecting from peer: %s", &hello.GenesisHash, h.genesis, from) - genesisErrCt.Inc(context.Background(), 1) + genesisErrCt.Tick(context.Background()) _ = s.Conn().Close() return } diff --git a/pkg/net/peermgr/peermgr.go b/pkg/net/peermgr/peermgr.go index e770228242..b280b8e234 100644 --- a/pkg/net/peermgr/peermgr.go +++ b/pkg/net/peermgr/peermgr.go @@ -6,6 +6,7 @@ import ( "sync" "time" + "github.com/ipfs-force-community/metrics" dht "github.com/libp2p/go-libp2p-kad-dht" "github.com/libp2p/go-libp2p/core/event" host "github.com/libp2p/go-libp2p/core/host" @@ -17,6 +18,10 @@ import ( var log = logging.Logger("peermgr") +var ( + peerCount = metrics.NewInt64("peer/count", "Number of peers", "") +) + const ( MaxFilPeers = 320 MinFilPeers = 128 @@ -96,8 +101,13 @@ func NewPeerMgr(h host.Host, dht *dht.IpfsDHT, period time.Duration, bootstrap [ pm.notifee = &net.NotifyBundle{ DisconnectedF: func(_ net.Network, c net.Conn) { + peerCount.Inc(context.Background(), -1) pm.Disconnect(c.RemotePeer()) }, + ConnectedF: func(_ net.Network, c net.Conn) { + // add dec peerCount + peerCount.Inc(context.Background(), 1) + }, } h.Network().Notify(pm.notifee) diff --git a/pkg/repo/fsrepo.go b/pkg/repo/fsrepo.go index 8cd49c86a0..c64e0c6322 100644 --- a/pkg/repo/fsrepo.go +++ b/pkg/repo/fsrepo.go @@ -50,8 +50,7 @@ type FSRepo struct { version uint // lk protects the config file - lk sync.RWMutex - cfg *config.Config + lk sync.RWMutex ds *blockstoreutil.BadgerBlockstore keystore fskeystore.Keystore @@ -242,7 +241,7 @@ func (r *FSRepo) Config() *config.Config { r.lk.RLock() defer r.lk.RUnlock() - return r.cfg + return Config } // ReplaceConfig replaces the current config with the newly passed in one. @@ -250,13 +249,13 @@ func (r *FSRepo) ReplaceConfig(cfg *config.Config) error { r.lk.Lock() defer r.lk.Unlock() - r.cfg = cfg + Config = cfg tmp := filepath.Join(r.path, tempConfigFilename) err := os.RemoveAll(tmp) if err != nil { return err } - err = r.cfg.WriteFile(tmp) + err = Config.WriteFile(tmp) if err != nil { return err } @@ -367,7 +366,7 @@ func LoadConfig(p string) (*config.Config, error) { } func (r *FSRepo) loadConfig() (err error) { - r.cfg, err = LoadConfig(r.path) + Config, err = LoadConfig(r.path) return } @@ -377,9 +376,9 @@ func (r *FSRepo) readVersion() (uint, error) { } func (r *FSRepo) openDatastore() error { - switch r.cfg.Datastore.Type { + switch Config.Datastore.Type { case "badgerds": - path := filepath.Join(r.path, r.cfg.Datastore.Path) + path := filepath.Join(r.path, Config.Datastore.Path) opts, err := blockstoreutil.BadgerBlockstoreOptions(path, false) if err != nil { return err @@ -391,7 +390,7 @@ func (r *FSRepo) openDatastore() error { } r.ds = ds default: - return fmt.Errorf("unknown datastore type in config: %s", r.cfg.Datastore.Type) + return fmt.Errorf("unknown datastore type in config: %s", Config.Datastore.Type) } return nil diff --git a/pkg/repo/mem.go b/pkg/repo/mem.go index ede31a705e..6125375d17 100644 --- a/pkg/repo/mem.go +++ b/pkg/repo/mem.go @@ -19,7 +19,6 @@ import ( type MemRepo struct { // lk guards the config lk sync.RWMutex - C *config.Config D blockstoreutil.Blockstore Ks fskeystore.Keystore W Datastore @@ -40,8 +39,9 @@ func NewInMemoryRepo() *MemRepo { // Reduce the time it takes to encrypt wallet password, default ScryptN is 1 << 21 // for test defConfig.Wallet.PassphraseConfig = config.TestPassphraseConfig() + Config = defConfig + return &MemRepo{ - C: defConfig, D: blockstoreutil.NewBlockstore(dss.MutexWrap(datastore.NewMapDatastore())), Ks: fskeystore.MutexWrap(fskeystore.NewMemKeystore()), W: dss.MutexWrap(datastore.NewMapDatastore()), @@ -58,7 +58,7 @@ func (mr *MemRepo) Config() *config.Config { mr.lk.RLock() defer mr.lk.RUnlock() - return mr.C + return Config } // ReplaceConfig replaces the current config with the newly passed in one. @@ -66,7 +66,7 @@ func (mr *MemRepo) ReplaceConfig(cfg *config.Config) error { mr.lk.Lock() defer mr.lk.Unlock() - mr.C = cfg + Config = cfg return nil } diff --git a/pkg/repo/repo.go b/pkg/repo/repo.go index 91c2af6612..0e690a44fd 100644 --- a/pkg/repo/repo.go +++ b/pkg/repo/repo.go @@ -7,6 +7,9 @@ import ( "github.com/ipfs/go-datastore" ) +// Config is the config object for the repo. +var Config = config.NewDefaultConfig() + // Datastore is the datastore interface provided by the repo type Datastore datastore.Batching diff --git a/venus-shared/utils/utils.go b/venus-shared/utils/utils.go index ac7b057887..56447e42e1 100644 --- a/venus-shared/utils/utils.go +++ b/venus-shared/utils/utils.go @@ -6,6 +6,8 @@ import ( "github.com/filecoin-project/venus/venus-shared/actors" "github.com/filecoin-project/venus/venus-shared/types" + + acrypto "github.com/filecoin-project/go-state-types/crypto" ) var NetworkNameWithNetworkType = map[types.NetworkName]types.NetworkType{ @@ -68,3 +70,35 @@ func LoadBuiltinActors(ctx context.Context, getter networkNameGetter) error { return nil } + +// Name returns the name of a variable whose type does not have a default implementation of the String() method. +func Name(a interface{}) string { + switch v := a.(type) { + case acrypto.DomainSeparationTag: + switch v { + case acrypto.DomainSeparationTag_TicketProduction: + return "TicketProduction" + case acrypto.DomainSeparationTag_ElectionProofProduction: + return "ElectionProofProduction" + case acrypto.DomainSeparationTag_WinningPoStChallengeSeed: + return "WinningPoStChallengeSeed" + case acrypto.DomainSeparationTag_WindowedPoStChallengeSeed: + return "WindowedPoStChallengeSeed" + case acrypto.DomainSeparationTag_SealRandomness: + return "SealRandomness" + case acrypto.DomainSeparationTag_InteractiveSealChallengeSeed: + return "InteractiveSealChallengeSeed" + case acrypto.DomainSeparationTag_WindowedPoStDeadlineAssignment: + return "WindowedPoStDeadlineAssignment" + case acrypto.DomainSeparationTag_MarketDealCronSeed: + return "MarketDealCronSeed" + case acrypto.DomainSeparationTag_PoStChainCommit: + return "PoStChainCommit" + default: + return "" + } + + default: + return "" + } +} diff --git a/venus-shared/utils/utils_test.go b/venus-shared/utils/utils_test.go index 31860fe4f0..6e11acfc4f 100644 --- a/venus-shared/utils/utils_test.go +++ b/venus-shared/utils/utils_test.go @@ -4,6 +4,7 @@ import ( "context" "testing" + acrypto "github.com/filecoin-project/go-state-types/crypto" tf "github.com/filecoin-project/venus/pkg/testhelpers/testflags" "github.com/filecoin-project/venus/venus-shared/actors" "github.com/filecoin-project/venus/venus-shared/api/chain/v1/mock" @@ -57,3 +58,27 @@ func TestLoadBuiltinActors(t *testing.T) { } } } + +func TestName(t *testing.T) { + testCases := []struct { + Name string + Input any + Output string + }{ + { + "empty", + []string{}, + "", + }, + { + "test1", + acrypto.DomainSeparationTag_TicketProduction, + "TicketProduction", + }} + + for _, testCase := range testCases { + t.Run(testCase.Name, func(t *testing.T) { + assert.Equal(t, testCase.Output, Name(testCase.Input)) + }) + } +}