diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a79f2e547..f9bbf5fe1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ jobs: - name: Install Go uses: actions/setup-go@v2.1.3 with: - go-version: 1.15.5 + go-version: 1.17 - name: "Build binaries" run: make all - name: "Run tests" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 000000000..cd00815aa --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,18 @@ +name: Lint Check + +on: [pull_request] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install Go + uses: actions/setup-go@v2.1.3 + with: + go-version: 1.17 + - name: "Run lint" + uses: golangci/golangci-lint-action@v3 + with: + version: v1.41 + args: --timeout=10m + only-new-issues: true \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml index 18b325e20..32bdec5b1 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -32,6 +32,7 @@ linters-settings: min-occurrences: 6 # minimum number of occurrences issues: + new: true exclude-rules: - path: crypto/blake2b/ linters: diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index c91900afa..da76ea943 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -118,6 +118,9 @@ var ( // errOutOfRangeChain is returned if an authorization list is attempted to // be modified via out-of-range or non-contiguous headers. errOutOfRangeChain = errors.New("out of range or non-contiguous chain") + + // errShutdownDetected is returned if a shutdown signal is detected + errShutdownDetected = errors.New("shutdown detected") ) // SignerFn is a signer callback function to request a header to be signed by a @@ -888,6 +891,11 @@ func (c *Bor) APIs(chain consensus.ChainHeaderReader) []rpc.API { }} } +// StopClient implements consensus.Engine. It will close any information fetching client before closing engine. +func (c *Bor) StopClient() { + c.HeimdallClient.Close() +} + // Close implements consensus.Engine. It's a noop for bor as there are no background threads. func (c *Bor) Close() error { return nil @@ -1137,6 +1145,9 @@ func (c *Bor) CommitStates( "fromID", lastStateID+1, "to", to.Format(time.RFC3339)) eventRecords, err := c.HeimdallClient.FetchStateSyncEvents(lastStateID+1, to.Unix()) + if err != nil { + return nil, err + } if c.config.OverrideStateSyncRecords != nil { if val, ok := c.config.OverrideStateSyncRecords[strconv.FormatUint(number, 10)]; ok { if val < len(eventRecords) { diff --git a/consensus/bor/rest.go b/consensus/bor/rest.go index 4408c1c41..6c3adde8f 100644 --- a/consensus/bor/rest.go +++ b/consensus/bor/rest.go @@ -27,11 +27,13 @@ type IHeimdallClient interface { Fetch(path string, query string) (*ResponseWithHeight, error) FetchWithRetry(path string, query string) (*ResponseWithHeight, error) FetchStateSyncEvents(fromID uint64, to int64) ([]*EventRecordWithTime, error) + Close() } type HeimdallClient struct { urlString string client http.Client + closeCh chan struct{} } func NewHeimdallClient(urlString string) (*HeimdallClient, error) { @@ -40,10 +42,16 @@ func NewHeimdallClient(urlString string) (*HeimdallClient, error) { client: http.Client{ Timeout: time.Duration(5 * time.Second), }, + closeCh: make(chan struct{}), } return h, nil } +func (h *HeimdallClient) Close() { + close(h.closeCh) + h.client.CloseIdleConnections() +} + func (h *HeimdallClient) FetchStateSyncEvents(fromID uint64, to int64) ([]*EventRecordWithTime, error) { eventRecords := make([]*EventRecordWithTime, 0) for { @@ -96,13 +104,29 @@ func (h *HeimdallClient) FetchWithRetry(rawPath string, rawQuery string) (*Respo u.Path = rawPath u.RawQuery = rawQuery + retryCount := 1 + res, err := h.internalFetch(u) + if err == nil && res != nil { + return res, nil + } + + retryTicker := time.NewTicker(5 * time.Second) + defer retryTicker.Stop() + for { - res, err := h.internalFetch(u) - if err == nil && res != nil { - return res, nil + select { + case <-h.closeCh: + log.Info("Shutdown detected, heimdall client terminates request") + return nil, errShutdownDetected + + case <-retryTicker.C: + log.Info("Retrying again in 5 seconds to fetch Heimdall data", "path", u.Path, "retryCount", retryCount) + retryCount += 1 + res, err := h.internalFetch(u) + if err == nil && res != nil { + return res, nil + } } - log.Info("Retrying again in 5 seconds for next Heimdall span", "path", u.Path) - time.Sleep(5 * time.Second) } } diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index 449095e72..700a3771e 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -690,6 +690,9 @@ func (c *Clique) SealHash(header *types.Header) common.Hash { return SealHash(header) } +// StopClient implements consensus.Engine. It will close any information fetching client before closing engine. +func (c *Clique) StopClient() {} + // Close implements consensus.Engine. It's a noop for clique as there are no background threads. func (c *Clique) Close() error { return nil diff --git a/consensus/consensus.go b/consensus/consensus.go index 2a5aac945..5ef1d511c 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -114,6 +114,10 @@ type Engine interface { // APIs returns the RPC APIs this consensus engine provides. APIs(chain ChainHeaderReader) []rpc.API + // StopClient terminates any background client maintained by the consensus engine. + // It is used to release resources related with information fetching. + StopClient() + // Close terminates any background threads maintained by the consensus engine. Close() error } diff --git a/consensus/ethash/ethash.go b/consensus/ethash/ethash.go index ec06d02a5..6fe670aad 100644 --- a/consensus/ethash/ethash.go +++ b/consensus/ethash/ethash.go @@ -544,6 +544,8 @@ func NewShared() *Ethash { return &Ethash{shared: sharedEthash} } +func (ethhash *Ethash) StopClient() {} + // Close closes the exit channel to notify all backend threads exiting. func (ethash *Ethash) Close() error { ethash.closeOnce.Do(func() { diff --git a/eth/backend.go b/eth/backend.go index fbe293723..273fe9fa5 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -576,15 +576,19 @@ func (s *Ethereum) Stop() error { // Stop all the peer-related stuff first. s.ethDialCandidates.Close() s.snapDialCandidates.Close() + + s.engine.StopClient() s.handler.Stop() // Then stop everything else. s.bloomIndexer.Close() close(s.closeBloomHandler) + s.txPool.Stop() s.miner.Stop() s.blockchain.Stop() s.engine.Close() + rawdb.PopUncleanShutdownMarker(s.chainDb) s.chainDb.Close() s.eventMux.Stop() diff --git a/go.mod b/go.mod index 56b0a97fd..cf82bb549 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,9 @@ module github.com/ethereum/go-ethereum -go 1.15 +go 1.17 require ( - github.com/Azure/azure-pipeline-go v0.2.2 // indirect github.com/Azure/azure-storage-blob-go v0.7.0 - github.com/Azure/go-autorest/autorest/adal v0.8.0 // indirect - github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect github.com/VictoriaMetrics/fastcache v1.6.0 github.com/aws/aws-sdk-go-v2 v1.2.0 github.com/aws/aws-sdk-go-v2/config v1.1.1 @@ -18,16 +15,12 @@ require ( github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f github.com/davecgh/go-spew v1.1.1 github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea - github.com/deepmap/oapi-codegen v1.8.2 // indirect - github.com/dlclark/regexp2 v1.2.0 // indirect github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498 github.com/edsrzf/mmap-go v1.0.0 github.com/fatih/color v1.7.0 github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff - github.com/go-ole/go-ole v1.2.1 // indirect - github.com/go-sourcemap/sourcemap v2.1.2+incompatible // indirect github.com/go-stack/stack v1.8.0 github.com/golang/protobuf v1.4.3 github.com/golang/snappy v0.0.4 @@ -41,15 +34,12 @@ require ( github.com/huin/goupnp v1.0.2 github.com/influxdata/influxdb v1.8.3 github.com/influxdata/influxdb-client-go/v2 v2.4.0 - github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e github.com/julienschmidt/httprouter v1.2.0 github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356 - github.com/kylelemons/godebug v1.1.0 // indirect github.com/mattn/go-colorable v0.1.8 github.com/mattn/go-isatty v0.0.12 - github.com/naoina/go-stringutil v0.1.0 // indirect github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 github.com/olekukonko/tablewriter v0.0.5 github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 @@ -60,11 +50,9 @@ require ( github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 github.com/stretchr/testify v1.7.0 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 - github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef github.com/xsleonard/go-merkle v1.1.0 golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 - golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912 golang.org/x/text v0.3.6 @@ -72,6 +60,37 @@ require ( gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 gopkg.in/urfave/cli.v1 v1.20.0 +) + +require ( + github.com/Azure/azure-pipeline-go v0.2.2 // indirect + github.com/Azure/go-autorest/autorest/adal v0.8.0 // indirect + github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.1.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.1.1 // indirect + github.com/aws/smithy-go v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/deepmap/oapi-codegen v1.8.2 // indirect + github.com/dlclark/regexp2 v1.2.0 // indirect + github.com/go-ole/go-ole v1.2.1 // indirect + github.com/go-sourcemap/sourcemap v2.1.2+incompatible // indirect + github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/naoina/go-stringutil v0.1.0 // indirect + github.com/opentracing/opentracing-go v1.1.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/objx v0.1.1 // indirect + github.com/tklauser/go-sysconf v0.3.5 // indirect + github.com/tklauser/numcpus v0.2.2 // indirect + golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d // indirect + golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect + google.golang.org/protobuf v1.23.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect gotest.tools v2.2.0+incompatible // indirect ) diff --git a/go.sum b/go.sum index bf559c270..9b317fdea 100644 --- a/go.sum +++ b/go.sum @@ -33,7 +33,6 @@ github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSW github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc= github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= @@ -407,7 +406,6 @@ github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPyS github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xsleonard/go-merkle v1.1.0 h1:fHe1fuhJjGH22ZzVTAH0jqHLhTGhOq3wQjJN+8P0jQg= github.com/xsleonard/go-merkle v1.1.0/go.mod h1:cW4z+UZ/4f2n9IJgIiyDCdYguchoDyDAPmpuOWGxdGg= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= diff --git a/params/version.go b/params/version.go index e7e206f92..a98604026 100644 --- a/params/version.go +++ b/params/version.go @@ -23,7 +23,7 @@ import ( const ( VersionMajor = 1 // Major version component of the current release VersionMinor = 0 // Minor version component of the current release - VersionPatch = 4 // Patch version component of the current release + VersionPatch = 5 // Patch version component of the current release VersionMeta = "stable" // Version metadata to append to the version string ) diff --git a/tests/bor/mocks/IHeimdallClient.go b/tests/bor/mocks/IHeimdallClient.go index d69b90862..b40bc8c43 100644 --- a/tests/bor/mocks/IHeimdallClient.go +++ b/tests/bor/mocks/IHeimdallClient.go @@ -80,3 +80,5 @@ func (_m *IHeimdallClient) FetchWithRetry(path string, query string) (*bor.Respo return r0, r1 } + +func(_m *IHeimdallClient) Close() {}