diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index bab7875..8f310ce 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -7,17 +7,21 @@ on: permissions: contents: read + pull-requests: read jobs: golangci: name: lint runs-on: ubuntu-22.04 steps: - - uses: actions/setup-go@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 with: - go-version: '1.20' - - uses: actions/checkout@v3 + cache: false + go-version: '1.22' - name: golangci-lint - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@v5 with: - args: --timeout=60m + version: 'latest' + args: '--timeout=60m' + skip-cache: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7e84c05..fe19ffb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -44,12 +44,13 @@ jobs: needs: [create_release, env_vars] steps: - name: Set up Go - uses: actions/setup-go@v3 + - uses: actions/setup-go@v5 with: - go-version: '^1.20' + cache: false + go-version: '^1.22' - name: Check out repository into the Go module directory - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Select correct tag run: git checkout ${{ github.ref_name }} @@ -119,12 +120,13 @@ jobs: needs: [create_release, env_vars] steps: - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: - go-version: '^1.20' + cache: false + go-version: '^1.22' - name: Check out repository into the Go module directory - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Select correct tag run: git checkout ${{ github.ref_name }} @@ -164,12 +166,13 @@ jobs: needs: [create_release, env_vars] steps: - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: - go-version: '^1.20' + cache: false + go-version: '^1.22' - name: Check out repository into the Go module directory - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Select correct tag run: git checkout ${{ github.ref_name }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8917f10..3e09a13 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,8 +8,12 @@ jobs: test: runs-on: ubuntu-22.04 steps: - - uses: actions/setup-go@v3 + - uses: actions/setup-go@v5 with: - go-version: '1.20' - - uses: actions/checkout@v3 - - uses: n8maninger/action-golang-test@v1 + cache: false + go-version: '1.22' + - uses: actions/checkout@v4 + - uses: n8maninger/action-golang-test@v2 + with: + args: "-race;-timeout=30m" + diff --git a/.golangci.yml b/.golangci.yml index bd74379..3481cf6 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -132,13 +132,11 @@ linters: disable: - contextcheck - cyclop - - deadcode - depguard - dupl - err113 - execinquery - exhaustive - - exhaustivestruct - exhaustruct - forcetypeassert - funlen @@ -146,25 +144,17 @@ linters: - gochecknoglobals - gocognit - goconst - - golint - gomnd - - ifshort - - interfacer - ireturn - inamedparam - lll - - maligned - mnd - musttag - nestif - nilnil - nlreturn - - nosnakecase - perfsprint - promlinter - - scopelint - - structcheck - - varcheck - varnamelen - wrapcheck - wsl diff --git a/Dockerfile b/Dockerfile index c3e0d41..50e140d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.20-bookworm as builder +FROM golang:1.22-bookworm as builder WORKDIR /app diff --git a/go.mod b/go.mod index a2c2760..9efc5b1 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/wealdtech/chaind -go 1.20 +go 1.22 require ( github.com/attestantio/go-eth2-client v0.20.0 diff --git a/go.sum b/go.sum index 541ac15..b2cc5d5 100644 --- a/go.sum +++ b/go.sum @@ -31,6 +31,7 @@ cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+ cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= cloud.google.com/go v0.103.0/go.mod h1:vwLx1nqLrzLX/fpwSMOXmFIqBOyHsvHbnAdbGSJ+mKk= cloud.google.com/go v0.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM= +cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -99,6 +100,7 @@ github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 h1:7To3pQ+pZo0i3dsWEbinPNFs5gPSBOsJtx3wTT94VBY= +github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -116,6 +118,7 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go. github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= +github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= @@ -124,6 +127,7 @@ github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw github.com/ferranbt/fastssz v0.1.3 h1:ZI+z3JH05h4kgmFXdHuR1aWYsgrg7o+Fw7/NCzM16Mo= github.com/ferranbt/fastssz v0.1.3/go.mod h1:0Y9TEd/9XuFlh7mskMPfXiI2Dkw4Ddg9EyXt1W7MRvE= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -181,6 +185,7 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -198,6 +203,7 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -249,6 +255,7 @@ github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0Jr github.com/huandu/go-clone v1.7.2 h1:3+Aq0Ed8XK+zKkLjE2dfHg0XrpIfcohBE1K+c8Usxoo= github.com/huandu/go-clone v1.7.2/go.mod h1:ReGivhG6op3GYr+UY3lS6mxjKp7MIGTknuU5TbTVaXE= github.com/huandu/go-clone/generic v1.6.0 h1:Wgmt/fUZ28r16F2Y3APotFD59sHk1p78K0XLdbUYN5U= +github.com/huandu/go-clone/generic v1.6.0/go.mod h1:xgd9ZebcMsBWWcBx5mVMCoqMX24gLWr5lQicr+nVXNs= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= @@ -274,9 +281,11 @@ github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuV github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= @@ -323,6 +332,7 @@ github.com/r3labs/sse/v2 v2.10.0/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktE github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U= @@ -363,6 +373,7 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10 h1:CQh33pStIp/E30b7TxDlXfM0145bn2e8boI30IxAhTg= +github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10/go.mod h1:x/Pa0FF5Te9kdrlZKJK82YmAkvL8+f989USgz6Jiw7M= github.com/wealdtech/go-majordomo v1.1.1 h1:o+vS/akiT7zuufU7H+A6Cp52qbkjzaaMZlgwm/rciDk= github.com/wealdtech/go-majordomo v1.1.1/go.mod h1:qEuabaXiE3bazGgcTE4WIWYUXlLjHkwh3jGLmC1NOBs= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -402,6 +413,7 @@ go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7e go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -883,6 +895,7 @@ gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UD gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= diff --git a/services/blocks/standard/handler.go b/services/blocks/standard/handler.go index f83e0cb..a14bd9e 100644 --- a/services/blocks/standard/handler.go +++ b/services/blocks/standard/handler.go @@ -696,7 +696,7 @@ func (*Service) dbBlockBellatrix( // base fee per gas is stored little-endian but we need it // big-endian for big.Int. var baseFeePerGasBEBytes [32]byte - for i := 0; i < 32; i++ { + for i := range 32 { baseFeePerGasBEBytes[i] = block.Body.ExecutionPayload.BaseFeePerGas[32-1-i] } baseFeePerGas := new(big.Int).SetBytes(baseFeePerGasBEBytes[:]) @@ -757,7 +757,7 @@ func (*Service) dbBlockCapella( // base fee per gas is stored little-endian but we need it // big-endian for big.Int. var baseFeePerGasBEBytes [32]byte - for i := 0; i < 32; i++ { + for i := range 32 { baseFeePerGasBEBytes[i] = block.Body.ExecutionPayload.BaseFeePerGas[32-1-i] } baseFeePerGas := new(big.Int).SetBytes(baseFeePerGasBEBytes[:]) @@ -924,7 +924,7 @@ func (s *Service) dbAttestation( if len(committee.Committee) == int(attestation.AggregationBits.Len()) { aggregationIndices = make([]phase0.ValidatorIndex, 0, len(committee.Committee)) - for i := uint64(0); i < attestation.AggregationBits.Len(); i++ { + for i := range attestation.AggregationBits.Len() { if attestation.AggregationBits.BitAt(i) { aggregationIndices = append(aggregationIndices, committee.Committee[i]) } @@ -976,7 +976,7 @@ func (s *Service) dbSyncAggregate( } indices := make([]phase0.ValidatorIndex, 0, syncAggregate.SyncCommitteeBits.Count()) - for i := 0; i < int(syncAggregate.SyncCommitteeBits.Len()); i++ { + for i := range int(syncAggregate.SyncCommitteeBits.Len()) { if syncAggregate.SyncCommitteeBits.BitAt(uint64(i)) { indices = append(indices, syncCommittee.Committee[i]) } diff --git a/services/chaindb/postgresql/validators.go b/services/chaindb/postgresql/validators.go index e612edd..0e61848 100644 --- a/services/chaindb/postgresql/validators.go +++ b/services/chaindb/postgresql/validators.go @@ -631,7 +631,7 @@ func padValidatorBalances(validatorBalances map[phase0.ValidatorIndex][]*chaindb if len(balances) != entries { paddedBalances := make([]*chaindb.ValidatorBalance, entries) padding := entries - len(balances) - for i := 0; i < padding; i++ { + for i := range padding { paddedBalances[i] = &chaindb.ValidatorBalance{ Index: validatorIndex, Epoch: startEpoch + phase0.Epoch(i), diff --git a/services/scheduler/standard/service.go b/services/scheduler/standard/service.go index 3d666ca..a08ddcd 100644 --- a/services/scheduler/standard/service.go +++ b/services/scheduler/standard/service.go @@ -26,9 +26,6 @@ import ( "go.uber.org/atomic" ) -// module-wide log. -var log zerolog.Logger - // job contains control points for a job. type job struct { // stateLock is required for active or finalised. @@ -44,6 +41,7 @@ type job struct { // the state of each job, in an attempt to ensure additional robustness in the face // of high concurrent load. type Service struct { + log zerolog.Logger jobs map[string]*job jobsMutex deadlock.RWMutex } @@ -56,7 +54,7 @@ func New(ctx context.Context, params ...Parameter) (*Service, error) { } // Set logging. - log = zerologger.With().Str("service", "scheduler").Str("impl", "advanced").Logger() + log := zerologger.With().Str("service", "scheduler").Str("impl", "advanced").Logger() if parameters.logLevel != log.GetLevel() { log = log.Level(parameters.logLevel) } @@ -66,6 +64,7 @@ func New(ctx context.Context, params ...Parameter) (*Service, error) { } return &Service{ + log: log, jobs: make(map[string]*job), }, nil } @@ -100,45 +99,45 @@ func (s *Service) ScheduleJob(ctx context.Context, s.jobsMutex.Unlock() jobScheduled(class) - log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Scheduled job") + s.log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Scheduled job") go func() { select { case <-ctx.Done(): - log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Parent context done; job not running") + s.log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Parent context done; job not running") s.jobsMutex.Lock() delete(s.jobs, name) s.jobsMutex.Unlock() finaliseJob(job) jobCancelled(class) case <-job.cancelCh: - log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Cancel triggered; job not running") + s.log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Cancel triggered; job not running") // If we receive this signal the job has already been deleted from the jobs list so no need to // do so again here. finaliseJob(job) jobCancelled(class) case <-job.runCh: - log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Run triggered; job running") + s.log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Run triggered; job running") // If we receive this signal the job has already been deleted from the jobs list so no need to // do so again here. jobStartedOnSignal(class) jobFunc(ctx, data) - log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Job complete") + s.log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Job complete") finaliseJob(job) job.active.Store(false) case <-time.After(time.Until(runtime)): // It is possible that the job is already active, so check that first before proceeding. if job.active.Load() { - log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Already running; job not running") + s.log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Already running; job not running") break } s.jobsMutex.Lock() delete(s.jobs, name) s.jobsMutex.Unlock() - log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Timer triggered; job running") + s.log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Timer triggered; job running") job.active.Store(true) jobStartedOnTimer(class) jobFunc(ctx, data) - log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Job complete") + s.log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Job complete") job.active.Store(false) finaliseJob(job) } @@ -188,7 +187,7 @@ func (s *Service) SchedulePeriodicJob(ctx context.Context, for { runtime, err := runtimeFunc(ctx, runtimeData) if errors.Is(err, scheduler.ErrNoMoreInstances) { - log.Trace().Str("job", name).Msg("No more instances; period job stopping") + s.log.Trace().Str("job", name).Msg("No more instances; period job stopping") s.jobsMutex.Lock() delete(s.jobs, name) s.jobsMutex.Unlock() @@ -197,7 +196,7 @@ func (s *Service) SchedulePeriodicJob(ctx context.Context, return } if err != nil { - log.Error().Str("job", name).Err(err).Msg("Failed to obtain runtime; periodic job stopping") + s.log.Error().Str("job", name).Err(err).Msg("Failed to obtain runtime; periodic job stopping") s.jobsMutex.Lock() delete(s.jobs, name) s.jobsMutex.Unlock() @@ -205,10 +204,10 @@ func (s *Service) SchedulePeriodicJob(ctx context.Context, jobCancelled(class) return } - log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Scheduled job") + s.log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Scheduled job") select { case <-ctx.Done(): - log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Parent context done; job not running") + s.log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Parent context done; job not running") s.jobsMutex.Lock() delete(s.jobs, name) s.jobsMutex.Unlock() @@ -216,26 +215,26 @@ func (s *Service) SchedulePeriodicJob(ctx context.Context, jobCancelled(class) return case <-job.cancelCh: - log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Cancel triggered; job not running") + s.log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Cancel triggered; job not running") finaliseJob(job) jobCancelled(class) return case <-job.runCh: - log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Run triggered; job running") + s.log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Run triggered; job running") jobStartedOnSignal(class) jobFunc(ctx, jobData) - log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Job complete") + s.log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Job complete") job.active.Store(false) case <-time.After(time.Until(runtime)): if job.active.Load() { - log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Already running; job not running") + s.log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Already running; job not running") continue } job.active.Store(true) - log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Timer triggered; job running") + s.log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Timer triggered; job running") jobStartedOnTimer(class) jobFunc(ctx, jobData) - log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Job complete") + s.log.Trace().Str("job", name).Time("scheduled", runtime).Msg("Job complete") job.active.Store(false) } } diff --git a/services/scheduler/standard/service_test.go b/services/scheduler/standard/service_test.go index 2563b45..b9152ff 100644 --- a/services/scheduler/standard/service_test.go +++ b/services/scheduler/standard/service_test.go @@ -69,15 +69,15 @@ func TestJob(t *testing.T) { require.NoError(t, err) require.NotNil(t, s) - run := 0 + run := uint32(0) runFunc := func(ctx context.Context, data any) { - run++ + atomic.AddUint32(&run, 1) } require.NoError(t, s.ScheduleJob(ctx, "Test", "Test job", time.Now().Add(20*time.Millisecond), runFunc, nil)) - require.Equal(t, 0, run) + require.Equal(t, uint32(0), atomic.LoadUint32(&run)) time.Sleep(time.Duration(50) * time.Millisecond) - assert.Equal(t, 1, run) + assert.Equal(t, uint32(1), atomic.LoadUint32(&run)) require.Len(t, s.ListJobs(ctx), 0) } @@ -87,9 +87,9 @@ func TestJobExists(t *testing.T) { require.NoError(t, err) require.NotNil(t, s) - run := 0 + run := uint32(0) runFunc := func(ctx context.Context, data any) { - run++ + atomic.AddUint32(&run, 1) } require.NoError(t, s.ScheduleJob(ctx, "Test", "Test job", time.Now().Add(10*time.Second), runFunc, nil)) @@ -108,18 +108,18 @@ func TestCancelJob(t *testing.T) { require.NoError(t, err) require.NotNil(t, s) - run := 0 + run := uint32(0) runFunc := func(ctx context.Context, data any) { - run++ + atomic.AddUint32(&run, 1) } require.NoError(t, s.ScheduleJob(ctx, "Test", "Test job", time.Now().Add(100*time.Millisecond), runFunc, nil)) - require.Equal(t, 0, run) + require.Equal(t, uint32(0), atomic.LoadUint32(&run)) require.Len(t, s.ListJobs(ctx), 1) require.NoError(t, s.CancelJob(ctx, "Test job")) require.Len(t, s.ListJobs(ctx), 0) time.Sleep(time.Duration(110) * time.Millisecond) - assert.Equal(t, 0, run) + require.Equal(t, uint32(0), atomic.LoadUint32(&run)) } func TestCancelUnknownJob(t *testing.T) { @@ -137,20 +137,20 @@ func TestCancelJobs(t *testing.T) { require.NoError(t, err) require.NotNil(t, s) - run := 0 + run := uint32(0) runFunc := func(ctx context.Context, data any) { - run++ + atomic.AddUint32(&run, 1) } require.NoError(t, s.ScheduleJob(ctx, "Test", "Test job 1", time.Now().Add(100*time.Millisecond), runFunc, nil)) require.NoError(t, s.ScheduleJob(ctx, "Test", "Test job 2", time.Now().Add(100*time.Millisecond), runFunc, nil)) require.NoError(t, s.ScheduleJob(ctx, "Test", "No cancel job", time.Now().Add(100*time.Millisecond), runFunc, nil)) - require.Equal(t, 0, run) + require.Equal(t, uint32(0), atomic.LoadUint32(&run)) require.Len(t, s.ListJobs(ctx), 3) s.CancelJobs(ctx, "Test job") require.Len(t, s.ListJobs(ctx), 1) time.Sleep(time.Duration(110) * time.Millisecond) - assert.Equal(t, 1, run) + require.Equal(t, uint32(1), atomic.LoadUint32(&run)) require.Len(t, s.ListJobs(ctx), 0) } @@ -160,18 +160,18 @@ func TestCancelJobIfExists(t *testing.T) { require.NoError(t, err) require.NotNil(t, s) - run := 0 + run := uint32(0) runFunc := func(ctx context.Context, data any) { - run++ + atomic.AddUint32(&run, 1) } require.NoError(t, s.ScheduleJob(ctx, "Test", "Test job", time.Now().Add(100*time.Millisecond), runFunc, nil)) - require.Equal(t, 0, run) + require.Equal(t, uint32(0), atomic.LoadUint32(&run)) require.Len(t, s.ListJobs(ctx), 1) s.CancelJobIfExists(ctx, "Test job") require.Len(t, s.ListJobs(ctx), 0) time.Sleep(time.Duration(110) * time.Millisecond) - assert.Equal(t, 0, run) + require.Equal(t, uint32(0), atomic.LoadUint32(&run)) s.CancelJobIfExists(ctx, "Unknown job") } @@ -182,18 +182,18 @@ func TestCancelParentContext(t *testing.T) { require.NoError(t, err) require.NotNil(t, s) - run := 0 + run := uint32(0) runFunc := func(ctx context.Context, data any) { - run++ + atomic.AddUint32(&run, 1) } require.NoError(t, s.ScheduleJob(ctx, "Test", "Test job", time.Now().Add(100*time.Millisecond), runFunc, nil)) require.Len(t, s.ListJobs(ctx), 1) - require.Equal(t, 0, run) + require.Equal(t, uint32(0), atomic.LoadUint32(&run)) cancel() time.Sleep(time.Duration(110) * time.Millisecond) require.Len(t, s.ListJobs(ctx), 0) - assert.Equal(t, 0, run) + require.Equal(t, uint32(0), atomic.LoadUint32(&run)) } func TestRunJob(t *testing.T) { @@ -202,17 +202,17 @@ func TestRunJob(t *testing.T) { require.NoError(t, err) require.NotNil(t, s) - run := 0 + run := uint32(0) runFunc := func(ctx context.Context, data any) { - run++ + atomic.AddUint32(&run, 1) } require.NoError(t, s.ScheduleJob(ctx, "Test", "Test job", time.Now().Add(time.Second), runFunc, nil)) require.Len(t, s.ListJobs(ctx), 1) - require.Equal(t, 0, run) + require.Equal(t, uint32(0), atomic.LoadUint32(&run)) require.NoError(t, s.RunJob(ctx, "Test job")) time.Sleep(time.Duration(100) * time.Millisecond) - assert.Equal(t, 1, run) + require.Equal(t, uint32(1), atomic.LoadUint32(&run)) require.Len(t, s.ListJobs(ctx), 0) } @@ -222,18 +222,18 @@ func TestRunJobIfExists(t *testing.T) { require.NoError(t, err) require.NotNil(t, s) - run := 0 + run := uint32(0) runFunc := func(ctx context.Context, data any) { - run++ + atomic.AddUint32(&run, 1) } require.NoError(t, s.ScheduleJob(ctx, "Test", "Test job", time.Now().Add(time.Second), runFunc, nil)) - require.Equal(t, 0, run) + require.Equal(t, uint32(0), atomic.LoadUint32(&run)) s.RunJobIfExists(ctx, "Unknown job") - require.Equal(t, 0, run) + require.Equal(t, uint32(0), atomic.LoadUint32(&run)) s.RunJobIfExists(ctx, "Test job") time.Sleep(time.Duration(100) * time.Millisecond) - assert.Equal(t, 1, run) + require.Equal(t, uint32(1), atomic.LoadUint32(&run)) } func TestRunUnknownJob(t *testing.T) { @@ -251,9 +251,9 @@ func TestPeriodicJob(t *testing.T) { require.NoError(t, err) require.NotNil(t, s) - run := 0 + run := uint32(0) runFunc := func(ctx context.Context, data any) { - run++ + atomic.AddUint32(&run, 1) } runtimeFunc := func(ctx context.Context, data any) (time.Time, error) { @@ -262,14 +262,14 @@ func TestPeriodicJob(t *testing.T) { require.NoError(t, s.SchedulePeriodicJob(ctx, "Test", "Test periodic job", runtimeFunc, nil, runFunc, nil)) require.Len(t, s.ListJobs(ctx), 1) - require.Equal(t, 0, run) + require.Equal(t, uint32(0), atomic.LoadUint32(&run)) time.Sleep(time.Duration(110) * time.Millisecond) - assert.Equal(t, 1, run) + require.Equal(t, uint32(1), atomic.LoadUint32(&run)) time.Sleep(time.Duration(110) * time.Millisecond) - assert.Equal(t, 2, run) + require.Equal(t, uint32(2), atomic.LoadUint32(&run)) require.NoError(t, s.RunJob(ctx, "Test periodic job")) time.Sleep(time.Duration(10) * time.Millisecond) - assert.Equal(t, 3, run) + require.Equal(t, uint32(3), atomic.LoadUint32(&run)) require.Len(t, s.ListJobs(ctx), 1) require.NoError(t, s.CancelJob(ctx, "Test periodic job")) @@ -282,9 +282,9 @@ func TestCancelPeriodicJob(t *testing.T) { require.NoError(t, err) require.NotNil(t, s) - run := 0 + run := uint32(0) runFunc := func(ctx context.Context, data any) { - run++ + atomic.AddUint32(&run, 1) } runtimeFunc := func(ctx context.Context, data any) (time.Time, error) { @@ -293,10 +293,10 @@ func TestCancelPeriodicJob(t *testing.T) { require.NoError(t, s.SchedulePeriodicJob(ctx, "Test", "Test periodic job", runtimeFunc, nil, runFunc, nil)) require.Len(t, s.ListJobs(ctx), 1) - require.Equal(t, 0, run) + require.Equal(t, uint32(0), atomic.LoadUint32(&run)) require.NoError(t, s.CancelJob(ctx, "Test periodic job")) time.Sleep(time.Duration(110) * time.Millisecond) - assert.Equal(t, 0, run) + require.Equal(t, uint32(0), atomic.LoadUint32(&run)) require.Len(t, s.ListJobs(ctx), 0) } @@ -306,9 +306,9 @@ func TestCancelPeriodicParentContext(t *testing.T) { require.NoError(t, err) require.NotNil(t, s) - run := 0 + run := uint32(0) runFunc := func(ctx context.Context, data any) { - run++ + atomic.AddUint32(&run, 1) } runtimeFunc := func(ctx context.Context, data any) (time.Time, error) { @@ -317,10 +317,10 @@ func TestCancelPeriodicParentContext(t *testing.T) { require.NoError(t, s.SchedulePeriodicJob(ctx, "Test", "Test job", runtimeFunc, nil, runFunc, nil)) require.Len(t, s.ListJobs(ctx), 1) - require.Equal(t, 0, run) + require.Equal(t, uint32(0), atomic.LoadUint32(&run)) cancel() time.Sleep(time.Duration(110) * time.Millisecond) - assert.Equal(t, 0, run) + require.Equal(t, uint32(0), atomic.LoadUint32(&run)) require.Len(t, s.ListJobs(ctx), 0) } @@ -330,9 +330,9 @@ func TestLimitedPeriodicJob(t *testing.T) { require.NoError(t, err) require.NotNil(t, s) - run := 0 + run := uint32(0) runFunc := func(ctx context.Context, data any) { - run++ + atomic.AddUint32(&run, 1) } runtimeFunc := func(ctx context.Context, data any) (time.Time, error) { @@ -344,9 +344,9 @@ func TestLimitedPeriodicJob(t *testing.T) { require.NoError(t, s.SchedulePeriodicJob(ctx, "Test", "Test job", runtimeFunc, nil, runFunc, nil)) require.Len(t, s.ListJobs(ctx), 1) - require.Equal(t, 0, run) + require.Equal(t, uint32(0), atomic.LoadUint32(&run)) time.Sleep(time.Duration(50) * time.Millisecond) - assert.Equal(t, 3, run) + require.Equal(t, uint32(3), atomic.LoadUint32(&run)) require.Len(t, s.ListJobs(ctx), 0) } @@ -356,9 +356,9 @@ func TestBadPeriodicJob(t *testing.T) { require.NoError(t, err) require.NotNil(t, s) - run := 0 + run := uint32(0) runFunc := func(ctx context.Context, data any) { - run++ + atomic.AddUint32(&run, 1) } runtimeFunc := func(ctx context.Context, data any) (time.Time, error) { @@ -370,9 +370,9 @@ func TestBadPeriodicJob(t *testing.T) { require.NoError(t, s.SchedulePeriodicJob(ctx, "Test", "Test job", runtimeFunc, nil, runFunc, nil)) require.Len(t, s.ListJobs(ctx), 1) - require.Equal(t, 0, run) + require.Equal(t, uint32(0), atomic.LoadUint32(&run)) time.Sleep(time.Duration(50) * time.Millisecond) - assert.Equal(t, 3, run) + require.Equal(t, uint32(3), atomic.LoadUint32(&run)) require.Len(t, s.ListJobs(ctx), 0) } @@ -382,9 +382,9 @@ func TestDuplicateJobName(t *testing.T) { require.NoError(t, err) require.NotNil(t, s) - run := 0 + run := uint32(0) runFunc := func(ctx context.Context, data any) { - run++ + atomic.AddUint32(&run, 1) } runtimeFunc := func(ctx context.Context, data any) (time.Time, error) { @@ -413,9 +413,9 @@ func TestBadJobs(t *testing.T) { require.NoError(t, err) require.NotNil(t, s) - run := 0 + run := uint32(0) runFunc := func(ctx context.Context, data any) { - run++ + atomic.AddUint32(&run, 1) } runtimeFunc := func(ctx context.Context, data any) (time.Time, error) { @@ -466,7 +466,7 @@ func TestManyJobs(t *testing.T) { // Sleep to let the others run normally. time.Sleep(400 * time.Millisecond) - require.Equal(t, uint32(jobs), run) + require.Equal(t, uint32(jobs), atomic.LoadUint32(&run)) require.Len(t, s.ListJobs(ctx), 0) } @@ -476,9 +476,9 @@ func TestListJobs(t *testing.T) { require.NoError(t, err) require.NotNil(t, s) - run := 0 + run := uint32(0) runFunc := func(ctx context.Context, data any) { - run++ + atomic.AddUint32(&run, 1) } jobs := s.ListJobs(ctx) @@ -528,7 +528,7 @@ func TestLongRunningPeriodicJob(t *testing.T) { // Sleep for 400 ms. Expect two runs (50+100+50+100+50). time.Sleep(400 * time.Millisecond) - assert.Equal(t, uint32(2), run) + require.Equal(t, uint32(2), atomic.LoadUint32(&run)) require.Len(t, s.ListJobs(ctx), 1) require.NoError(t, s.CancelJob(ctx, "Test long running periodic job")) @@ -557,7 +557,7 @@ func TestOverlappingJobs(t *testing.T) { time.Sleep(500 * time.Millisecond) // Ensure both jobs have completed. - require.Equal(t, uint32(2), run) + require.Equal(t, uint32(2), atomic.LoadUint32(&run)) require.Len(t, s.ListJobs(ctx), 0) } @@ -599,7 +599,7 @@ func TestMulti(t *testing.T) { runWG.Wait() // Ensure the job has only completed once. - require.Equal(t, uint32(1), run) + require.Equal(t, uint32(1), atomic.LoadUint32(&run)) require.Len(t, s.ListJobs(ctx), 0) } @@ -609,10 +609,10 @@ func TestCancelWhilstRunning(t *testing.T) { require.NoError(t, err) require.NotNil(t, s) - run := 0 + run := uint32(0) runFunc := func(ctx context.Context, data any) { time.Sleep(50 * time.Millisecond) - run++ + atomic.AddUint32(&run, 1) } runtimeFunc := func(ctx context.Context, data any) (time.Time, error) { @@ -623,16 +623,16 @@ func TestCancelWhilstRunning(t *testing.T) { require.NoError(t, s.SchedulePeriodicJob(ctx, "Test", "Test periodic job", runtimeFunc, nil, runFunc, nil)) require.Len(t, s.ListJobs(ctx), 1) require.Contains(t, s.ListJobs(ctx), "Test periodic job") - require.Equal(t, 0, run) + require.Equal(t, uint32(0), atomic.LoadUint32(&run)) time.Sleep(time.Duration(60) * time.Millisecond) - require.Equal(t, 0, run) + require.Equal(t, uint32(0), atomic.LoadUint32(&run)) // Cancel occurs during first run. require.NoError(t, s.CancelJob(ctx, "Test periodic job")) require.Len(t, s.ListJobs(ctx), 0) // Wait for first run to finish. time.Sleep(time.Duration(60) * time.Millisecond) - assert.Equal(t, 1, run) + require.Equal(t, uint32(1), atomic.LoadUint32(&run)) // Ensure second run never happens. time.Sleep(time.Duration(120) * time.Millisecond) - assert.Equal(t, 1, run) + require.Equal(t, uint32(1), atomic.LoadUint32(&run)) } diff --git a/services/summarizer/standard/validatorday.go b/services/summarizer/standard/validatorday.go index 3186e0c..4e792be 100644 --- a/services/summarizer/standard/validatorday.go +++ b/services/summarizer/standard/validatorday.go @@ -379,7 +379,7 @@ func (s *Service) syncCommitteeSummary(ctx context.Context, } aggregateBits := bitfield.Bitlist(aggregate.Bits) - for i := uint64(0); i < aggregateBits.Len(); i++ { + for i := range aggregateBits.Len() { if _, exists := res[syncCommittee[i]]; !exists { res[syncCommittee[i]] = &scSummary{} }