diff --git a/.github/workflows/build-test-release.yml b/.github/workflows/build-test-release.yml index a6f43578..c4865745 100644 --- a/.github/workflows/build-test-release.yml +++ b/.github/workflows/build-test-release.yml @@ -19,7 +19,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.17 + go-version: 1.18 - name: Run unit tests shell: bash run: scripts/tests.unit.sh @@ -28,7 +28,7 @@ jobs: run: scripts/tests.integration.sh - name: Run e2e tests shell: bash - run: E2E=true scripts/run.sh 1.7.17 + run: E2E=true scripts/run.sh 1.8.0 env: E2E: true - name: Run GoReleaser for cross-platform builds diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 8f8120a6..10c62a7f 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -27,7 +27,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.17 + go-version: 1.18 - name: Run static analysis tests shell: bash run: scripts/tests.lint.sh diff --git a/go.mod b/go.mod index 3c8af8f7..a8c51fe3 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,11 @@ module github.com/ava-labs/spacesvm -go 1.17 +go 1.18 require ( github.com/ava-labs/avalanche-network-runner-sdk v0.1.0 - github.com/ava-labs/avalanchego v1.7.17 - github.com/ethereum/go-ethereum v1.10.20 + github.com/ava-labs/avalanchego v1.8.0 + github.com/ethereum/go-ethereum v1.10.23 github.com/fatih/color v1.13.0 github.com/golang/mock v1.6.0 github.com/gorilla/rpc v1.2.0 @@ -31,7 +31,6 @@ require ( github.com/hashicorp/go-plugin v1.4.4 // indirect github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect - github.com/linxGnu/grocksdb v1.6.34 // indirect github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect @@ -56,12 +55,13 @@ require ( go.uber.org/zap v1.21.0 // indirect golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect golang.org/x/net v0.0.0-20220708220712-1185a9018129 // indirect + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect golang.org/x/text v0.3.7 // indirect gonum.org/v1/gonum v0.11.0 // indirect google.golang.org/genproto v0.0.0-20220712132514-bdd2acd4974d // indirect - google.golang.org/grpc v1.48.0 // indirect + google.golang.org/grpc v1.49.0 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 87585946..79e27329 100644 --- a/go.sum +++ b/go.sum @@ -64,8 +64,8 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/ava-labs/avalanche-network-runner-sdk v0.1.0 h1:m35SkmT7OO0cxrnqHCtQ0v8BHsDw8EZmo+yjH0DTqIs= github.com/ava-labs/avalanche-network-runner-sdk v0.1.0/go.mod h1:1oDcmKg7Ed2QN3uxl6r5FqMsZMSAsGVBtI4ra0ewW/A= -github.com/ava-labs/avalanchego v1.7.17 h1:+Kafk8GaveL/J97yiw+DDtt8TaLWDsyrB61p/QTiEuU= -github.com/ava-labs/avalanchego v1.7.17/go.mod h1:PDJudeWWz4IXxexK95XRMuziAv6XPpMPbCHGwwlzNfw= +github.com/ava-labs/avalanchego v1.8.0 h1:rQrK6YzIMqjaZ9YQbL1TcbUwzFdTeMXGqzynEB+w8bE= +github.com/ava-labs/avalanchego v1.8.0/go.mod h1:KzMGQZ77xkTVxkxl/zGH3aIGjaHnGbuPTycxkcjngIc= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -121,8 +121,8 @@ github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPO 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 v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= -github.com/ethereum/go-ethereum v1.10.20 h1:75IW830ClSS40yrQC1ZCMZCt5I+zU16oqId2SiQwdQ4= -github.com/ethereum/go-ethereum v1.10.20/go.mod h1:LWUN82TCHGpxB3En5HVmLLzPD7YSrEUFmFfN1nKkVN0= +github.com/ethereum/go-ethereum v1.10.23 h1:Xk8XAT4/UuqcjMLIMF+7imjkg32kfVFKoeyQDaO2yWM= +github.com/ethereum/go-ethereum v1.10.23/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= @@ -301,8 +301,6 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/linxGnu/grocksdb v1.6.34 h1:fHNRbWepGN1zA4FFt/9LuiOPtSxDsr8mn4/RlU5+g1Q= -github.com/linxGnu/grocksdb v1.6.34/go.mod h1:/+iSQrn7Izt6kFhHBQvcE6FkklsKXa8hc35pFyFDrDw= github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -591,6 +589,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -887,8 +886,8 @@ google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= -google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.49.0 h1:WTLtQzmQori5FUH25Pq4WT22oCsv8USpQ+F6rqtsmxw= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/scripts/tests.lint.sh b/scripts/tests.lint.sh index 38d6018e..68fd97c4 100755 --- a/scripts/tests.lint.sh +++ b/scripts/tests.lint.sh @@ -25,7 +25,7 @@ TESTS=${TESTS:-"golangci_lint license_header"} # https://github.com/golangci/golangci-lint/releases function test_golangci_lint { - go install -v github.com/golangci/golangci-lint/cmd/golangci-lint@v1.43.0 + go install -v github.com/golangci/golangci-lint/cmd/golangci-lint@v1.47.3 golangci-lint run --config .golangci.yml } diff --git a/utils/timer/staged_timer.go b/utils/timer/staged_timer.go new file mode 100644 index 00000000..c807f8f3 --- /dev/null +++ b/utils/timer/staged_timer.go @@ -0,0 +1,20 @@ +// Copyright (C) 2019-2021, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package timer + +import "time" + +// NewStagedTimer returns a timer that will execute [f] +// when a timeout occurs and execute an additional timeout after +// the returned duration if [f] returns true and some duration. +func NewStagedTimer(f func() (time.Duration, bool)) *Timer { + t := NewTimer(nil) + t.handler = func() { + delay, repeat := f() + if repeat { + t.SetTimeoutIn(delay) + } + } + return t +} diff --git a/utils/timer/staged_timer_test.go b/utils/timer/staged_timer_test.go new file mode 100644 index 00000000..98b0160f --- /dev/null +++ b/utils/timer/staged_timer_test.go @@ -0,0 +1,47 @@ +// Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package timer + +import ( + "sync" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestSingleStagedTimer(t *testing.T) { + wg := sync.WaitGroup{} + wg.Add(1) + ticks := 1 + i := 0 + timer := NewStagedTimer(func() (time.Duration, bool) { + defer wg.Done() + i++ + return 0, false + }) + go timer.Dispatch() + + timer.SetTimeoutIn(time.Millisecond) + wg.Wait() + require.Equal(t, i, ticks) +} + +func TestMultiStageTimer(t *testing.T) { + wg := sync.WaitGroup{} + ticks := 3 + wg.Add(ticks) + + i := 0 + timer := NewStagedTimer(func() (time.Duration, bool) { + defer wg.Done() + i++ + return time.Millisecond, i < ticks + }) + go timer.Dispatch() + + timer.SetTimeoutIn(time.Millisecond) + wg.Wait() + require.Equal(t, i, ticks) +} diff --git a/utils/timer/timer.go b/utils/timer/timer.go new file mode 100644 index 00000000..45292ab4 --- /dev/null +++ b/utils/timer/timer.go @@ -0,0 +1,108 @@ +// Copyright (C) 2019-2021, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package timer + +import ( + "sync" + "time" +) + +// Timer wraps a timer object. This allows a user to specify a handler. Once +// specifying the handler, the dispatch thread can be called. The dispatcher +// will only return after calling Stop. SetTimeoutIn will result in calling the +// handler in the specified amount of time. +type Timer struct { + handler func() + timeout chan struct{} + + lock sync.Mutex + wg sync.WaitGroup + finished, shouldExecute bool + duration time.Duration +} + +// NewTimer creates a new timer object +func NewTimer(handler func()) *Timer { + timer := &Timer{ + handler: handler, + timeout: make(chan struct{}, 1), + } + timer.wg.Add(1) + + return timer +} + +// SetTimeoutIn will set the timer to fire the handler in [duration] +func (t *Timer) SetTimeoutIn(duration time.Duration) { + t.lock.Lock() + defer t.lock.Unlock() + + t.duration = duration + t.shouldExecute = true + t.reset() +} + +// Cancel the currently scheduled event +func (t *Timer) Cancel() { + t.lock.Lock() + defer t.lock.Unlock() + + t.shouldExecute = false + t.reset() +} + +// Stop this timer from executing any more. +func (t *Timer) Stop() { + t.lock.Lock() + if !t.finished { + defer t.wg.Wait() + } + defer t.lock.Unlock() + + t.finished = true + t.reset() +} + +func (t *Timer) Dispatch() { + t.lock.Lock() + defer t.lock.Unlock() + defer t.wg.Done() + + timer := time.NewTimer(0) + cleared := false + reset := false + for !t.finished { // t.finished needs to be thread safe + if !reset && !timer.Stop() && !cleared { + <-timer.C + } + + if cleared && t.shouldExecute { + t.lock.Unlock() + t.handler() + } else { + t.lock.Unlock() + } + + cleared = false + reset = false + select { + case <-t.timeout: + t.lock.Lock() + if t.shouldExecute { + timer.Reset(t.duration) + } + reset = true + case <-timer.C: + t.lock.Lock() + cleared = true + } + } +} + +func (t *Timer) reset() { + select { + case t.timeout <- struct{}{}: + default: + } +} diff --git a/utils/timer/timer_test.go b/utils/timer/timer_test.go new file mode 100644 index 00000000..d3e049e2 --- /dev/null +++ b/utils/timer/timer_test.go @@ -0,0 +1,21 @@ +// Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package timer + +import ( + "sync" + "testing" + "time" +) + +func TestTimer(t *testing.T) { + wg := sync.WaitGroup{} + wg.Add(1) + defer wg.Wait() + + timer := NewTimer(wg.Done) + go timer.Dispatch() + + timer.SetTimeoutIn(time.Millisecond) +} diff --git a/vm/block_builder.go b/vm/block_builder.go index 011505ca..4033df50 100644 --- a/vm/block_builder.go +++ b/vm/block_builder.go @@ -8,7 +8,7 @@ import ( "time" "github.com/ava-labs/avalanchego/snow/engine/common" - "github.com/ava-labs/avalanchego/utils/timer" + "github.com/ava-labs/spacesvm/utils/timer" log "github.com/inconshreveable/log15" )