Skip to content

Commit 0f26890

Browse files
feat: add retry with exp. backoff to all RPC network calls (#148)
This PR adds retry logic to all RPC network calls. It relies on the avast/retry-go library, and is configured with the following parameters: * delays: [0.5s, 2s, 8s, 32s] * attempts: 5 * timeout of each network call: 30s In addition, the PR "fixes" the semantic of the is{Operation,Ready,Pending,Done} methods. Previously, they would return false in case of a network error -- which naturally let to unexpected behavior in the core event handling logic. Now, we return (bool, error) and the calling code properly handles the network failures. -- Test coverage is low due to (1) the complexity of mocking the failed calls on a code base that was not designed with a clear separation between i/o and business logic and (2) the short lifespan of changes to the timelock-worker service, which should be deprecated soon. To compensate, I spent a significant amount of time running local manual tests, trying to validate all failure scenarios.
1 parent a29e8b1 commit 0f26890

File tree

10 files changed

+1108
-115
lines changed

10 files changed

+1108
-115
lines changed

.mockery.yaml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Mockery configuration file
2+
3+
# All interfaces in a package are generated by default. You can set this to false in the config of
4+
# of each package to disable this behavior.
5+
all: false
6+
with-expecter: true
7+
# The name of the mock file to be generated is the snake cased interface name.
8+
filename: "{{.InterfaceName | snakecase | lower}}.go"
9+
# Creates the mocks in a `mocks` dir inside the package containing the interfaces.
10+
dir: "{{.InterfaceDir}}/mocks"
11+
# The name of the mock struct is the interface name.
12+
mockname: "{{.InterfaceName}}"
13+
# Places the mock package in the same package as the interface.
14+
outpkg: "mocks"
15+
packages:
16+
github.com/ethereum/go-ethereum/accounts/abi/bind:
17+
interfaces:
18+
ContractBackend:
19+
config:
20+
# inpackage: false
21+
filename: "{{.InterfaceName | snakecase}}.go"
22+
# mockname: "{{.InterfaceName}}"
23+
dir: "./pkg/timelock/mocks"

.tool-versions

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
golang 1.22.9
22
golangci-lint 1.62.0
3-
task 3.40.0
3+
task 3.40.0
4+
mockery 2.50.0

go.mod

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/smartcontractkit/timelock-worker
33
go 1.22
44

55
require (
6+
github.com/avast/retry-go/v4 v4.6.1
67
github.com/docker/go-connections v0.5.0
78
github.com/ethereum/go-ethereum v1.13.15
89
github.com/google/go-cmp v0.6.0
@@ -12,7 +13,7 @@ require (
1213
github.com/smartcontractkit/chain-selectors v1.0.17
1314
github.com/spf13/cobra v1.8.1
1415
github.com/spf13/viper v1.19.0
15-
github.com/stretchr/testify v1.9.0
16+
github.com/stretchr/testify v1.10.0
1617
github.com/testcontainers/testcontainers-go v0.34.0
1718
go.uber.org/zap v1.27.0
1819
)
@@ -116,6 +117,7 @@ require (
116117
github.com/spf13/cast v1.6.0 // indirect
117118
github.com/spf13/pflag v1.0.5 // indirect
118119
github.com/status-im/keycard-go v0.2.0 // indirect
120+
github.com/stretchr/objx v0.5.2 // indirect
119121
github.com/subosito/gotenv v1.6.0 // indirect
120122
github.com/supranational/blst v0.3.11 // indirect
121123
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect

go.sum

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY
2424
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
2525
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
2626
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
27+
github.com/avast/retry-go/v4 v4.6.1 h1:VkOLRubHdisGrHnTu89g08aQEWEgRU7LVEop3GbIcMk=
28+
github.com/avast/retry-go/v4 v4.6.1/go.mod h1:V6oF8njAwxJ5gRo1Q7Cxab24xs5NCWZBeaHHBklR8mA=
2729
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
2830
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
2931
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
@@ -425,8 +427,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
425427
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
426428
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
427429
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
428-
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
429430
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
431+
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
432+
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
430433
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
431434
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
432435
github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4=

pkg/timelock/const.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const (
1313

1414
fieldTXHash string = "TX Hash"
1515
fieldBlockNumber string = "Block Number"
16+
operationID string = "Operation ID"
1617

1718
logPath string = "/tmp/"
1819
logFile string = "timelock-worker.log"

0 commit comments

Comments
 (0)