From 6e5dcbfb70c0a58f3f94441e83e40d0e0ee4a93d Mon Sep 17 00:00:00 2001 From: cwarnerdev <138500512+cwarnerdev@users.noreply.github.com> Date: Fri, 4 Apr 2025 04:54:13 -1000 Subject: [PATCH 01/18] use fmt.Fprintf instead of f.WriteString(fmt.Sprintf()) --- app/shutdown/shutdown.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/shutdown/shutdown.go b/app/shutdown/shutdown.go index 07b34db2..f7662d89 100644 --- a/app/shutdown/shutdown.go +++ b/app/shutdown/shutdown.go @@ -122,7 +122,7 @@ func (gs *ShutdownHandler) writeSelfShutdownLogFile(msg string, critical bool) { message += " (CRITICAL)" } - if _, err := f.WriteString(fmt.Sprintf("%s: %s\n", time.Now().Format(time.RFC3339), message)); err != nil { + if _, err := fmt.Fprintf(f, "%s: %s\n", time.Now().Format(time.RFC3339), message); err != nil { gs.LogWarnf("self-shutdown log can't be written, error: %s", err.Error()) } } From 91fec0b88f0e44e10f0abd42e68fae3f70beac3d Mon Sep 17 00:00:00 2001 From: cwarnerdev <138500512+cwarnerdev@users.noreply.github.com> Date: Fri, 4 Apr 2025 04:56:01 -1000 Subject: [PATCH 02/18] use safecast for conversions, return error from UpdateBoundParameters() --- app/config.go | 4 +- app/configuration/configuration.go | 54 ++++++++++++++++++++----- app/configuration/configuration_test.go | 3 +- app/go.mod | 1 + app/go.sum | 2 + 5 files changed, 53 insertions(+), 11 deletions(-) diff --git a/app/config.go b/app/config.go index 1b70442a..4b85a200 100644 --- a/app/config.go +++ b/app/config.go @@ -136,7 +136,9 @@ func loadConfigurations(configFilesFlagSet *flag.FlagSet, configurationSets []*C for _, config := range configurationSets { // propagate values in the config back to bound parameters - config.config.UpdateBoundParameters() + if err := config.config.UpdateBoundParameters(); err != nil { + return err + } } return nil diff --git a/app/configuration/configuration.go b/app/configuration/configuration.go index 54e0edd2..26eba3dc 100644 --- a/app/configuration/configuration.go +++ b/app/configuration/configuration.go @@ -10,6 +10,8 @@ import ( "strings" "time" + "fortio.org/safecast" + "github.com/knadh/koanf" "github.com/knadh/koanf/providers/env" "github.com/knadh/koanf/providers/file" @@ -616,7 +618,7 @@ func (c *Configuration) BindParameters(flagset *flag.FlagSet, namespace string, // UpdateBoundParameters updates parameters that were bound using the BindParameters method with the current values in // the configuration. -func (c *Configuration) UpdateBoundParameters() { +func (c *Configuration) UpdateBoundParameters() error { for _, boundParameter := range c.boundParameters { parameterName := boundParameter.Name @@ -633,25 +635,57 @@ func (c *Configuration) UpdateBoundParameters() { case reflectutils.IntType: *(boundParameter.BoundPointer.(*int)) = c.Int(parameterName) case reflectutils.Int8Type: - *(boundParameter.BoundPointer.(*int8)) = int8(c.Int(parameterName)) + v, err := safecast.Convert[int8](c.Int(parameterName)) + if err != nil { + return err + } + *(boundParameter.BoundPointer.(*int8)) = v case reflectutils.Int16Type: - *(boundParameter.BoundPointer.(*int16)) = int16(c.Int(parameterName)) + v, err := safecast.Convert[int16](c.Int(parameterName)) + if err != nil { + return err + } + *(boundParameter.BoundPointer.(*int16)) = v case reflectutils.Int32Type: - *(boundParameter.BoundPointer.(*int32)) = int32(c.Int(parameterName)) + v, err := safecast.Convert[int32](c.Int(parameterName)) + if err != nil { + return err + } + *(boundParameter.BoundPointer.(*int32)) = v case reflectutils.Int64Type: *(boundParameter.BoundPointer.(*int64)) = c.Int64(parameterName) case reflectutils.StringType: *(boundParameter.BoundPointer.(*string)) = c.String(parameterName) case reflectutils.UintType: - *(boundParameter.BoundPointer.(*uint)) = uint(c.Int(parameterName)) + v, err := safecast.Convert[uint](c.Int(parameterName)) + if err != nil { + return err + } + *(boundParameter.BoundPointer.(*uint)) = v case reflectutils.Uint8Type: - *(boundParameter.BoundPointer.(*uint8)) = uint8(c.Int(parameterName)) + v, err := safecast.Convert[uint8](c.Int(parameterName)) + if err != nil { + return err + } + *(boundParameter.BoundPointer.(*uint8)) = v case reflectutils.Uint16Type: - *(boundParameter.BoundPointer.(*uint16)) = uint16(c.Int(parameterName)) + v, err := safecast.Convert[uint16](c.Int(parameterName)) + if err != nil { + return err + } + *(boundParameter.BoundPointer.(*uint16)) = v case reflectutils.Uint32Type: - *(boundParameter.BoundPointer.(*uint32)) = uint32(c.Int(parameterName)) + v, err := safecast.Convert[uint32](c.Int(parameterName)) + if err != nil { + return err + } + *(boundParameter.BoundPointer.(*uint32)) = v case reflectutils.Uint64Type: - *(boundParameter.BoundPointer.(*uint64)) = uint64(c.Int64(parameterName)) + v, err := safecast.Convert[uint64](c.Int64(parameterName)) + if err != nil { + return err + } + *(boundParameter.BoundPointer.(*uint64)) = v case reflectutils.StringSliceType: *(boundParameter.BoundPointer.(*[]string)) = c.Strings(parameterName) case reflectutils.StringMapType: @@ -672,6 +706,8 @@ func (c *Configuration) UpdateBoundParameters() { reflect.ValueOf(boundParameter.BoundPointer).Elem().Set(newBoundParameterPointer.Elem()) } } + + return nil } // GetParameterPath returns the path to the parameter with the given name. diff --git a/app/configuration/configuration_test.go b/app/configuration/configuration_test.go index 76087611..218c83d8 100644 --- a/app/configuration/configuration_test.go +++ b/app/configuration/configuration_test.go @@ -272,7 +272,8 @@ func TestBindAndUpdateParameters(t *testing.T) { err = config.LoadFlagSet(flagset) assert.NoError(t, err) - config.UpdateBoundParameters() + err = config.UpdateBoundParameters() + assert.NoError(t, err) assertFlag(t, flagset, config, ¶meters.TestField, "configuration.testField", diff --git a/app/go.mod b/app/go.mod index c61e0529..55aa5b2b 100644 --- a/app/go.mod +++ b/app/go.mod @@ -3,6 +3,7 @@ module github.com/iotaledger/hive.go/app go 1.22 require ( + fortio.org/safecast v1.0.0 github.com/felixge/fgprof v0.9.4 github.com/hashicorp/go-version v1.6.0 github.com/iotaledger/hive.go/ierrors v0.0.0-20240517131232-748f1ce3a2d2 diff --git a/app/go.sum b/app/go.sum index bacd4247..7bf0d744 100644 --- a/app/go.sum +++ b/app/go.sum @@ -1,5 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +fortio.org/safecast v1.0.0 h1:dr3131WPX8iS1pTf76+39WeXbTrerDYLvi9s7Oi3wiY= +fortio.org/safecast v1.0.0/go.mod h1:xZmcPk3vi4kuUFf+tq4SvnlVdwViqf6ZSZl91Jr9Jdg= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= From 53e72ddc8cb364f4bf1b3d270a2bd8d2884bc172 Mon Sep 17 00:00:00 2001 From: cwarnerdev <138500512+cwarnerdev@users.noreply.github.com> Date: Thu, 3 Apr 2025 04:07:44 -1000 Subject: [PATCH 03/18] fix linters migrating the linter config to latest so they will run --- .golangci.yml | 341 +++++++++++++++++++++++++------------------------- 1 file changed, 170 insertions(+), 171 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index e28605e9..7109afed 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,177 +1,176 @@ +version: "2" run: - tests: true - -linters-settings: - gofmt: - simplify: true - goimports: - local-prefixes: github.com/iotaledger + tests: true +linters: + default: none + enable: + - asasalint + - asciicheck + - bidichk + - bodyclose + - copyloopvar + - decorder + - depguard + - dogsled + - dupl + - dupword + - durationcheck + - err113 + - errcheck + - errchkjson + - errname + - errorlint + - forcetypeassert + - ginkgolinter + - gocheckcompilerdirectives + - goconst + - godot + - goheader + - gomodguard + - goprintffuncname + - gosec + - gosmopolitan + - govet + - grouper + - importas + - inamedparam + - ineffassign + - intrange + - loggercheck + - makezero + - mirror + - misspell + - musttag + - nakedret + - nilerr + - nilnil + - nlreturn + - noctx + - nolintlint + - nosprintfhostport + - paralleltest + - prealloc + - predeclared + - promlinter + - protogetter + - reassign + - revive + - rowserrcheck + - sloglint + - spancheck + - sqlclosecheck + - staticcheck + - tagliatelle + - testableexamples + - testifylint + - testpackage + - thelper + - tparallel + - unconvert + - unparam + - unused + - usestdlibvars + - wastedassign + - whitespace + - zerologlint + settings: + depguard: + rules: + main: + files: + - '!**/ierrors.go' + - '!**/ierrors_no_stacktrace.go' + deny: + - pkg: errors + desc: Should be replaced with "github.com/iotaledger/hive.go/ierrors" package + - pkg: golang.org/x/xerrors + desc: Should be replaced with "github.com/iotaledger/hive.go/ierrors" package + - pkg: github.com/pkg/errors + desc: Should be replaced with "github.com/iotaledger/hive.go/ierrors" package gocyclo: - min-complexity: 15 + min-complexity: 15 govet: - disable: - - shadow + disable: + - shadow misspell: - locale: US - staticcheck: - checks: ["all"] + locale: US nlreturn: - block-size: 2 - stylecheck: - initialisms: ["ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS", "SIP", "RTP", "AMQP", "DB", "TS"] - depguard: - rules: - main: - # exclude the ierrors.go file itself - files: - - "!**/ierrors.go" - - "!**/ierrors_no_stacktrace.go" - deny: - - pkg: "errors" - desc: Should be replaced with "github.com/iotaledger/hive.go/ierrors" package - - pkg: "golang.org/x/xerrors" - desc: Should be replaced with "github.com/iotaledger/hive.go/ierrors" package - - pkg: "github.com/pkg/errors" - desc: Should be replaced with "github.com/iotaledger/hive.go/ierrors" package - -linters: - # Disable all linters. - disable-all: true - # Enable specific linter - enable: - - errcheck - - gosimple - - govet - - ineffassign - - staticcheck - - unused - - asasalint - - asciicheck - - bidichk - - bodyclose - #- containedctx - #- contextcheck # this linter is buggy and renders all nolint rules useless - - copyloopvar - #- cyclop - - decorder - - depguard - - dogsled - - dupl - - dupword - - durationcheck - - errchkjson - - errname - - errorlint - - execinquery - #- exhaustive - #- exhaustruct - - exportloopref - #- forbidigo - - forcetypeassert - #- funlen - #- gci - - ginkgolinter - - gocheckcompilerdirectives - #- gochecknoglobals - #- gochecknoinits - #- gochecksumtype - #- gocognit - - goconst - #- gocritic - #- gocyclo - - godot - #- godox - - goerr113 - - gofmt - #- gofumpt - - goheader - - goimports - #- gomnd - #- gomoddirectives - - gomodguard - - goprintffuncname - - gosec - - gosmopolitan - - grouper - - importas - - inamedparam - #- interfacebloat - - intrange - #- ireturn - #- lll - - loggercheck - #- maintidx - - makezero - - mirror - - misspell - - musttag - - nakedret - #- nestif - - nilerr - - nilnil - - nlreturn - - noctx - - nolintlint - #- nonamedreturns - - nosprintfhostport - - paralleltest - #- perfsprint - - prealloc - - predeclared - - promlinter - - protogetter - - reassign - - revive - - rowserrcheck - - sloglint - - spancheck - - sqlclosecheck - - stylecheck - #- tagalign - - tagliatelle - - tenv - - testableexamples - - testifylint - - testpackage - - thelper - - tparallel - - unconvert - - unparam - - usestdlibvars - #- varnamelen - - wastedassign - - whitespace - #- wrapcheck - #- wsl - - zerologlint - + block-size: 2 + staticcheck: + checks: + - all + initialisms: + - ACL + - API + - ASCII + - CPU + - CSS + - DNS + - EOF + - GUID + - HTML + - HTTP + - HTTPS + - ID + - IP + - JSON + - QPS + - RAM + - RPC + - SLA + - SMTP + - SQL + - SSH + - TCP + - TLS + - TTL + - UDP + - UI + - GID + - UID + - UUID + - URI + - URL + - UTF8 + - VM + - XML + - XMPP + - XSRF + - XSS + - SIP + - RTP + - AMQP + - DB + - TS + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + paths: + - .*_test.go$ + - third_party$ + - builtin$ + - examples$ issues: - exclude-files: - - ".*_test.go$" - # Maximum issues count per one linter. - # Set to 0 to disable. - # Default: 50 - max-issues-per-linter: 0 - # Maximum count of issues with the same text. - # Set to 0 to disable. - # Default: 3 - max-same-issues: 0 - #exclude: - # - 'Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*print(f|ln)?|os\.(Un)?Setenv). is not checked' # errcheck - # - "err113: do not define dynamic errors, use wrapped static errors instead:" # goerr113 - # - "type name will be used as [0-9A-Za-z_.]+ by other packages, and that stutters; consider calling this" # golint - # - "Potential file inclusion via variable" # gosec - # - "G404: Use of weak random number generator" # gosec - # - "Subprocess launch(ed with variable|ing should be audited)" # gosec - # - "Use of unsafe calls should be audited" # gosec - # - "G108: Profiling endpoint is automatically exposed on /debug/pprof" # gosec - # - "(Expect directory permissions to be 0750 or less|Expect file permissions to be 0600 or less)" # gosec - # - "G101: Potential hardcoded credentials" # gosec - # - "(G104|G307)" # gosec Duplicated errcheck checks. - # - "`[0-9A-Za-z_.]+` - `[0-9A-Za-z_.]+` always receives `[0-9A-Za-z_.]+`" # unparam - # - "should have comment .*or be unexported" # revive - # - "exported: comment on exported" # revive - # - "package-comments: package comment should be of the form" # revive - # - "blank-imports" # revive - # - "var-naming: don't use leading k in Go names;" #revive - # - 'shadow: declaration of "err"' # govet + max-issues-per-linter: 0 + max-same-issues: 0 +formatters: + enable: + - gofmt + - goimports + settings: + gofmt: + simplify: true + goimports: + local-prefixes: + - github.com/iotaledger + exclusions: + generated: lax + paths: + - .*_test.go$ + - third_party$ + - builtin$ + - examples$ From 80629a6b59d15b46fd2224edbd8860b66a21f310 Mon Sep 17 00:00:00 2001 From: cwarnerdev <138500512+cwarnerdev@users.noreply.github.com> Date: Fri, 4 Apr 2025 05:15:48 -1000 Subject: [PATCH 04/18] ignore g115 in SafeMulInt64 - sign is accounted for --- core/safemath/safe_math.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/safemath/safe_math.go b/core/safemath/safe_math.go index 25d2f6fc..74f246ac 100644 --- a/core/safemath/safe_math.go +++ b/core/safemath/safe_math.go @@ -83,6 +83,9 @@ func SafeMulUint64(x, y uint64) (uint64, error) { // Returns x * y or an error if that computation would under- or overflow. // // According to benchmarks, this function is about 27% faster than SafeMul. +// +//nolint:gosec // disable G115 - integer overlfows are checked manua +//nolint:gosec // disable G115 - integer overlfows are checked manually func SafeMulInt64(x, y int64) (int64, error) { // This function stores the sign of the resulting int64 multiplication // and then executes the multiplication with two uint64s, in 128-bit space. From 1769b9768f9706bf104ccc28f4bc5e39bfbfa0c9 Mon Sep 17 00:00:00 2001 From: cwarnerdev <138500512+cwarnerdev@users.noreply.github.com> Date: Fri, 4 Apr 2025 05:30:05 -1000 Subject: [PATCH 05/18] fix redefinition of the built-in function --- lo/lo.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lo/lo.go b/lo/lo.go index 2bb167d1..bb6c14c8 100644 --- a/lo/lo.go +++ b/lo/lo.go @@ -222,12 +222,12 @@ func Max[T constraints.Ordered](collection ...T) T { maxElem = collection[0] - return Reduce(collection, func(max, value T) T { - if Comparator(value, max) > 0 { + return Reduce(collection, func(accum, value T) T { + if Comparator(value, accum) > 0 { return value } - return max + return accum }, maxElem) } @@ -240,12 +240,12 @@ func Min[T constraints.Ordered](collection ...T) T { minElem = collection[0] - return Reduce(collection, func(min, value T) T { - if Comparator(value, min) < 0 { + return Reduce(collection, func(accum, value T) T { + if Comparator(value, accum) < 0 { return value } - return min + return accum }, minElem) } From 372d70252406331932fcf9415e85f6c6cd8b1793 Mon Sep 17 00:00:00 2001 From: cwarnerdev <138500512+cwarnerdev@users.noreply.github.com> Date: Fri, 4 Apr 2025 05:31:42 -1000 Subject: [PATCH 06/18] fix QF1008: could remove embedded field "Logger" from selector (staticcheck) client.Logger.Shutdown() --- web/websockethub/hub.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/websockethub/hub.go b/web/websockethub/hub.go index ace7153e..55aa14b5 100644 --- a/web/websockethub/hub.go +++ b/web/websockethub/hub.go @@ -186,7 +186,7 @@ drainLoop: } // cleanup the logger - client.Logger.Shutdown() + client.Shutdown() h.events.ClientDisconnected.Trigger(&ClientConnectionEvent{ID: client.id}) From d196ad1168baf4177bd494badf10c03ba58f594f Mon Sep 17 00:00:00 2001 From: cwarnerdev <138500512+cwarnerdev@users.noreply.github.com> Date: Fri, 4 Apr 2025 06:01:25 -1000 Subject: [PATCH 07/18] fix QF1008: could remove embedded field --- ds/reactive/clock_impl.go | 6 +++--- ds/set_impl.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ds/reactive/clock_impl.go b/ds/reactive/clock_impl.go index 0a0c3263..e953048b 100644 --- a/ds/reactive/clock_impl.go +++ b/ds/reactive/clock_impl.go @@ -21,7 +21,7 @@ func newClock(granularity time.Duration) *clock { } // set the initial value. - c.variable.Set(time.Now()) + c.Set(time.Now()) go func() { // align the ticker to the given granularity. @@ -29,14 +29,14 @@ func newClock(granularity time.Duration) *clock { ticker := time.NewTicker(granularity) // first tick after the initial value. - c.variable.Set(time.Now().Truncate(granularity)) + c.Set(time.Now().Truncate(granularity)) for { select { case <-c.shutdown: return case t := <-ticker.C: - c.variable.Set(t.Truncate(granularity)) + c.Set(t.Truncate(granularity)) } } }() diff --git a/ds/set_impl.go b/ds/set_impl.go index f83e2505..26f69942 100644 --- a/ds/set_impl.go +++ b/ds/set_impl.go @@ -155,7 +155,7 @@ func newReadableSet[T comparable](elements ...T) *readableSet[T] { } for _, element := range elements { - r.OrderedMap.Set(element, types.Void) + r.Set(element, types.Void) } return r From 11974d9074de63281011aca22a870a7eb512c6f4 Mon Sep 17 00:00:00 2001 From: cwarnerdev <138500512+cwarnerdev@users.noreply.github.com> Date: Fri, 4 Apr 2025 06:11:41 -1000 Subject: [PATCH 08/18] fix G115: integer overflow conversion --- ds/go.mod | 1 + ds/go.sum | 2 ++ ds/reactive/wait_group_impl.go | 5 ++++- ds/serializableorderedmap/serializable_orderedmap.go | 9 ++++++++- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/ds/go.mod b/ds/go.mod index 87335502..a070f2a6 100644 --- a/ds/go.mod +++ b/ds/go.mod @@ -3,6 +3,7 @@ module github.com/iotaledger/hive.go/ds go 1.22 require ( + fortio.org/safecast v1.0.0 github.com/iotaledger/hive.go/constraints v0.0.0-20240517131232-748f1ce3a2d2 github.com/iotaledger/hive.go/ierrors v0.0.0-20240517131232-748f1ce3a2d2 github.com/iotaledger/hive.go/lo v0.0.0-20240517131232-748f1ce3a2d2 diff --git a/ds/go.sum b/ds/go.sum index 012009e1..985b6547 100644 --- a/ds/go.sum +++ b/ds/go.sum @@ -1,3 +1,5 @@ +fortio.org/safecast v1.0.0 h1:dr3131WPX8iS1pTf76+39WeXbTrerDYLvi9s7Oi3wiY= +fortio.org/safecast v1.0.0/go.mod h1:xZmcPk3vi4kuUFf+tq4SvnlVdwViqf6ZSZl91Jr9Jdg= github.com/btcsuite/btcd/btcec/v2 v2.2.1 h1:xP60mv8fvp+0khmrN0zTdPC3cNm24rfeE6lh2R/Yv3E= github.com/btcsuite/btcd/btcec/v2 v2.2.1/go.mod h1:9/CSmJxmuvqzX9Wh2fXMWToLOHhPd11lSPuIupwTkI8= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= diff --git a/ds/reactive/wait_group_impl.go b/ds/reactive/wait_group_impl.go index 1a838404..fa19bd33 100644 --- a/ds/reactive/wait_group_impl.go +++ b/ds/reactive/wait_group_impl.go @@ -6,6 +6,8 @@ import ( "sync" "sync/atomic" + "fortio.org/safecast" + "github.com/iotaledger/hive.go/ds" "github.com/iotaledger/hive.go/lo" ) @@ -37,7 +39,8 @@ func newWaitGroup[T comparable](elements ...T) *waitGroup[T] { // Add adds the given elements to the wait group. func (w *waitGroup[T]) Add(elements ...T) { // first increase the counter so that the trigger is not executed before all elements are added - w.pendingElementsCounter.Add(int32(len(elements))) + v := safecast.MustConvert[int32](len(elements)) + w.pendingElementsCounter.Add(v) // then add the elements (and correct the counter if the elements are already present) for _, element := range elements { diff --git a/ds/serializableorderedmap/serializable_orderedmap.go b/ds/serializableorderedmap/serializable_orderedmap.go index b200b81f..8155a94a 100644 --- a/ds/serializableorderedmap/serializable_orderedmap.go +++ b/ds/serializableorderedmap/serializable_orderedmap.go @@ -3,6 +3,8 @@ package serializableorderedmap import ( "context" + "fortio.org/safecast" + "github.com/iotaledger/hive.go/ds/orderedmap" "github.com/iotaledger/hive.go/ierrors" "github.com/iotaledger/hive.go/serializer/v2" @@ -23,9 +25,14 @@ func New[K comparable, V any]() *SerializableOrderedMap[K, V] { // Encode returns a serialized byte slice of the object. func (o *SerializableOrderedMap[K, V]) Encode(api *serix.API) ([]byte, error) { + v, err := safecast.Convert[uint32](o.Size()) + if err != nil { + return nil, err + } + seri := serializer.NewSerializer() - seri.WriteNum(uint32(o.Size()), func(err error) error { + seri.WriteNum(v, func(err error) error { return ierrors.Wrap(err, "failed to write SerializableOrderedMap size to serializer") }) From 893e978f96bd2e8210de4a79e2daae16bd2b6df7 Mon Sep 17 00:00:00 2001 From: cwarnerdev <138500512+cwarnerdev@users.noreply.github.com> Date: Fri, 4 Apr 2025 06:19:10 -1000 Subject: [PATCH 09/18] fix G115: integer overflow conversion --- ads/go.mod | 1 + ads/go.sum | 2 ++ ads/map_impl.go | 16 ++++++++++++++-- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/ads/go.mod b/ads/go.mod index 6cf8439c..a6891264 100644 --- a/ads/go.mod +++ b/ads/go.mod @@ -3,6 +3,7 @@ module github.com/iotaledger/hive.go/ads go 1.22 require ( + fortio.org/safecast v1.0.0 github.com/iotaledger/hive.go/ds v0.0.0-20240517131232-748f1ce3a2d2 github.com/iotaledger/hive.go/ierrors v0.0.0-20240517131232-748f1ce3a2d2 github.com/iotaledger/hive.go/kvstore v0.0.0-20240517131232-748f1ce3a2d2 diff --git a/ads/go.sum b/ads/go.sum index 2bda3a9f..8a06509d 100644 --- a/ads/go.sum +++ b/ads/go.sum @@ -1,3 +1,5 @@ +fortio.org/safecast v1.0.0 h1:dr3131WPX8iS1pTf76+39WeXbTrerDYLvi9s7Oi3wiY= +fortio.org/safecast v1.0.0/go.mod h1:xZmcPk3vi4kuUFf+tq4SvnlVdwViqf6ZSZl91Jr9Jdg= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/ads/map_impl.go b/ads/map_impl.go index 7a191d55..03d3a44a 100644 --- a/ads/map_impl.go +++ b/ads/map_impl.go @@ -4,6 +4,8 @@ import ( "crypto/sha256" "sync" + "fortio.org/safecast" + "github.com/pokt-network/smt" "github.com/iotaledger/hive.go/ds/types" @@ -124,7 +126,12 @@ func (m *authenticatedMap[IdentifierType, K, V]) Size() int { return 0 } - return int(size) + v, err := safecast.Convert[int](size) + if err != nil { + return 0 + } + + return v } // Commit persists the current state of the map to the storage. @@ -277,7 +284,12 @@ func (m *authenticatedMap[IdentifierType, K, V]) addSize(delta int) error { return ierrors.Wrap(err, "failed to get size") } - if err := m.size.Set(uint64(int(size) + delta)); err != nil { + deltaUint, err := safecast.Convert[uint64](delta) + if err != nil { + return ierrors.Wrap(err, "failed to convert delta to uint64") + } + + if err := m.size.Set(size + deltaUint); err != nil { return ierrors.Wrap(err, "failed to set size") } From 3958eb35c4046d7cd652729b6d432440d05152c4 Mon Sep 17 00:00:00 2001 From: cwarnerdev <138500512+cwarnerdev@users.noreply.github.com> Date: Fri, 4 Apr 2025 06:22:47 -1000 Subject: [PATCH 10/18] ignore G115: integer overflow conversion --- crypto/randomness.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/randomness.go b/crypto/randomness.go index e18df1c3..f1912137 100644 --- a/crypto/randomness.go +++ b/crypto/randomness.go @@ -14,7 +14,7 @@ func (s RandomnessSource) Seed(int64) {} // Int63 returns a non-negative random 63-bit integer as an int64. func (s RandomnessSource) Int63() int64 { - return int64(s.Uint64() & ^uint64(1<<63)) + return int64(s.Uint64() & ^uint64(1<<63)) //nolint:gosec // ignore integer overflow error } // Uint64 returns a random 64-bit value as a uint64. From f6bb1fc124b0d6b898293abe9ef30e63824da0c2 Mon Sep 17 00:00:00 2001 From: cwarnerdev <138500512+cwarnerdev@users.noreply.github.com> Date: Fri, 4 Apr 2025 06:29:34 -1000 Subject: [PATCH 11/18] update nolint for err113 --- ierrors/ierrors.go | 2 +- ierrors/ierrors_no_stacktrace.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ierrors/ierrors.go b/ierrors/ierrors.go index 81a1795a..a72e9dc4 100644 --- a/ierrors/ierrors.go +++ b/ierrors/ierrors.go @@ -2,7 +2,7 @@ // It enhances error handling by adding additional error creation and manipulation functions. // This package also supports stacktraces when the "stacktrace" build tag is added. // -//nolint:goerr113 +//nolint:err113 package ierrors import ( diff --git a/ierrors/ierrors_no_stacktrace.go b/ierrors/ierrors_no_stacktrace.go index 4f68f012..815ccb9b 100644 --- a/ierrors/ierrors_no_stacktrace.go +++ b/ierrors/ierrors_no_stacktrace.go @@ -1,6 +1,6 @@ //go:build !stacktrace -//nolint:goerr113 +//nolint:err113 package ierrors import ( From 9f18e7087c85bf8a40f4e7772a491475334e93dd Mon Sep 17 00:00:00 2001 From: cwarnerdev <138500512+cwarnerdev@users.noreply.github.com> Date: Tue, 8 Apr 2025 05:25:54 -1000 Subject: [PATCH 12/18] update fix linter errors --- serializer/error.go | 6 ++--- serializer/go.mod | 1 + serializer/go.sum | 2 ++ serializer/serializer.go | 39 +++++++++++++++++++++-------- serializer/serix/map_decode.go | 20 +++++++++++---- serializer/serix/map_encode_test.go | 3 ++- serializer/serix/type_settings.go | 29 ++++++++++++++++----- serializer/stream/read.go | 29 ++++++++++++++++++--- serializer/stream/write.go | 3 +++ 9 files changed, 102 insertions(+), 30 deletions(-) diff --git a/serializer/error.go b/serializer/error.go index 5d45df95..8426d325 100644 --- a/serializer/error.go +++ b/serializer/error.go @@ -89,9 +89,9 @@ func CheckExactByteLength(exact int, length int) error { } // CheckMinByteLength checks that length is at least min. -func CheckMinByteLength(min int, length int) error { - if length < min { - return ierrors.Wrapf(ErrDeserializationNotEnoughData, "data must be at least %d bytes long but is %d", min, length) +func CheckMinByteLength(minimum int, length int) error { + if length < minimum { + return ierrors.Wrapf(ErrDeserializationNotEnoughData, "data must be at least %d bytes long but is %d", minimum, length) } return nil diff --git a/serializer/go.mod b/serializer/go.mod index cb3eaea7..bfcf05c2 100644 --- a/serializer/go.mod +++ b/serializer/go.mod @@ -3,6 +3,7 @@ module github.com/iotaledger/hive.go/serializer/v2 go 1.22 require ( + fortio.org/safecast v1.0.0 github.com/ethereum/go-ethereum v1.14.3 github.com/iancoleman/orderedmap v0.3.0 github.com/iotaledger/hive.go/ds v0.0.0-20240517131232-748f1ce3a2d2 diff --git a/serializer/go.sum b/serializer/go.sum index 996eefbb..9fae9881 100644 --- a/serializer/go.sum +++ b/serializer/go.sum @@ -1,3 +1,5 @@ +fortio.org/safecast v1.0.0 h1:dr3131WPX8iS1pTf76+39WeXbTrerDYLvi9s7Oi3wiY= +fortio.org/safecast v1.0.0/go.mod h1:xZmcPk3vi4kuUFf+tq4SvnlVdwViqf6ZSZl91Jr9Jdg= github.com/btcsuite/btcd/btcec/v2 v2.2.1 h1:xP60mv8fvp+0khmrN0zTdPC3cNm24rfeE6lh2R/Yv3E= github.com/btcsuite/btcd/btcec/v2 v2.2.1/go.mod h1:9/CSmJxmuvqzX9Wh2fXMWToLOHhPd11lSPuIupwTkI8= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= diff --git a/serializer/serializer.go b/serializer/serializer.go index 3354cb8c..1d9ce64c 100644 --- a/serializer/serializer.go +++ b/serializer/serializer.go @@ -10,6 +10,8 @@ import ( "sort" "time" + "fortio.org/safecast" + "github.com/iotaledger/hive.go/ierrors" ) @@ -231,7 +233,7 @@ func (s *Serializer) writeSliceLength(l int, lenType SeriLengthPrefixType, errPr return } - if err := binary.Write(&s.buf, binary.LittleEndian, uint16(l)); err != nil { + if err := binary.Write(&s.buf, binary.LittleEndian, uint16(l)); err != nil { //nolint:gosec // overflow checked above s.err = errProducer(err) return @@ -242,7 +244,7 @@ func (s *Serializer) writeSliceLength(l int, lenType SeriLengthPrefixType, errPr return } - if err := binary.Write(&s.buf, binary.LittleEndian, uint32(l)); err != nil { + if err := binary.Write(&s.buf, binary.LittleEndian, uint32(l)); err != nil { //nolint:gosec // overflow checked above s.err = errProducer(err) return @@ -432,12 +434,17 @@ func TimeToUint64(value time.Time) uint64 { unixNano = 0 } - return uint64(unixNano) + return uint64(unixNano) //nolint:gosec // overflow checked above } // Uint64ToTime converts a uint64 unix timestamp with nanosecond-precision to a time.Time. -func Uint64ToTime(value uint64) time.Time { - return time.Unix(0, int64(value)).UTC() +func Uint64ToTime(value uint64) (time.Time, error) { + v, err := safecast.Convert[int64](value) + if err != nil { + return time.Unix(0, 0), err + } + + return time.Unix(0, v).UTC(), nil } // WritePayload writes the given payload Serializable into the Serializer. @@ -493,7 +500,11 @@ func (s *Serializer) WritePayloadLength(length int, errProducer ErrProducer) *Se } func (s *Serializer) writePayloadLength(length int) error { - if err := binary.Write(&s.buf, binary.LittleEndian, uint32(length)); err != nil { + v, err := safecast.Convert[uint32](length) + if err != nil { + return ierrors.Wrap(err, "unable to serialize payload length") + } + if err := binary.Write(&s.buf, binary.LittleEndian, v); err != nil { return ierrors.Wrap(err, "unable to serialize payload length") } @@ -687,19 +698,19 @@ func (d *Deserializer) ReadNum(dest any, errProducer ErrProducer) *Deserializer *x = data[0] case *int16: - *x = int16(binary.LittleEndian.Uint16(data)) + *x = safecast.MustConvert[int16](binary.LittleEndian.Uint16(data)) case *uint16: *x = binary.LittleEndian.Uint16(data) case *int32: - *x = int32(binary.LittleEndian.Uint32(data)) + *x = safecast.MustConvert[int32](binary.LittleEndian.Uint32(data)) case *uint32: *x = binary.LittleEndian.Uint32(data) case *int64: - *x = int64(binary.LittleEndian.Uint64(data)) + *x = safecast.MustConvert[int64](binary.LittleEndian.Uint64(data)) case *uint64: *x = binary.LittleEndian.Uint64(data) @@ -984,7 +995,13 @@ func (d *Deserializer) ReadSequenceOfObjects( var arrayElementValidator ElementValidationFunc if deSeriMode.HasMode(DeSeriModePerformValidation) { - if err := arrayRules.CheckBounds(uint(sliceLength)); err != nil { + v, err := safecast.Convert[uint](sliceLength) + if err != nil { + d.err = errProducer(err) + + return d + } + if err := arrayRules.CheckBounds(v); err != nil { d.err = errProducer(err) return d @@ -1053,7 +1070,7 @@ func (d *Deserializer) ReadTime(dest *time.Time, errProducer ErrProducer) *Deser nanoseconds = math.MaxInt64 } - *dest = time.Unix(0, int64(nanoseconds)).UTC() + *dest = time.Unix(0, int64(nanoseconds)).UTC() //nolint:gosec // overflow checked above d.offset += UInt64ByteSize diff --git a/serializer/serix/map_decode.go b/serializer/serix/map_decode.go index a2dc52d5..aba929fd 100644 --- a/serializer/serix/map_decode.go +++ b/serializer/serix/map_decode.go @@ -145,7 +145,11 @@ func (api *API) mapDecodeBasedOnType(ctx context.Context, mapVal any, value refl sliceValue := sliceFromArray(value) sliceValueType := sliceValue.Type() if sliceValueType.AssignableTo(bytesType) { - byteSlice, err := DecodeHex(mapVal.(string)) + str, ok := mapVal.(string) + if !ok { + return ierrors.New("non string value for string field") + } + byteSlice, err := DecodeHex(str) if err != nil { return ierrors.Wrap(err, "failed to read byte slice from map") } @@ -262,8 +266,11 @@ func (api *API) mapDecodeFloat(value reflect.Value, valueType reflect.Type, mapV addrValue := value.Addr() bitSize, _, addrTypeToConvert := getNumberTypeToConvert(valueType.Kind()) addrValue = addrValue.Convert(addrTypeToConvert) - - f, err := strconv.ParseFloat(mapVal.(string), bitSize) + str, ok := mapVal.(string) + if !ok { + return ierrors.New("non string value for string field") + } + f, err := strconv.ParseFloat(str, bitSize) if err != nil { return err } @@ -315,8 +322,11 @@ func (api *API) mapDecodeStruct(ctx context.Context, mapVal any, value reflect.V if err != nil { return ierrors.Wrapf(err, "unable to parse time %s map value", strVal) } - - value.Set(reflect.ValueOf(serializer.Uint64ToTime(nanoTime))) + t, err := serializer.Uint64ToTime(nanoTime) + if err != nil { + return ierrors.Wrapf(err, "unable to parse time %s map value", strVal) + } + value.Set(reflect.ValueOf(t)) return nil } diff --git a/serializer/serix/map_encode_test.go b/serializer/serix/map_encode_test.go index 47e5445e..9077c0cf 100644 --- a/serializer/serix/map_encode_test.go +++ b/serializer/serix/map_encode_test.go @@ -377,7 +377,8 @@ func TestMapEncodeDecode(t *testing.T) { uint64Time, err := serix.DecodeUint64("1660301478120072000") require.NoError(t, err) - exampleTime := serializer.Uint64ToTime(uint64Time) + exampleTime, err := serializer.Uint64ToTime(uint64Time) + require.NoError(t, err) return paras{ api: api, diff --git a/serializer/serix/type_settings.go b/serializer/serix/type_settings.go index 8161eabd..5d83cbbe 100644 --- a/serializer/serix/type_settings.go +++ b/serializer/serix/type_settings.go @@ -4,6 +4,8 @@ import ( "reflect" "sync" + "fortio.org/safecast" + hiveorderedmap "github.com/iotaledger/hive.go/ds/orderedmap" "github.com/iotaledger/hive.go/ierrors" "github.com/iotaledger/hive.go/serializer/v2" @@ -212,15 +214,23 @@ func (ts TypeSettings) MaxLen() (uint, bool) { // MinMaxLen returns min/max lengths for the object. // Returns 0 for either value if they are not set. func (ts TypeSettings) MinMaxLen() (int, int) { - var min, max int + var minimum, maximum int if ts.arrayRules != nil { - min = int(ts.arrayRules.Min) + v, err := safecast.Convert[int](ts.arrayRules.Min) + if err != nil { + panic("array rule min conversion failed") + } + minimum = v } if ts.arrayRules != nil { - max = int(ts.arrayRules.Max) + v, err := safecast.Convert[int](ts.arrayRules.Max) + if err != nil { + panic("array rule max conversion failed") + } + maximum = v } - return min, max + return minimum, maximum } func (ts TypeSettings) ensureOrdering() TypeSettings { @@ -267,13 +277,20 @@ func (ts TypeSettings) toMode(opts *options) serializer.DeSerializationMode { // checkMinMaxBoundsLength checks whether the given length is within its defined bounds. func (ts TypeSettings) checkMinMaxBoundsLength(length int) error { + v, err := safecast.Convert[uint](length) if minLen, ok := ts.MinLen(); ok { - if uint(length) < minLen { + if err != nil { + return ierrors.Wrap(err, "invalid length specified") + } + if v < minLen { return ierrors.Wrapf(serializer.ErrArrayValidationMinElementsNotReached, "min length %d not reached (len %d)", minLen, length) } } if maxLen, ok := ts.MaxLen(); ok { - if uint(length) > maxLen { + if err != nil { + return ierrors.Wrap(err, "invalid length specified") + } + if v > maxLen { return ierrors.Wrapf(serializer.ErrArrayValidationMaxElementsExceeded, "max length %d exceeded (len %d)", maxLen, length) } } diff --git a/serializer/stream/read.go b/serializer/stream/read.go index 1b10440d..f1e3f74f 100644 --- a/serializer/stream/read.go +++ b/serializer/stream/read.go @@ -5,6 +5,8 @@ import ( "fmt" "io" + "fortio.org/safecast" + "github.com/iotaledger/hive.go/ierrors" "github.com/iotaledger/hive.go/serializer/v2" ) @@ -127,29 +129,48 @@ func readFixedSize(reader io.Reader, lenType serializer.SeriLengthPrefixType) (i if err != nil { return 0, ierrors.Wrap(err, "failed to read length prefix") } + v, err := safecast.Convert[int](result) + if err != nil { + return 0, ierrors.Wrap(err, "failed to convert length prefix") + } - return int(result), nil + return v, nil case serializer.SeriLengthPrefixTypeAsUint16: result, err := Read[uint16](reader) if err != nil { return 0, ierrors.Wrap(err, "failed to read length prefix") } - return int(result), nil + v, err := safecast.Convert[int](result) + if err != nil { + return 0, ierrors.Wrap(err, "failed to convert length prefix") + } + + return v, nil case serializer.SeriLengthPrefixTypeAsUint32: result, err := Read[uint32](reader) if err != nil { return 0, ierrors.Wrap(err, "failed to read length prefix") } - return int(result), nil + v, err := safecast.Convert[int](result) + if err != nil { + return 0, ierrors.Wrap(err, "failed to convert length prefix") + } + + return v, nil case serializer.SeriLengthPrefixTypeAsUint64: result, err := Read[uint64](reader) if err != nil { return 0, ierrors.Wrap(err, "failed to read length prefix") } - return int(result), nil + v, err := safecast.Convert[int](result) + if err != nil { + return 0, ierrors.Wrap(err, "failed to convert length prefix") + } + + return v, nil default: panic(fmt.Sprintf("unknown slice length type %v", lenType)) } diff --git a/serializer/stream/write.go b/serializer/stream/write.go index 05d25a1c..12a7ba63 100644 --- a/serializer/stream/write.go +++ b/serializer/stream/write.go @@ -131,6 +131,9 @@ func writeFixedSize(writer io.Writer, l int, lenType serializer.SeriLengthPrefix return nil case serializer.SeriLengthPrefixTypeAsUint64: + if l < 0 { + return ierrors.Errorf("unable to serialize collection length: length %d must be non-negative", l) + } if err := Write(writer, uint64(l)); err != nil { return ierrors.Wrap(err, "unable to write length") } From 59273f6078587594da7f099b02d5cb7e210d7a5c Mon Sep 17 00:00:00 2001 From: cwarnerdev <138500512+cwarnerdev@users.noreply.github.com> Date: Tue, 8 Apr 2025 05:30:02 -1000 Subject: [PATCH 13/18] fix addSize() --- ads/map_impl.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/ads/map_impl.go b/ads/map_impl.go index 03d3a44a..2c689b72 100644 --- a/ads/map_impl.go +++ b/ads/map_impl.go @@ -284,12 +284,19 @@ func (m *authenticatedMap[IdentifierType, K, V]) addSize(delta int) error { return ierrors.Wrap(err, "failed to get size") } - deltaUint, err := safecast.Convert[uint64](delta) + sizeInt, err := safecast.Convert[int](size) if err != nil { - return ierrors.Wrap(err, "failed to convert delta to uint64") + return ierrors.Wrap(err, "failed to convert size to int") } - if err := m.size.Set(size + deltaUint); err != nil { + newSize := sizeInt + delta + + updatedSize, err := safecast.Convert[uint64](newSize) + if err != nil { + return ierrors.Wrap(err, "failed to convert new size to uint64") + } + + if err := m.size.Set(updatedSize); err != nil { return ierrors.Wrap(err, "failed to set size") } From 686b89422620a67c4866afff644516bf3360a51b Mon Sep 17 00:00:00 2001 From: cwarnerdev <138500512+cwarnerdev@users.noreply.github.com> Date: Tue, 8 Apr 2025 05:41:19 -1000 Subject: [PATCH 14/18] fix linter errors --- runtime/backoff/options.go | 4 ++-- runtime/contextutils/merged_context.go | 10 +++++----- runtime/event/events_test.go | 4 ++-- runtime/event/options.go | 8 ++++---- runtime/go.mod | 1 + runtime/go.sum | 2 ++ 6 files changed, 16 insertions(+), 13 deletions(-) diff --git a/runtime/backoff/options.go b/runtime/backoff/options.go index 349f9943..a432be17 100644 --- a/runtime/backoff/options.go +++ b/runtime/backoff/options.go @@ -29,11 +29,11 @@ func (f statelessOptionFunc) apply(p Policy) Policy { } // MaxRetries configures a backoff policy to return Stop if NextBackOff() has been called too many times. -func MaxRetries(max int) Option { +func MaxRetries(value int) Option { return optionFunc(func(p Policy) Policy { return &maxRetriesOption{ delegate: p, - maxTries: max, + maxTries: value, numTries: 0, } }) diff --git a/runtime/contextutils/merged_context.go b/runtime/contextutils/merged_context.go index fe5d4c0d..79a613d6 100644 --- a/runtime/contextutils/merged_context.go +++ b/runtime/contextutils/merged_context.go @@ -87,20 +87,20 @@ func MergeContexts(ctxPrimary context.Context, ctxSecondary context.Context) (co // Deadline returns ok==false when no deadline is set. // Successive calls to Deadline return the same results. func (mc *mergedContext) Deadline() (time.Time, bool) { - min := time.Time{} + minimum := time.Time{} if dl, ok := mc.ctxPrimary.Deadline(); ok { - min = dl + minimum = dl } if dl, ok := mc.ctxSecondary.Deadline(); ok { // if deadline not set yet or secondary deadline is before current deadline - if min.IsZero() || dl.Before(min) { - min = dl + if minimum.IsZero() || dl.Before(minimum) { + minimum = dl } } - return min, !min.IsZero() + return minimum, !minimum.IsZero() } // Done returns a channel that's closed when work done on behalf of the diff --git a/runtime/event/events_test.go b/runtime/event/events_test.go index 6872231e..e23df222 100644 --- a/runtime/event/events_test.go +++ b/runtime/event/events_test.go @@ -137,8 +137,8 @@ func TestEvent1_Hook_WorkerPool(t *testing.T) { require.False(t, hook.WasTriggered()) testEvent.Trigger(0) require.True(t, testEvent.WasTriggered()) - require.Equal(t, 1, testEvent.TriggerCount()) - require.Equal(t, testEvent.MaxTriggerCount(), 0) + require.Equal(t, uint64(1), testEvent.TriggerCount()) + require.Equal(t, testEvent.MaxTriggerCount(), uint64(0)) require.False(t, testEvent.MaxTriggerCountReached()) require.True(t, hook.WasTriggered()) diff --git a/runtime/event/options.go b/runtime/event/options.go index 35890ba8..66f97f39 100644 --- a/runtime/event/options.go +++ b/runtime/event/options.go @@ -49,13 +49,13 @@ func (t *triggerSettings) WasTriggered() bool { } // TriggerCount returns the number of times Trigger was called. -func (t *triggerSettings) TriggerCount() int { - return int(t.triggerCount.Load()) +func (t *triggerSettings) TriggerCount() uint64 { + return t.triggerCount.Load() } // MaxTriggerCount returns the maximum number of times Trigger can be called. -func (t *triggerSettings) MaxTriggerCount() int { - return int(t.maxTriggerCount) +func (t *triggerSettings) MaxTriggerCount() uint64 { + return t.maxTriggerCount } // MaxTriggerCountReached returns true if the maximum number of times Trigger can be called was reached. diff --git a/runtime/go.mod b/runtime/go.mod index 4052953e..369a35c4 100644 --- a/runtime/go.mod +++ b/runtime/go.mod @@ -3,6 +3,7 @@ module github.com/iotaledger/hive.go/runtime go 1.22 require ( + fortio.org/safecast v1.0.0 github.com/fjl/memsize v0.0.2 github.com/iotaledger/hive.go/constraints v0.0.0-20240517131232-748f1ce3a2d2 github.com/iotaledger/hive.go/ds v0.0.0-20240517131232-748f1ce3a2d2 diff --git a/runtime/go.sum b/runtime/go.sum index e4b6fd56..a9e478d0 100644 --- a/runtime/go.sum +++ b/runtime/go.sum @@ -1,3 +1,5 @@ +fortio.org/safecast v1.0.0 h1:dr3131WPX8iS1pTf76+39WeXbTrerDYLvi9s7Oi3wiY= +fortio.org/safecast v1.0.0/go.mod h1:xZmcPk3vi4kuUFf+tq4SvnlVdwViqf6ZSZl91Jr9Jdg= github.com/btcsuite/btcd/btcec/v2 v2.2.1 h1:xP60mv8fvp+0khmrN0zTdPC3cNm24rfeE6lh2R/Yv3E= github.com/btcsuite/btcd/btcec/v2 v2.2.1/go.mod h1:9/CSmJxmuvqzX9Wh2fXMWToLOHhPd11lSPuIupwTkI8= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= From fffa583c756bdd53789659511d83d40af0a9e7d3 Mon Sep 17 00:00:00 2001 From: cwarnerdev <138500512+cwarnerdev@users.noreply.github.com> Date: Tue, 8 Apr 2025 05:48:30 -1000 Subject: [PATCH 15/18] Revert "fix linter errors" This reverts commit 686b89422620a67c4866afff644516bf3360a51b. --- runtime/backoff/options.go | 4 ++-- runtime/contextutils/merged_context.go | 10 +++++----- runtime/event/events_test.go | 4 ++-- runtime/event/options.go | 8 ++++---- runtime/go.mod | 1 - runtime/go.sum | 2 -- 6 files changed, 13 insertions(+), 16 deletions(-) diff --git a/runtime/backoff/options.go b/runtime/backoff/options.go index a432be17..349f9943 100644 --- a/runtime/backoff/options.go +++ b/runtime/backoff/options.go @@ -29,11 +29,11 @@ func (f statelessOptionFunc) apply(p Policy) Policy { } // MaxRetries configures a backoff policy to return Stop if NextBackOff() has been called too many times. -func MaxRetries(value int) Option { +func MaxRetries(max int) Option { return optionFunc(func(p Policy) Policy { return &maxRetriesOption{ delegate: p, - maxTries: value, + maxTries: max, numTries: 0, } }) diff --git a/runtime/contextutils/merged_context.go b/runtime/contextutils/merged_context.go index 79a613d6..fe5d4c0d 100644 --- a/runtime/contextutils/merged_context.go +++ b/runtime/contextutils/merged_context.go @@ -87,20 +87,20 @@ func MergeContexts(ctxPrimary context.Context, ctxSecondary context.Context) (co // Deadline returns ok==false when no deadline is set. // Successive calls to Deadline return the same results. func (mc *mergedContext) Deadline() (time.Time, bool) { - minimum := time.Time{} + min := time.Time{} if dl, ok := mc.ctxPrimary.Deadline(); ok { - minimum = dl + min = dl } if dl, ok := mc.ctxSecondary.Deadline(); ok { // if deadline not set yet or secondary deadline is before current deadline - if minimum.IsZero() || dl.Before(minimum) { - minimum = dl + if min.IsZero() || dl.Before(min) { + min = dl } } - return minimum, !minimum.IsZero() + return min, !min.IsZero() } // Done returns a channel that's closed when work done on behalf of the diff --git a/runtime/event/events_test.go b/runtime/event/events_test.go index e23df222..6872231e 100644 --- a/runtime/event/events_test.go +++ b/runtime/event/events_test.go @@ -137,8 +137,8 @@ func TestEvent1_Hook_WorkerPool(t *testing.T) { require.False(t, hook.WasTriggered()) testEvent.Trigger(0) require.True(t, testEvent.WasTriggered()) - require.Equal(t, uint64(1), testEvent.TriggerCount()) - require.Equal(t, testEvent.MaxTriggerCount(), uint64(0)) + require.Equal(t, 1, testEvent.TriggerCount()) + require.Equal(t, testEvent.MaxTriggerCount(), 0) require.False(t, testEvent.MaxTriggerCountReached()) require.True(t, hook.WasTriggered()) diff --git a/runtime/event/options.go b/runtime/event/options.go index 66f97f39..35890ba8 100644 --- a/runtime/event/options.go +++ b/runtime/event/options.go @@ -49,13 +49,13 @@ func (t *triggerSettings) WasTriggered() bool { } // TriggerCount returns the number of times Trigger was called. -func (t *triggerSettings) TriggerCount() uint64 { - return t.triggerCount.Load() +func (t *triggerSettings) TriggerCount() int { + return int(t.triggerCount.Load()) } // MaxTriggerCount returns the maximum number of times Trigger can be called. -func (t *triggerSettings) MaxTriggerCount() uint64 { - return t.maxTriggerCount +func (t *triggerSettings) MaxTriggerCount() int { + return int(t.maxTriggerCount) } // MaxTriggerCountReached returns true if the maximum number of times Trigger can be called was reached. diff --git a/runtime/go.mod b/runtime/go.mod index 369a35c4..4052953e 100644 --- a/runtime/go.mod +++ b/runtime/go.mod @@ -3,7 +3,6 @@ module github.com/iotaledger/hive.go/runtime go 1.22 require ( - fortio.org/safecast v1.0.0 github.com/fjl/memsize v0.0.2 github.com/iotaledger/hive.go/constraints v0.0.0-20240517131232-748f1ce3a2d2 github.com/iotaledger/hive.go/ds v0.0.0-20240517131232-748f1ce3a2d2 diff --git a/runtime/go.sum b/runtime/go.sum index a9e478d0..e4b6fd56 100644 --- a/runtime/go.sum +++ b/runtime/go.sum @@ -1,5 +1,3 @@ -fortio.org/safecast v1.0.0 h1:dr3131WPX8iS1pTf76+39WeXbTrerDYLvi9s7Oi3wiY= -fortio.org/safecast v1.0.0/go.mod h1:xZmcPk3vi4kuUFf+tq4SvnlVdwViqf6ZSZl91Jr9Jdg= github.com/btcsuite/btcd/btcec/v2 v2.2.1 h1:xP60mv8fvp+0khmrN0zTdPC3cNm24rfeE6lh2R/Yv3E= github.com/btcsuite/btcd/btcec/v2 v2.2.1/go.mod h1:9/CSmJxmuvqzX9Wh2fXMWToLOHhPd11lSPuIupwTkI8= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= From cab53712fe9eb8ff76abc441f09a8fc78e016a38 Mon Sep 17 00:00:00 2001 From: cwarnerdev <138500512+cwarnerdev@users.noreply.github.com> Date: Tue, 8 Apr 2025 05:52:10 -1000 Subject: [PATCH 16/18] fix linter errors --- runtime/backoff/options.go | 4 ++-- runtime/contextutils/merged_context.go | 10 +++++----- runtime/event/options.go | 9 +++++++-- runtime/go.mod | 1 + runtime/go.sum | 2 ++ 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/runtime/backoff/options.go b/runtime/backoff/options.go index 349f9943..7982098f 100644 --- a/runtime/backoff/options.go +++ b/runtime/backoff/options.go @@ -29,11 +29,11 @@ func (f statelessOptionFunc) apply(p Policy) Policy { } // MaxRetries configures a backoff policy to return Stop if NextBackOff() has been called too many times. -func MaxRetries(max int) Option { +func MaxRetries(maximum int) Option { return optionFunc(func(p Policy) Policy { return &maxRetriesOption{ delegate: p, - maxTries: max, + maxTries: maximum, numTries: 0, } }) diff --git a/runtime/contextutils/merged_context.go b/runtime/contextutils/merged_context.go index fe5d4c0d..79a613d6 100644 --- a/runtime/contextutils/merged_context.go +++ b/runtime/contextutils/merged_context.go @@ -87,20 +87,20 @@ func MergeContexts(ctxPrimary context.Context, ctxSecondary context.Context) (co // Deadline returns ok==false when no deadline is set. // Successive calls to Deadline return the same results. func (mc *mergedContext) Deadline() (time.Time, bool) { - min := time.Time{} + minimum := time.Time{} if dl, ok := mc.ctxPrimary.Deadline(); ok { - min = dl + minimum = dl } if dl, ok := mc.ctxSecondary.Deadline(); ok { // if deadline not set yet or secondary deadline is before current deadline - if min.IsZero() || dl.Before(min) { - min = dl + if minimum.IsZero() || dl.Before(minimum) { + minimum = dl } } - return min, !min.IsZero() + return minimum, !minimum.IsZero() } // Done returns a channel that's closed when work done on behalf of the diff --git a/runtime/event/options.go b/runtime/event/options.go index 35890ba8..53c9c0fb 100644 --- a/runtime/event/options.go +++ b/runtime/event/options.go @@ -3,6 +3,8 @@ package event import ( "sync/atomic" + "fortio.org/safecast" + "github.com/iotaledger/hive.go/lo" "github.com/iotaledger/hive.go/runtime/options" "github.com/iotaledger/hive.go/runtime/workerpool" @@ -50,12 +52,15 @@ func (t *triggerSettings) WasTriggered() bool { // TriggerCount returns the number of times Trigger was called. func (t *triggerSettings) TriggerCount() int { - return int(t.triggerCount.Load()) + v := safecast.MustConvert[int](t.triggerCount.Load()) + return v } // MaxTriggerCount returns the maximum number of times Trigger can be called. func (t *triggerSettings) MaxTriggerCount() int { - return int(t.maxTriggerCount) + v := safecast.MustConvert[int](t.maxTriggerCount) + + return v } // MaxTriggerCountReached returns true if the maximum number of times Trigger can be called was reached. diff --git a/runtime/go.mod b/runtime/go.mod index 4052953e..369a35c4 100644 --- a/runtime/go.mod +++ b/runtime/go.mod @@ -3,6 +3,7 @@ module github.com/iotaledger/hive.go/runtime go 1.22 require ( + fortio.org/safecast v1.0.0 github.com/fjl/memsize v0.0.2 github.com/iotaledger/hive.go/constraints v0.0.0-20240517131232-748f1ce3a2d2 github.com/iotaledger/hive.go/ds v0.0.0-20240517131232-748f1ce3a2d2 diff --git a/runtime/go.sum b/runtime/go.sum index e4b6fd56..a9e478d0 100644 --- a/runtime/go.sum +++ b/runtime/go.sum @@ -1,3 +1,5 @@ +fortio.org/safecast v1.0.0 h1:dr3131WPX8iS1pTf76+39WeXbTrerDYLvi9s7Oi3wiY= +fortio.org/safecast v1.0.0/go.mod h1:xZmcPk3vi4kuUFf+tq4SvnlVdwViqf6ZSZl91Jr9Jdg= github.com/btcsuite/btcd/btcec/v2 v2.2.1 h1:xP60mv8fvp+0khmrN0zTdPC3cNm24rfeE6lh2R/Yv3E= github.com/btcsuite/btcd/btcec/v2 v2.2.1/go.mod h1:9/CSmJxmuvqzX9Wh2fXMWToLOHhPd11lSPuIupwTkI8= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= From 22ab85d5896fd5f9d6231f5f163a7d6aafc0bcef Mon Sep 17 00:00:00 2001 From: cwarnerdev <138500512+cwarnerdev@users.noreply.github.com> Date: Tue, 8 Apr 2025 06:48:41 -1000 Subject: [PATCH 17/18] fix linter errors --- kvstore/go.mod | 1 + kvstore/go.sum | 2 ++ kvstore/mapdb/mapdb.go | 2 ++ kvstore/testutil/util.go | 20 ++++++++++---------- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/kvstore/go.mod b/kvstore/go.mod index 239ce73e..bd9577e3 100644 --- a/kvstore/go.mod +++ b/kvstore/go.mod @@ -3,6 +3,7 @@ module github.com/iotaledger/hive.go/kvstore go 1.22 require ( + fortio.org/safecast v1.0.0 github.com/iotaledger/grocksdb v1.7.5-0.20230220105546-5162e18885c7 github.com/iotaledger/hive.go/ds v0.0.0-20240517131232-748f1ce3a2d2 github.com/iotaledger/hive.go/ierrors v0.0.0-20240517131232-748f1ce3a2d2 diff --git a/kvstore/go.sum b/kvstore/go.sum index 04443f5a..dede6451 100644 --- a/kvstore/go.sum +++ b/kvstore/go.sum @@ -1,3 +1,5 @@ +fortio.org/safecast v1.0.0 h1:dr3131WPX8iS1pTf76+39WeXbTrerDYLvi9s7Oi3wiY= +fortio.org/safecast v1.0.0/go.mod h1:xZmcPk3vi4kuUFf+tq4SvnlVdwViqf6ZSZl91Jr9Jdg= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= diff --git a/kvstore/mapdb/mapdb.go b/kvstore/mapdb/mapdb.go index 6156a52e..9b54b92d 100644 --- a/kvstore/mapdb/mapdb.go +++ b/kvstore/mapdb/mapdb.go @@ -112,6 +112,7 @@ func (s *mapDB) Set(key kvstore.Key, value kvstore.Value) error { return s.set(key, value) } +//nolint:unparam // error is always nil func (s *mapDB) set(key kvstore.Key, value kvstore.Value) error { s.m.set(byteutils.ConcatBytes(s.realm, key), value) @@ -142,6 +143,7 @@ func (s *mapDB) Delete(key kvstore.Key) error { return s.delete(key) } +//nolint:unparam // error is always nil func (s *mapDB) delete(key kvstore.Key) error { s.m.delete(byteutils.ConcatBytes(s.realm, key)) diff --git a/kvstore/testutil/util.go b/kvstore/testutil/util.go index da98041f..34e23327 100644 --- a/kvstore/testutil/util.go +++ b/kvstore/testutil/util.go @@ -74,28 +74,28 @@ func RandString(length int) string { } // RandUint8 returns a random uint8. -func RandUint8(max uint8) uint8 { - return uint8(RandomInt31n(int32(max))) +func RandUint8(maximum uint8) uint8 { + return uint8(RandomInt31n(int32(maximum))) //nolint:gosec } // RandUint16 returns a random uint16. -func RandUint16(max uint16) uint16 { - return uint16(RandomInt31n(int32(max))) +func RandUint16(maximum uint16) uint16 { + return uint16(RandomInt31n(int32(maximum))) //nolint:gosec } // RandUint32 returns a random uint32. -func RandUint32(max uint32) uint32 { - return uint32(RandomInt63n(int64(max))) +func RandUint32(maximum uint32) uint32 { + return uint32(RandomInt63n(int64(maximum))) //nolint:gosec } // RandUint64 returns a random uint64. -func RandUint64(max uint64) uint64 { - return uint64(RandomInt63n(int64(uint32(max)))) +func RandUint64(maximum uint64) uint64 { + return uint64(RandomInt63n(int64(uint32(maximum)))) //nolint:gosec } // RandFloat64 returns a random float64. -func RandFloat64(max float64) float64 { - return RandomFloat64() * max +func RandFloat64(maximum float64) float64 { + return RandomFloat64() * maximum } // Rand32ByteArray returns an array with 32 random bytes. From 1f69c0acd8b8e0e0c721c2e9c704510cbd4aeed3 Mon Sep 17 00:00:00 2001 From: cwarnerdev <138500512+cwarnerdev@users.noreply.github.com> Date: Tue, 8 Apr 2025 07:01:49 -1000 Subject: [PATCH 18/18] fix typo --- core/safemath/safe_math.go | 1 - 1 file changed, 1 deletion(-) diff --git a/core/safemath/safe_math.go b/core/safemath/safe_math.go index 74f246ac..c4265b58 100644 --- a/core/safemath/safe_math.go +++ b/core/safemath/safe_math.go @@ -84,7 +84,6 @@ func SafeMulUint64(x, y uint64) (uint64, error) { // // According to benchmarks, this function is about 27% faster than SafeMul. // -//nolint:gosec // disable G115 - integer overlfows are checked manua //nolint:gosec // disable G115 - integer overlfows are checked manually func SafeMulInt64(x, y int64) (int64, error) { // This function stores the sign of the resulting int64 multiplication