Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
ed73f1f7
Commit
ed73f1f7
authored
Sep 14, 2023
by
Felipe Andrade
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(proxyd): high availability
parent
1ce16570
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
416 additions
and
60 deletions
+416
-60
backend.go
proxyd/backend.go
+2
-2
cache.go
proxyd/cache.go
+2
-2
config.go
proxyd/config.go
+4
-0
consensus_poller.go
proxyd/consensus_poller.go
+18
-16
consensus_tracker.go
proxyd/consensus_tracker.go
+211
-25
frontend_rate_limiter.go
proxyd/frontend_rate_limiter.go
+1
-1
frontend_rate_limiter_test.go
proxyd/frontend_rate_limiter_test.go
+1
-1
go.mod
proxyd/go.mod
+5
-2
go.sum
proxyd/go.sum
+102
-1
methods.go
proxyd/methods.go
+2
-2
metrics.go
proxyd/metrics.go
+40
-1
proxyd.go
proxyd/proxyd.go
+22
-1
redis.go
proxyd/redis.go
+1
-1
server.go
proxyd/server.go
+5
-5
No files found.
proxyd/backend.go
View file @
ed73f1f7
...
@@ -630,7 +630,7 @@ func (b *Backend) ErrorRate() (errorRate float64) {
...
@@ -630,7 +630,7 @@ func (b *Backend) ErrorRate() (errorRate float64) {
return
errorRate
return
errorRate
}
}
// IsDegraded checks if the backend is serving traffic in a degraded
state
(i.e. used as a last resource)
// IsDegraded checks if the backend is serving traffic in a degraded
local
(i.e. used as a last resource)
func
(
b
*
Backend
)
IsDegraded
()
bool
{
func
(
b
*
Backend
)
IsDegraded
()
bool
{
avgLatency
:=
time
.
Duration
(
b
.
latencySlidingWindow
.
Avg
())
avgLatency
:=
time
.
Duration
(
b
.
latencySlidingWindow
.
Avg
())
return
avgLatency
>=
b
.
maxDegradedLatencyThreshold
return
avgLatency
>=
b
.
maxDegradedLatencyThreshold
...
@@ -677,7 +677,7 @@ func (bg *BackendGroup) Forward(ctx context.Context, rpcReqs []*RPCReq, isBatch
...
@@ -677,7 +677,7 @@ func (bg *BackendGroup) Forward(ctx context.Context, rpcReqs []*RPCReq, isBatch
if
bg
.
Consensus
!=
nil
{
if
bg
.
Consensus
!=
nil
{
// When `consensus_aware` is set to `true`, the backend group acts as a load balancer
// When `consensus_aware` is set to `true`, the backend group acts as a load balancer
// serving traffic
from
any backend that agrees in the consensus group
// serving traffic
update
any backend that agrees in the consensus group
backends
=
bg
.
loadBalancedConsensusGroup
()
backends
=
bg
.
loadBalancedConsensusGroup
()
// We also rewrite block tags to enforce compliance with consensus
// We also rewrite block tags to enforce compliance with consensus
...
...
proxyd/cache.go
View file @
ed73f1f7
...
@@ -7,8 +7,8 @@ import (
...
@@ -7,8 +7,8 @@ import (
"time"
"time"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/rpc"
"github.com/redis/go-redis/v9"
"github.com/go-redis/redis/v8"
"github.com/golang/snappy"
"github.com/golang/snappy"
lru
"github.com/hashicorp/golang-lru"
lru
"github.com/hashicorp/golang-lru"
)
)
...
@@ -78,7 +78,7 @@ func (c *redisCache) Get(ctx context.Context, key string) (string, error) {
...
@@ -78,7 +78,7 @@ func (c *redisCache) Get(ctx context.Context, key string) (string, error) {
func
(
c
*
redisCache
)
Put
(
ctx
context
.
Context
,
key
string
,
value
string
)
error
{
func
(
c
*
redisCache
)
Put
(
ctx
context
.
Context
,
key
string
,
value
string
)
error
{
start
:=
time
.
Now
()
start
:=
time
.
Now
()
err
:=
c
.
rdb
.
SetE
X
(
ctx
,
c
.
namespaced
(
key
),
value
,
redisTTL
)
.
Err
()
err
:=
c
.
rdb
.
SetE
x
(
ctx
,
c
.
namespaced
(
key
),
value
,
redisTTL
)
.
Err
()
redisCacheDurationSumm
.
WithLabelValues
(
"SETEX"
)
.
Observe
(
float64
(
time
.
Since
(
start
)
.
Milliseconds
()))
redisCacheDurationSumm
.
WithLabelValues
(
"SETEX"
)
.
Observe
(
float64
(
time
.
Since
(
start
)
.
Milliseconds
()))
if
err
!=
nil
{
if
err
!=
nil
{
...
...
proxyd/config.go
View file @
ed73f1f7
...
@@ -110,6 +110,10 @@ type BackendGroupConfig struct {
...
@@ -110,6 +110,10 @@ type BackendGroupConfig struct {
ConsensusMaxBlockLag
uint64
`toml:"consensus_max_block_lag"`
ConsensusMaxBlockLag
uint64
`toml:"consensus_max_block_lag"`
ConsensusMaxBlockRange
uint64
`toml:"consensus_max_block_range"`
ConsensusMaxBlockRange
uint64
`toml:"consensus_max_block_range"`
ConsensusMinPeerCount
int
`toml:"consensus_min_peer_count"`
ConsensusMinPeerCount
int
`toml:"consensus_min_peer_count"`
ConsensusHA
bool
`toml:"consensus_ha"`
ConsensusHAHeartbeatInterval
TOMLDuration
`toml:"consensus_ha_heartbeat_interval"`
ConsensusHALockPeriod
TOMLDuration
`toml:"consensus_ha_lock_period"`
}
}
type
BackendGroupsConfig
map
[
string
]
*
BackendGroupConfig
type
BackendGroupsConfig
map
[
string
]
*
BackendGroupConfig
...
...
proxyd/consensus_poller.go
View file @
ed73f1f7
...
@@ -19,10 +19,11 @@ const (
...
@@ -19,10 +19,11 @@ const (
type
OnConsensusBroken
func
()
type
OnConsensusBroken
func
()
// ConsensusPoller checks the consensus
state
for each member of a BackendGroup
// ConsensusPoller checks the consensus
local
for each member of a BackendGroup
// resolves the highest common block for multiple nodes, and reconciles the consensus
// resolves the highest common block for multiple nodes, and reconciles the consensus
// in case of block hash divergence to minimize re-orgs
// in case of block hash divergence to minimize re-orgs
type
ConsensusPoller
struct
{
type
ConsensusPoller
struct
{
ctx
context
.
Context
cancelFunc
context
.
CancelFunc
cancelFunc
context
.
CancelFunc
listeners
[]
OnConsensusBroken
listeners
[]
OnConsensusBroken
...
@@ -220,6 +221,7 @@ func NewConsensusPoller(bg *BackendGroup, opts ...ConsensusOpt) *ConsensusPoller
...
@@ -220,6 +221,7 @@ func NewConsensusPoller(bg *BackendGroup, opts ...ConsensusOpt) *ConsensusPoller
state
:=
make
(
map
[
*
Backend
]
*
backendState
,
len
(
bg
.
Backends
))
state
:=
make
(
map
[
*
Backend
]
*
backendState
,
len
(
bg
.
Backends
))
cp
:=
&
ConsensusPoller
{
cp
:=
&
ConsensusPoller
{
ctx
:
ctx
,
cancelFunc
:
cancelFunc
,
cancelFunc
:
cancelFunc
,
backendGroup
:
bg
,
backendGroup
:
bg
,
backendState
:
state
,
backendState
:
state
,
...
@@ -248,7 +250,7 @@ func NewConsensusPoller(bg *BackendGroup, opts ...ConsensusOpt) *ConsensusPoller
...
@@ -248,7 +250,7 @@ func NewConsensusPoller(bg *BackendGroup, opts ...ConsensusOpt) *ConsensusPoller
return
cp
return
cp
}
}
// UpdateBackend refreshes the consensus
state
of a single backend
// UpdateBackend refreshes the consensus
local
of a single backend
func
(
cp
*
ConsensusPoller
)
UpdateBackend
(
ctx
context
.
Context
,
be
*
Backend
)
{
func
(
cp
*
ConsensusPoller
)
UpdateBackend
(
ctx
context
.
Context
,
be
*
Backend
)
{
bs
:=
cp
.
getBackendState
(
be
)
bs
:=
cp
.
getBackendState
(
be
)
RecordConsensusBackendBanned
(
be
,
bs
.
IsBanned
())
RecordConsensusBackendBanned
(
be
,
bs
.
IsBanned
())
...
@@ -258,7 +260,7 @@ func (cp *ConsensusPoller) UpdateBackend(ctx context.Context, be *Backend) {
...
@@ -258,7 +260,7 @@ func (cp *ConsensusPoller) UpdateBackend(ctx context.Context, be *Backend) {
return
return
}
}
// if backend is not healthy
state
we'll only resume checking it after ban
// if backend is not healthy
local
we'll only resume checking it after ban
if
!
be
.
IsHealthy
()
{
if
!
be
.
IsHealthy
()
{
log
.
Warn
(
"backend banned - not healthy"
,
"backend"
,
be
.
Name
)
log
.
Warn
(
"backend banned - not healthy"
,
"backend"
,
be
.
Name
)
cp
.
Ban
(
be
)
cp
.
Ban
(
be
)
...
@@ -268,7 +270,7 @@ func (cp *ConsensusPoller) UpdateBackend(ctx context.Context, be *Backend) {
...
@@ -268,7 +270,7 @@ func (cp *ConsensusPoller) UpdateBackend(ctx context.Context, be *Backend) {
inSync
,
err
:=
cp
.
isInSync
(
ctx
,
be
)
inSync
,
err
:=
cp
.
isInSync
(
ctx
,
be
)
RecordConsensusBackendInSync
(
be
,
err
==
nil
&&
inSync
)
RecordConsensusBackendInSync
(
be
,
err
==
nil
&&
inSync
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Warn
(
"error updating backend sync
state
"
,
"name"
,
be
.
Name
,
"err"
,
err
)
log
.
Warn
(
"error updating backend sync
local
"
,
"name"
,
be
.
Name
,
"err"
,
err
)
}
}
var
peerCount
uint64
var
peerCount
uint64
...
@@ -306,7 +308,7 @@ func (cp *ConsensusPoller) UpdateBackend(ctx context.Context, be *Backend) {
...
@@ -306,7 +308,7 @@ func (cp *ConsensusPoller) UpdateBackend(ctx context.Context, be *Backend) {
RecordBackendFinalizedBlock
(
be
,
finalizedBlockNumber
)
RecordBackendFinalizedBlock
(
be
,
finalizedBlockNumber
)
if
changed
{
if
changed
{
log
.
Debug
(
"backend
state
updated"
,
log
.
Debug
(
"backend
local
updated"
,
"name"
,
be
.
Name
,
"name"
,
be
.
Name
,
"peerCount"
,
peerCount
,
"peerCount"
,
peerCount
,
"inSync"
,
inSync
,
"inSync"
,
inSync
,
...
@@ -352,9 +354,9 @@ func (cp *ConsensusPoller) checkExpectedBlockTags(
...
@@ -352,9 +354,9 @@ func (cp *ConsensusPoller) checkExpectedBlockTags(
currentSafe
<=
currentLatest
currentSafe
<=
currentLatest
}
}
// UpdateBackendGroupConsensus resolves the current group consensus based on the
state
of the backends
// UpdateBackendGroupConsensus resolves the current group consensus based on the
local
of the backends
func
(
cp
*
ConsensusPoller
)
UpdateBackendGroupConsensus
(
ctx
context
.
Context
)
{
func
(
cp
*
ConsensusPoller
)
UpdateBackendGroupConsensus
(
ctx
context
.
Context
)
{
// get the latest block number
from
the tracker
// get the latest block number
update
the tracker
currentConsensusBlockNumber
:=
cp
.
GetLatestBlockNumber
()
currentConsensusBlockNumber
:=
cp
.
GetLatestBlockNumber
()
// get the candidates for the consensus group
// get the candidates for the consensus group
...
@@ -472,7 +474,7 @@ func (cp *ConsensusPoller) UpdateBackendGroupConsensus(ctx context.Context) {
...
@@ -472,7 +474,7 @@ func (cp *ConsensusPoller) UpdateBackendGroupConsensus(ctx context.Context) {
RecordGroupConsensusFilteredCount
(
cp
.
backendGroup
,
len
(
filteredBackendsNames
))
RecordGroupConsensusFilteredCount
(
cp
.
backendGroup
,
len
(
filteredBackendsNames
))
RecordGroupTotalCount
(
cp
.
backendGroup
,
len
(
cp
.
backendGroup
.
Backends
))
RecordGroupTotalCount
(
cp
.
backendGroup
,
len
(
cp
.
backendGroup
.
Backends
))
log
.
Debug
(
"group
state
"
,
log
.
Debug
(
"group
local
"
,
"proposedBlock"
,
proposedBlock
,
"proposedBlock"
,
proposedBlock
,
"consensusBackends"
,
strings
.
Join
(
consensusBackendsNames
,
", "
),
"consensusBackends"
,
strings
.
Join
(
consensusBackendsNames
,
", "
),
"filteredBackends"
,
strings
.
Join
(
filteredBackendsNames
,
", "
))
"filteredBackends"
,
strings
.
Join
(
filteredBackendsNames
,
", "
))
...
@@ -493,13 +495,13 @@ func (cp *ConsensusPoller) Ban(be *Backend) {
...
@@ -493,13 +495,13 @@ func (cp *ConsensusPoller) Ban(be *Backend) {
bs
.
backendStateMux
.
Lock
()
bs
.
backendStateMux
.
Lock
()
bs
.
bannedUntil
=
time
.
Now
()
.
Add
(
cp
.
banPeriod
)
bs
.
bannedUntil
=
time
.
Now
()
.
Add
(
cp
.
banPeriod
)
// when we ban a node, we give it the chance to start
from
any block when it is back
// when we ban a node, we give it the chance to start
update
any block when it is back
bs
.
latestBlockNumber
=
0
bs
.
latestBlockNumber
=
0
bs
.
safeBlockNumber
=
0
bs
.
safeBlockNumber
=
0
bs
.
finalizedBlockNumber
=
0
bs
.
finalizedBlockNumber
=
0
}
}
// Unban removes any bans
from
the backends
// Unban removes any bans
update
the backends
func
(
cp
*
ConsensusPoller
)
Unban
(
be
*
Backend
)
{
func
(
cp
*
ConsensusPoller
)
Unban
(
be
*
Backend
)
{
bs
:=
cp
.
backendState
[
be
]
bs
:=
cp
.
backendState
[
be
]
defer
bs
.
backendStateMux
.
Unlock
()
defer
bs
.
backendStateMux
.
Unlock
()
...
@@ -514,7 +516,7 @@ func (cp *ConsensusPoller) Reset() {
...
@@ -514,7 +516,7 @@ func (cp *ConsensusPoller) Reset() {
}
}
}
}
// fetchBlock is a convenient wrapper to make a request to get a block directly
from
the backend
// fetchBlock is a convenient wrapper to make a request to get a block directly
update
the backend
func
(
cp
*
ConsensusPoller
)
fetchBlock
(
ctx
context
.
Context
,
be
*
Backend
,
block
string
)
(
blockNumber
hexutil
.
Uint64
,
blockHash
string
,
err
error
)
{
func
(
cp
*
ConsensusPoller
)
fetchBlock
(
ctx
context
.
Context
,
be
*
Backend
,
block
string
)
(
blockNumber
hexutil
.
Uint64
,
blockHash
string
,
err
error
)
{
var
rpcRes
RPCRes
var
rpcRes
RPCRes
err
=
be
.
ForwardRPC
(
ctx
,
&
rpcRes
,
"67"
,
"eth_getBlockByNumber"
,
block
,
false
)
err
=
be
.
ForwardRPC
(
ctx
,
&
rpcRes
,
"67"
,
"eth_getBlockByNumber"
,
block
,
false
)
...
@@ -532,7 +534,7 @@ func (cp *ConsensusPoller) fetchBlock(ctx context.Context, be *Backend, block st
...
@@ -532,7 +534,7 @@ func (cp *ConsensusPoller) fetchBlock(ctx context.Context, be *Backend, block st
return
return
}
}
// getPeerCount is a convenient wrapper to retrieve the current peer count
from
the backend
// getPeerCount is a convenient wrapper to retrieve the current peer count
update
the backend
func
(
cp
*
ConsensusPoller
)
getPeerCount
(
ctx
context
.
Context
,
be
*
Backend
)
(
count
uint64
,
err
error
)
{
func
(
cp
*
ConsensusPoller
)
getPeerCount
(
ctx
context
.
Context
,
be
*
Backend
)
(
count
uint64
,
err
error
)
{
var
rpcRes
RPCRes
var
rpcRes
RPCRes
err
=
be
.
ForwardRPC
(
ctx
,
&
rpcRes
,
"67"
,
"net_peerCount"
)
err
=
be
.
ForwardRPC
(
ctx
,
&
rpcRes
,
"67"
,
"net_peerCount"
)
...
@@ -550,7 +552,7 @@ func (cp *ConsensusPoller) getPeerCount(ctx context.Context, be *Backend) (count
...
@@ -550,7 +552,7 @@ func (cp *ConsensusPoller) getPeerCount(ctx context.Context, be *Backend) (count
return
count
,
nil
return
count
,
nil
}
}
// isInSync is a convenient wrapper to check if the backend is in sync
from
the network
// isInSync is a convenient wrapper to check if the backend is in sync
update
the network
func
(
cp
*
ConsensusPoller
)
isInSync
(
ctx
context
.
Context
,
be
*
Backend
)
(
result
bool
,
err
error
)
{
func
(
cp
*
ConsensusPoller
)
isInSync
(
ctx
context
.
Context
,
be
*
Backend
)
(
result
bool
,
err
error
)
{
var
rpcRes
RPCRes
var
rpcRes
RPCRes
err
=
be
.
ForwardRPC
(
ctx
,
&
rpcRes
,
"67"
,
"eth_syncing"
)
err
=
be
.
ForwardRPC
(
ctx
,
&
rpcRes
,
"67"
,
"eth_syncing"
)
...
@@ -577,7 +579,7 @@ func (cp *ConsensusPoller) isInSync(ctx context.Context, be *Backend) (result bo
...
@@ -577,7 +579,7 @@ func (cp *ConsensusPoller) isInSync(ctx context.Context, be *Backend) (result bo
return
res
,
nil
return
res
,
nil
}
}
// getBackendState creates a copy of backend
state
so that the caller can use it without locking
// getBackendState creates a copy of backend
local
so that the caller can use it without locking
func
(
cp
*
ConsensusPoller
)
getBackendState
(
be
*
Backend
)
*
backendState
{
func
(
cp
*
ConsensusPoller
)
getBackendState
(
be
*
Backend
)
*
backendState
{
bs
:=
cp
.
backendState
[
be
]
bs
:=
cp
.
backendState
[
be
]
defer
bs
.
backendStateMux
.
Unlock
()
defer
bs
.
backendStateMux
.
Unlock
()
...
@@ -614,7 +616,7 @@ func (cp *ConsensusPoller) setBackendState(be *Backend, peerCount uint64, inSync
...
@@ -614,7 +616,7 @@ func (cp *ConsensusPoller) setBackendState(be *Backend, peerCount uint64, inSync
}
}
// getConsensusCandidates find out what backends are the candidates to be in the consensus group
// getConsensusCandidates find out what backends are the candidates to be in the consensus group
// and create a copy of current their
state
// and create a copy of current their
local
//
//
// a candidate is a serving node within the following conditions:
// a candidate is a serving node within the following conditions:
// - not banned
// - not banned
...
@@ -668,7 +670,7 @@ func (cp *ConsensusPoller) getConsensusCandidates() map[*Backend]*backendState {
...
@@ -668,7 +670,7 @@ func (cp *ConsensusPoller) getConsensusCandidates() map[*Backend]*backendState {
}
}
}
}
// remove lagging backends
from
the candidates
// remove lagging backends
update
the candidates
for
_
,
be
:=
range
lagging
{
for
_
,
be
:=
range
lagging
{
delete
(
candidates
,
be
)
delete
(
candidates
,
be
)
}
}
...
...
proxyd/consensus_tracker.go
View file @
ed73f1f7
...
@@ -2,12 +2,17 @@ package proxyd
...
@@ -2,12 +2,17 @@ package proxyd
import
(
import
(
"context"
"context"
"encoding/json"
"fmt"
"fmt"
"os"
"sync"
"sync"
"time"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/log"
"github.com/go-redis/redis/v8"
"github.com/go-redsync/redsync/v4"
"github.com/go-redsync/redsync/v4/redis/goredis/v9"
"github.com/redis/go-redis/v9"
)
)
// ConsensusTracker abstracts how we store and retrieve the current consensus
// ConsensusTracker abstracts how we store and retrieve the current consensus
...
@@ -21,17 +26,29 @@ type ConsensusTracker interface {
...
@@ -21,17 +26,29 @@ type ConsensusTracker interface {
SetFinalizedBlockNumber
(
blockNumber
hexutil
.
Uint64
)
SetFinalizedBlockNumber
(
blockNumber
hexutil
.
Uint64
)
}
}
// DTO to hold the current consensus state
type
ConsensusTrackerState
struct
{
Latest
hexutil
.
Uint64
`json:"latest"`
Safe
hexutil
.
Uint64
`json:"safe"`
Finalized
hexutil
.
Uint64
`json:"finalized"`
}
func
(
s
*
ConsensusTrackerState
)
update
(
o
*
ConsensusTrackerState
)
{
s
.
Latest
=
o
.
Latest
s
.
Safe
=
o
.
Safe
s
.
Finalized
=
o
.
Finalized
}
// InMemoryConsensusTracker store and retrieve in memory, async-safe
// InMemoryConsensusTracker store and retrieve in memory, async-safe
type
InMemoryConsensusTracker
struct
{
type
InMemoryConsensusTracker
struct
{
latestBlockNumber
hexutil
.
Uint64
mutex
sync
.
Mutex
safeBlockNumber
hexutil
.
Uint64
state
*
ConsensusTrackerState
finalizedBlockNumber
hexutil
.
Uint64
mutex
sync
.
Mutex
}
}
func
NewInMemoryConsensusTracker
()
ConsensusTracker
{
func
NewInMemoryConsensusTracker
()
ConsensusTracker
{
return
&
InMemoryConsensusTracker
{
return
&
InMemoryConsensusTracker
{
mutex
:
sync
.
Mutex
{},
mutex
:
sync
.
Mutex
{},
state
:
&
ConsensusTrackerState
{},
}
}
}
}
...
@@ -39,83 +56,252 @@ func (ct *InMemoryConsensusTracker) GetLatestBlockNumber() hexutil.Uint64 {
...
@@ -39,83 +56,252 @@ func (ct *InMemoryConsensusTracker) GetLatestBlockNumber() hexutil.Uint64 {
defer
ct
.
mutex
.
Unlock
()
defer
ct
.
mutex
.
Unlock
()
ct
.
mutex
.
Lock
()
ct
.
mutex
.
Lock
()
return
ct
.
latestBlockNumber
return
ct
.
state
.
Latest
}
}
func
(
ct
*
InMemoryConsensusTracker
)
SetLatestBlockNumber
(
blockNumber
hexutil
.
Uint64
)
{
func
(
ct
*
InMemoryConsensusTracker
)
SetLatestBlockNumber
(
blockNumber
hexutil
.
Uint64
)
{
defer
ct
.
mutex
.
Unlock
()
defer
ct
.
mutex
.
Unlock
()
ct
.
mutex
.
Lock
()
ct
.
mutex
.
Lock
()
ct
.
latestBlockNumber
=
blockNumber
ct
.
state
.
Latest
=
blockNumber
}
}
func
(
ct
*
InMemoryConsensusTracker
)
GetSafeBlockNumber
()
hexutil
.
Uint64
{
func
(
ct
*
InMemoryConsensusTracker
)
GetSafeBlockNumber
()
hexutil
.
Uint64
{
defer
ct
.
mutex
.
Unlock
()
defer
ct
.
mutex
.
Unlock
()
ct
.
mutex
.
Lock
()
ct
.
mutex
.
Lock
()
return
ct
.
s
afeBlockNumber
return
ct
.
s
tate
.
Safe
}
}
func
(
ct
*
InMemoryConsensusTracker
)
SetSafeBlockNumber
(
blockNumber
hexutil
.
Uint64
)
{
func
(
ct
*
InMemoryConsensusTracker
)
SetSafeBlockNumber
(
blockNumber
hexutil
.
Uint64
)
{
defer
ct
.
mutex
.
Unlock
()
defer
ct
.
mutex
.
Unlock
()
ct
.
mutex
.
Lock
()
ct
.
mutex
.
Lock
()
ct
.
s
afeBlockNumber
=
blockNumber
ct
.
s
tate
.
Safe
=
blockNumber
}
}
func
(
ct
*
InMemoryConsensusTracker
)
GetFinalizedBlockNumber
()
hexutil
.
Uint64
{
func
(
ct
*
InMemoryConsensusTracker
)
GetFinalizedBlockNumber
()
hexutil
.
Uint64
{
defer
ct
.
mutex
.
Unlock
()
defer
ct
.
mutex
.
Unlock
()
ct
.
mutex
.
Lock
()
ct
.
mutex
.
Lock
()
return
ct
.
finalizedBlockNumber
return
ct
.
state
.
Finalized
}
}
func
(
ct
*
InMemoryConsensusTracker
)
SetFinalizedBlockNumber
(
blockNumber
hexutil
.
Uint64
)
{
func
(
ct
*
InMemoryConsensusTracker
)
SetFinalizedBlockNumber
(
blockNumber
hexutil
.
Uint64
)
{
defer
ct
.
mutex
.
Unlock
()
defer
ct
.
mutex
.
Unlock
()
ct
.
mutex
.
Lock
()
ct
.
mutex
.
Lock
()
ct
.
finalizedBlockNumber
=
blockNumber
ct
.
state
.
Finalized
=
blockNumber
}
}
// RedisConsensusTracker
uses a Redis `client` to store and retrieve consensus, async-safe
// RedisConsensusTracker
store and retrieve in a shared Redis cluster, with leader election
type
RedisConsensusTracker
struct
{
type
RedisConsensusTracker
struct
{
ctx
context
.
Context
ctx
context
.
Context
client
*
redis
.
Client
client
*
redis
.
Client
backendGroup
string
namespace
string
backendGroup
*
BackendGroup
redlock
*
redsync
.
Mutex
lockPeriod
time
.
Duration
heartbeatInterval
time
.
Duration
leader
bool
leaderName
string
// holds the state collected by local pollers
local
*
InMemoryConsensusTracker
// holds a copy of the remote shared state
// when leader, updates the remote with the local state
remote
*
InMemoryConsensusTracker
}
}
func
NewRedisConsensusTracker
(
ctx
context
.
Context
,
r
*
redis
.
Client
,
namespace
string
)
ConsensusTracker
{
type
RedisConsensusTrackerOpt
func
(
cp
*
RedisConsensusTracker
)
return
&
RedisConsensusTracker
{
func
WithLockPeriod
(
lockPeriod
time
.
Duration
)
RedisConsensusTrackerOpt
{
return
func
(
ct
*
RedisConsensusTracker
)
{
ct
.
lockPeriod
=
lockPeriod
}
}
func
WithHeartbeatInterval
(
heartbeatInterval
time
.
Duration
)
RedisConsensusTrackerOpt
{
return
func
(
ct
*
RedisConsensusTracker
)
{
ct
.
heartbeatInterval
=
heartbeatInterval
}
}
func
NewRedisConsensusTracker
(
ctx
context
.
Context
,
redisClient
*
redis
.
Client
,
bg
*
BackendGroup
,
namespace
string
,
opts
...
RedisConsensusTrackerOpt
)
ConsensusTracker
{
tracker
:=
&
RedisConsensusTracker
{
ctx
:
ctx
,
ctx
:
ctx
,
client
:
r
,
client
:
redisClient
,
backendGroup
:
namespace
,
backendGroup
:
bg
,
namespace
:
namespace
,
lockPeriod
:
30
*
time
.
Second
,
heartbeatInterval
:
2
*
time
.
Second
,
local
:
NewInMemoryConsensusTracker
()
.
(
*
InMemoryConsensusTracker
),
remote
:
NewInMemoryConsensusTracker
()
.
(
*
InMemoryConsensusTracker
),
}
for
_
,
opt
:=
range
opts
{
opt
(
tracker
)
}
return
tracker
}
func
(
ct
*
RedisConsensusTracker
)
Init
()
{
go
func
()
{
for
{
// follow same context as backend group poller
ctx
:=
ct
.
backendGroup
.
Consensus
.
ctx
timer
:=
time
.
NewTimer
(
ct
.
heartbeatInterval
)
ct
.
stateHeartbeat
()
select
{
case
<-
timer
.
C
:
case
<-
ctx
.
Done
()
:
timer
.
Stop
()
return
}
}
}()
}
func
(
ct
*
RedisConsensusTracker
)
stateHeartbeat
()
{
pool
:=
goredis
.
NewPool
(
ct
.
client
)
rs
:=
redsync
.
New
(
pool
)
key
:=
ct
.
key
(
"mutex"
)
val
,
err
:=
ct
.
client
.
Get
(
ct
.
ctx
,
key
)
.
Result
()
if
err
!=
nil
&&
err
!=
redis
.
Nil
{
log
.
Error
(
"failed to read the mutex"
,
"err"
,
err
)
ct
.
leader
=
false
return
}
if
val
!=
""
{
if
ct
.
leader
{
log
.
Debug
(
"extending lock"
)
ok
,
err
:=
ct
.
redlock
.
Extend
()
if
err
!=
nil
||
!
ok
{
log
.
Error
(
"failed to extend lock"
,
"err"
,
err
,
"mutex"
,
ct
.
redlock
.
Name
(),
"val"
,
ct
.
redlock
.
Value
())
ct
.
leader
=
false
return
}
ct
.
postPayload
(
val
)
}
else
{
// retrieve current leader
leaderName
,
err
:=
ct
.
client
.
Get
(
ct
.
ctx
,
ct
.
key
(
fmt
.
Sprintf
(
"leader:%s"
,
val
)))
.
Result
()
if
err
!=
nil
&&
err
!=
redis
.
Nil
{
log
.
Error
(
"failed to read the remote leader"
,
"err"
,
err
)
return
}
ct
.
leaderName
=
leaderName
log
.
Debug
(
"following"
,
"val"
,
val
,
"leader"
,
leaderName
)
// retrieve payload
val
,
err
:=
ct
.
client
.
Get
(
ct
.
ctx
,
ct
.
key
(
fmt
.
Sprintf
(
"state:%s"
,
val
)))
.
Result
()
if
err
!=
nil
&&
err
!=
redis
.
Nil
{
log
.
Error
(
"failed to read the remote state"
,
"err"
,
err
)
return
}
if
val
==
""
{
log
.
Error
(
"remote state is missing (recent leader election maybe?)"
)
return
}
state
:=
&
ConsensusTrackerState
{}
err
=
json
.
Unmarshal
([]
byte
(
val
),
state
)
if
err
!=
nil
{
log
.
Error
(
"failed to unmarshal the remote state"
,
"err"
,
err
)
return
}
ct
.
remote
.
mutex
.
Lock
()
defer
ct
.
remote
.
mutex
.
Unlock
()
ct
.
remote
.
state
.
update
(
state
)
log
.
Debug
(
"updated state from remote"
,
"state"
,
val
,
"leader"
,
leaderName
)
}
}
else
{
if
ct
.
local
.
GetLatestBlockNumber
()
==
0
||
ct
.
local
.
GetSafeBlockNumber
()
==
0
||
ct
.
local
.
GetFinalizedBlockNumber
()
==
0
{
log
.
Warn
(
"lock not found, but local state is missing, skipping"
)
return
}
log
.
Info
(
"lock not found, creating a new one"
)
mutex
:=
rs
.
NewMutex
(
key
,
redsync
.
WithExpiry
(
ct
.
lockPeriod
),
redsync
.
WithFailFast
(
true
),
redsync
.
WithTries
(
1
))
if
err
:=
mutex
.
Lock
();
err
!=
nil
{
log
.
Debug
(
"failed to obtain lock"
,
"err"
,
err
)
ct
.
leader
=
false
return
}
log
.
Info
(
"lock acquired"
,
"mutex"
,
mutex
.
Name
(),
"val"
,
mutex
.
Value
())
ct
.
redlock
=
mutex
ct
.
leader
=
true
ct
.
postPayload
(
mutex
.
Value
())
}
}
}
}
func
(
ct
*
RedisConsensusTracker
)
key
(
tag
string
)
string
{
func
(
ct
*
RedisConsensusTracker
)
key
(
tag
string
)
string
{
return
fmt
.
Sprintf
(
"consensus:%s:%s"
,
ct
.
backendGroup
,
tag
)
return
fmt
.
Sprintf
(
"consensus:%s:%s"
,
ct
.
namespace
,
tag
)
}
}
func
(
ct
*
RedisConsensusTracker
)
GetLatestBlockNumber
()
hexutil
.
Uint64
{
func
(
ct
*
RedisConsensusTracker
)
GetLatestBlockNumber
()
hexutil
.
Uint64
{
return
hexutil
.
Uint64
(
hexutil
.
MustDecodeUint64
(
ct
.
client
.
Get
(
ct
.
ctx
,
ct
.
key
(
"latest"
))
.
Val
())
)
return
ct
.
remote
.
GetLatestBlockNumber
(
)
}
}
func
(
ct
*
RedisConsensusTracker
)
SetLatestBlockNumber
(
blockNumber
hexutil
.
Uint64
)
{
func
(
ct
*
RedisConsensusTracker
)
SetLatestBlockNumber
(
blockNumber
hexutil
.
Uint64
)
{
ct
.
client
.
Set
(
ct
.
ctx
,
ct
.
key
(
"latest"
),
blockNumber
,
0
)
ct
.
local
.
SetLatestBlockNumber
(
blockNumber
)
}
}
func
(
ct
*
RedisConsensusTracker
)
GetSafeBlockNumber
()
hexutil
.
Uint64
{
func
(
ct
*
RedisConsensusTracker
)
GetSafeBlockNumber
()
hexutil
.
Uint64
{
return
hexutil
.
Uint64
(
hexutil
.
MustDecodeUint64
(
ct
.
client
.
Get
(
ct
.
ctx
,
ct
.
key
(
"safe"
))
.
Val
())
)
return
ct
.
remote
.
GetSafeBlockNumber
(
)
}
}
func
(
ct
*
RedisConsensusTracker
)
SetSafeBlockNumber
(
blockNumber
hexutil
.
Uint64
)
{
func
(
ct
*
RedisConsensusTracker
)
SetSafeBlockNumber
(
blockNumber
hexutil
.
Uint64
)
{
ct
.
client
.
Set
(
ct
.
ctx
,
ct
.
key
(
"safe"
),
blockNumber
,
0
)
ct
.
local
.
SetSafeBlockNumber
(
blockNumber
)
}
}
func
(
ct
*
RedisConsensusTracker
)
GetFinalizedBlockNumber
()
hexutil
.
Uint64
{
func
(
ct
*
RedisConsensusTracker
)
GetFinalizedBlockNumber
()
hexutil
.
Uint64
{
return
hexutil
.
Uint64
(
hexutil
.
MustDecodeUint64
(
ct
.
client
.
Get
(
ct
.
ctx
,
ct
.
key
(
"finalized"
))
.
Val
())
)
return
ct
.
remote
.
GetFinalizedBlockNumber
(
)
}
}
func
(
ct
*
RedisConsensusTracker
)
SetFinalizedBlockNumber
(
blockNumber
hexutil
.
Uint64
)
{
func
(
ct
*
RedisConsensusTracker
)
SetFinalizedBlockNumber
(
blockNumber
hexutil
.
Uint64
)
{
ct
.
client
.
Set
(
ct
.
ctx
,
ct
.
key
(
"finalized"
),
blockNumber
,
0
)
ct
.
local
.
SetFinalizedBlockNumber
(
blockNumber
)
}
func
(
ct
*
RedisConsensusTracker
)
postPayload
(
mutexVal
string
)
{
ct
.
remote
.
mutex
.
Lock
()
defer
ct
.
remote
.
mutex
.
Unlock
()
jsonState
,
err
:=
json
.
Marshal
(
ct
.
local
.
state
)
if
err
!=
nil
{
log
.
Error
(
"failed to marshal local"
,
"err"
,
err
)
ct
.
leader
=
false
return
}
ct
.
client
.
Set
(
ct
.
ctx
,
ct
.
key
(
fmt
.
Sprintf
(
"state:%s"
,
mutexVal
)),
jsonState
,
ct
.
lockPeriod
)
leader
,
_
:=
os
.
LookupEnv
(
"HOSTNAME"
)
if
leader
==
""
{
}
ct
.
client
.
Set
(
ct
.
ctx
,
ct
.
key
(
fmt
.
Sprintf
(
"leader:%s"
,
mutexVal
)),
leader
,
ct
.
lockPeriod
)
log
.
Debug
(
"posted state"
,
"state"
,
string
(
jsonState
),
"leader"
,
leader
)
ct
.
leaderName
=
leader
ct
.
remote
.
state
.
update
(
ct
.
local
.
state
)
RecordGroupConsensusHALatestBlock
(
ct
.
backendGroup
,
leader
,
ct
.
local
.
state
.
Latest
)
RecordGroupConsensusHASafeBlock
(
ct
.
backendGroup
,
leader
,
ct
.
local
.
state
.
Safe
)
RecordGroupConsensusHAFinalizedBlock
(
ct
.
backendGroup
,
leader
,
ct
.
local
.
state
.
Finalized
)
}
}
proxyd/frontend_rate_limiter.go
View file @
ed73f1f7
...
@@ -6,7 +6,7 @@ import (
...
@@ -6,7 +6,7 @@ import (
"sync"
"sync"
"time"
"time"
"github.com/
go-redis/redis/v8
"
"github.com/
redis/go-redis/v9
"
)
)
type
FrontendRateLimiter
interface
{
type
FrontendRateLimiter
interface
{
...
...
proxyd/frontend_rate_limiter_test.go
View file @
ed73f1f7
...
@@ -7,7 +7,7 @@ import (
...
@@ -7,7 +7,7 @@ import (
"time"
"time"
"github.com/alicebob/miniredis"
"github.com/alicebob/miniredis"
"github.com/
go-redis/redis/v8
"
"github.com/
redis/go-redis/v9
"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/require"
)
)
...
...
proxyd/go.mod
View file @
ed73f1f7
...
@@ -7,7 +7,6 @@ require (
...
@@ -7,7 +7,6 @@ require (
github.com/alicebob/miniredis v2.5.0+incompatible
github.com/alicebob/miniredis v2.5.0+incompatible
github.com/emirpasic/gods v1.18.1
github.com/emirpasic/gods v1.18.1
github.com/ethereum/go-ethereum v1.12.1
github.com/ethereum/go-ethereum v1.12.1
github.com/go-redis/redis/v8 v8.11.4
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb
github.com/gorilla/mux v1.8.0
github.com/gorilla/mux v1.8.0
github.com/gorilla/websocket v1.5.0
github.com/gorilla/websocket v1.5.0
...
@@ -44,11 +43,14 @@ require (
...
@@ -44,11 +43,14 @@ require (
github.com/ethereum/c-kzg-4844 v0.3.0 // indirect
github.com/ethereum/c-kzg-4844 v0.3.0 // indirect
github.com/getsentry/sentry-go v0.18.0 // indirect
github.com/getsentry/sentry-go v0.18.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-redsync/redsync/v4 v4.9.4 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/gomodule/redigo v1.8.8 // indirect
github.com/gomodule/redigo v1.8.9 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
github.com/holiman/uint256 v1.2.3 // indirect
github.com/holiman/uint256 v1.2.3 // indirect
github.com/klauspost/compress v1.15.15 // indirect
github.com/klauspost/compress v1.15.15 // indirect
...
@@ -62,6 +64,7 @@ require (
...
@@ -62,6 +64,7 @@ require (
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.39.0 // indirect
github.com/prometheus/common v0.39.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/redis/go-redis/v9 v9.1.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/rogpeppe/go-internal v1.9.0 // indirect
github.com/rogpeppe/go-internal v1.9.0 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
...
...
proxyd/go.sum
View file @
ed73f1f7
...
@@ -25,6 +25,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
...
@@ -25,6 +25,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bits-and-blooms/bitset v1.7.0 h1:YjAGVd3XmtK9ktAbX8Zg2g2PwLIMjGREZJHlV4j7NEo=
github.com/bits-and-blooms/bitset v1.7.0 h1:YjAGVd3XmtK9ktAbX8Zg2g2PwLIMjGREZJHlV4j7NEo=
github.com/bits-and-blooms/bitset v1.7.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
github.com/bits-and-blooms/bitset v1.7.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
github.com/bsm/ginkgo/v2 v2.5.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w=
github.com/bsm/gomega v1.20.0/go.mod h1:JifAceMQ4crZIWYUKrlGcmbN3bqHogVTADMD2ATsbwk=
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrfdnWo=
github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrfdnWo=
github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA=
github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA=
...
@@ -114,11 +116,17 @@ github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/
...
@@ -114,11 +116,17 @@ github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg=
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-redis/redis/v7 v7.4.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
github.com/go-redsync/redsync/v4 v4.9.4 h1:vRmYusI+qF95XSpApHAdeu+RjyDvxBXbMthbc/x148c=
github.com/go-redsync/redsync/v4 v4.9.4/go.mod h1:RqBDXUw0q+u9FJTeD2gMzGtHeSVV93DiqGl10B9Hn/4=
github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
...
@@ -136,6 +144,7 @@ github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY
...
@@ -136,6 +144,7 @@ github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
...
@@ -156,6 +165,8 @@ github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg
...
@@ -156,6 +165,8 @@ github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg
github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
github.com/gomodule/redigo v1.8.8 h1:f6cXq6RRfiyrOJEV7p3JhLDlmawGBVBBP1MggY8Mo4E=
github.com/gomodule/redigo v1.8.8 h1:f6cXq6RRfiyrOJEV7p3JhLDlmawGBVBBP1MggY8Mo4E=
github.com/gomodule/redigo v1.8.8/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE=
github.com/gomodule/redigo v1.8.8/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE=
github.com/gomodule/redigo v1.8.9 h1:Sl3u+2BI/kk+VEatbj0scLdrFhjPmbxOc1myhDP41ws=
github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
...
@@ -163,9 +174,12 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
...
@@ -163,9 +174,12 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
...
@@ -174,6 +188,11 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7
...
@@ -174,6 +188,11 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs=
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs=
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
...
@@ -184,6 +203,7 @@ github.com/holiman/uint256 v1.2.3 h1:K8UWO1HUJpRMXBxbmaY1Y8IAMZC/RsKB+ArEnnK4l5o
...
@@ -184,6 +203,7 @@ github.com/holiman/uint256 v1.2.3 h1:K8UWO1HUJpRMXBxbmaY1Y8IAMZC/RsKB+ArEnnK4l5o
github.com/holiman/uint256 v1.2.3/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw=
github.com/holiman/uint256 v1.2.3/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE=
github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI=
github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI=
...
@@ -257,21 +277,43 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS
...
@@ -257,21 +277,43 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU=
github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0=
github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo=
github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw=
github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo=
github.com/onsi/ginkgo/v2 v2.8.0/go.mod h1:6JsQiECmxCa3V5st74AL/AmsV482EDdVrGaVW6z3oYU=
github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c=
github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c=
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo=
github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc=
github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM=
github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg=
github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM=
github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM=
github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q=
github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM=
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
...
@@ -290,6 +332,9 @@ github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8u
...
@@ -290,6 +332,9 @@ github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8u
github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y=
github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y=
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
github.com/redis/go-redis/v9 v9.0.2/go.mod h1:/xDTe9EF1LM61hek62Poq2nzQSGj0xSrEtEHbBQevps=
github.com/redis/go-redis/v9 v9.1.0 h1:137FnGdk+EQdCbye1FW+qOEcY5S+SpY9T0NiuqvtfMY=
github.com/redis/go-redis/v9 v9.1.0/go.mod h1:urWj3He21Dj5k4TK1y59xH8Uj6ATueP8AH1cY3lZl4c=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
...
@@ -298,6 +343,7 @@ github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZV
...
@@ -298,6 +343,7 @@ github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZV
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U=
github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U=
github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
github.com/rueian/rueidis v0.0.93/go.mod h1:lo6LBci0D986usi5Wxjb4RVNaWENKYbHZSnufGJ9bTE=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g=
github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g=
...
@@ -325,6 +371,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
...
@@ -325,6 +371,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203/go.mod h1:oqN97ltKNihBbwlX8dLpwxCl3+HnXKV/R0e+sRLd9C8=
github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4=
github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4=
github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
...
@@ -354,10 +401,18 @@ github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZ
...
@@ -354,10 +401,18 @@ github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZ
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9 h1:k/gmLsJDWwWqbLCur2yWnJzwQEKRcAHXo6seXGuSwWw=
github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9 h1:k/gmLsJDWwWqbLCur2yWnJzwQEKRcAHXo6seXGuSwWw=
github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9/go.mod h1:E1AXubJBdNmFERAOucpDIxNzeGfLzg0mYh+UfMWdChA=
github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9/go.mod h1:E1AXubJBdNmFERAOucpDIxNzeGfLzg0mYh+UfMWdChA=
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.opentelemetry.io/otel v1.12.0/go.mod h1:geaoz0L0r1BEOR81k7/n9W4TCXYCJ7bPO7K374jQHG0=
go.opentelemetry.io/otel/metric v0.35.0/go.mod h1:qAcbhaTRFU6uG8QM7dDo7XvFsWcugziq/5YI065TokQ=
go.opentelemetry.io/otel/sdk v1.12.0/go.mod h1:WYcvtgquYvgODEvxOry5owO2y9MyciW7JqMz6cpXShE=
go.opentelemetry.io/otel/sdk/metric v0.35.0/go.mod h1:eDyp1GxSiwV98kr7w4pzrszQh/eze9MqBqPd2bCPmyE=
go.opentelemetry.io/otel/trace v1.12.0/go.mod h1:pHlgBynn6s25qJ2szD+Bv+iwKJttjHSI3lUAyf0GNuQ=
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
...
@@ -369,6 +424,7 @@ golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPh
...
@@ -369,6 +424,7 @@ golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
...
@@ -377,11 +433,16 @@ golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnL
...
@@ -377,11 +433,16 @@ golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnL
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
...
@@ -394,6 +455,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
...
@@ -394,6 +455,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
...
@@ -403,6 +465,14 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
...
@@ -403,6 +465,14 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
...
@@ -413,6 +483,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
...
@@ -413,6 +483,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
...
@@ -427,7 +499,9 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w
...
@@ -427,7 +499,9 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
...
@@ -444,18 +518,37 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
...
@@ -444,18 +518,37 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
...
@@ -472,7 +565,14 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK
...
@@ -472,7 +565,14 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
...
@@ -501,6 +601,7 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
...
@@ -501,6 +601,7 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
...
...
proxyd/methods.go
View file @
ed73f1f7
...
@@ -44,7 +44,7 @@ func (e *StaticMethodHandler) GetRPCMethod(ctx context.Context, req *RPCReq) (*R
...
@@ -44,7 +44,7 @@ func (e *StaticMethodHandler) GetRPCMethod(ctx context.Context, req *RPCReq) (*R
key
:=
e
.
key
(
req
)
key
:=
e
.
key
(
req
)
val
,
err
:=
e
.
cache
.
Get
(
ctx
,
key
)
val
,
err
:=
e
.
cache
.
Get
(
ctx
,
key
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Error
(
"error reading
from
cache"
,
"key"
,
key
,
"method"
,
req
.
Method
,
"err"
,
err
)
log
.
Error
(
"error reading
update
cache"
,
"key"
,
key
,
"method"
,
req
.
Method
,
"err"
,
err
)
return
nil
,
err
return
nil
,
err
}
}
if
val
==
""
{
if
val
==
""
{
...
@@ -53,7 +53,7 @@ func (e *StaticMethodHandler) GetRPCMethod(ctx context.Context, req *RPCReq) (*R
...
@@ -53,7 +53,7 @@ func (e *StaticMethodHandler) GetRPCMethod(ctx context.Context, req *RPCReq) (*R
var
result
interface
{}
var
result
interface
{}
if
err
:=
json
.
Unmarshal
([]
byte
(
val
),
&
result
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
([]
byte
(
val
),
&
result
);
err
!=
nil
{
log
.
Error
(
"error unmarshalling value
from
cache"
,
"key"
,
key
,
"method"
,
req
.
Method
,
"err"
,
err
)
log
.
Error
(
"error unmarshalling value
update
cache"
,
"key"
,
key
,
"method"
,
req
.
Method
,
"err"
,
err
)
return
nil
,
err
return
nil
,
err
}
}
return
&
RPCRes
{
return
&
RPCRes
{
...
...
proxyd/metrics.go
View file @
ed73f1f7
...
@@ -262,6 +262,33 @@ var (
...
@@ -262,6 +262,33 @@ var (
"backend_group_name"
,
"backend_group_name"
,
})
})
consensusHALatestBlock
=
promauto
.
NewGaugeVec
(
prometheus
.
GaugeOpts
{
Namespace
:
MetricsNamespace
,
Name
:
"group_consensus_ha_latest_block"
,
Help
:
"Consensus HA latest block"
,
},
[]
string
{
"backend_group_name"
,
"leader"
,
})
consensusHASafeBlock
=
promauto
.
NewGaugeVec
(
prometheus
.
GaugeOpts
{
Namespace
:
MetricsNamespace
,
Name
:
"group_consensus_ha_safe_block"
,
Help
:
"Consensus HA safe block"
,
},
[]
string
{
"backend_group_name"
,
"leader"
,
})
consensusHAFinalizedBlock
=
promauto
.
NewGaugeVec
(
prometheus
.
GaugeOpts
{
Namespace
:
MetricsNamespace
,
Name
:
"group_consensus_ha_finalized_block"
,
Help
:
"Consensus HA finalized block"
,
},
[]
string
{
"backend_group_name"
,
"leader"
,
})
backendLatestBlockBackend
=
promauto
.
NewGaugeVec
(
prometheus
.
GaugeOpts
{
backendLatestBlockBackend
=
promauto
.
NewGaugeVec
(
prometheus
.
GaugeOpts
{
Namespace
:
MetricsNamespace
,
Namespace
:
MetricsNamespace
,
Name
:
"backend_latest_block"
,
Name
:
"backend_latest_block"
,
...
@@ -305,7 +332,7 @@ var (
...
@@ -305,7 +332,7 @@ var (
consensusGroupFilteredCount
=
promauto
.
NewGaugeVec
(
prometheus
.
GaugeOpts
{
consensusGroupFilteredCount
=
promauto
.
NewGaugeVec
(
prometheus
.
GaugeOpts
{
Namespace
:
MetricsNamespace
,
Namespace
:
MetricsNamespace
,
Name
:
"group_consensus_filtered_count"
,
Name
:
"group_consensus_filtered_count"
,
Help
:
"Consensus group filtered out
from
serving traffic count"
,
Help
:
"Consensus group filtered out
update
serving traffic count"
,
},
[]
string
{
},
[]
string
{
"backend_group_name"
,
"backend_group_name"
,
})
})
...
@@ -438,6 +465,18 @@ func RecordBatchSize(size int) {
...
@@ -438,6 +465,18 @@ func RecordBatchSize(size int) {
batchSizeHistogram
.
Observe
(
float64
(
size
))
batchSizeHistogram
.
Observe
(
float64
(
size
))
}
}
func
RecordGroupConsensusHALatestBlock
(
group
*
BackendGroup
,
leader
string
,
blockNumber
hexutil
.
Uint64
)
{
consensusHALatestBlock
.
WithLabelValues
(
group
.
Name
,
leader
)
.
Set
(
float64
(
blockNumber
))
}
func
RecordGroupConsensusHASafeBlock
(
group
*
BackendGroup
,
leader
string
,
blockNumber
hexutil
.
Uint64
)
{
consensusHASafeBlock
.
WithLabelValues
(
group
.
Name
,
leader
)
.
Set
(
float64
(
blockNumber
))
}
func
RecordGroupConsensusHAFinalizedBlock
(
group
*
BackendGroup
,
leader
string
,
blockNumber
hexutil
.
Uint64
)
{
consensusHAFinalizedBlock
.
WithLabelValues
(
group
.
Name
,
leader
)
.
Set
(
float64
(
blockNumber
))
}
func
RecordGroupConsensusLatestBlock
(
group
*
BackendGroup
,
blockNumber
hexutil
.
Uint64
)
{
func
RecordGroupConsensusLatestBlock
(
group
*
BackendGroup
,
blockNumber
hexutil
.
Uint64
)
{
consensusLatestBlock
.
WithLabelValues
(
group
.
Name
)
.
Set
(
float64
(
blockNumber
))
consensusLatestBlock
.
WithLabelValues
(
group
.
Name
)
.
Set
(
float64
(
blockNumber
))
}
}
...
...
proxyd/proxyd.go
View file @
ed73f1f7
package
proxyd
package
proxyd
import
(
import
(
"context"
"crypto/tls"
"crypto/tls"
"errors"
"errors"
"fmt"
"fmt"
...
@@ -10,8 +11,8 @@ import (
...
@@ -10,8 +11,8 @@ import (
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/log"
"github.com/go-redis/redis/v8"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/redis/go-redis/v9"
"golang.org/x/sync/semaphore"
"golang.org/x/sync/semaphore"
)
)
...
@@ -313,8 +314,28 @@ func Start(config *Config) (*Server, func(), error) {
...
@@ -313,8 +314,28 @@ func Start(config *Config) (*Server, func(), error) {
copts
=
append
(
copts
,
WithMaxBlockRange
(
bgcfg
.
ConsensusMaxBlockRange
))
copts
=
append
(
copts
,
WithMaxBlockRange
(
bgcfg
.
ConsensusMaxBlockRange
))
}
}
var
tracker
ConsensusTracker
if
bgcfg
.
ConsensusHA
{
if
redisClient
==
nil
{
log
.
Crit
(
"cant start - consensus high availability requires redis"
)
}
topts
:=
make
([]
RedisConsensusTrackerOpt
,
0
)
if
bgcfg
.
ConsensusHALockPeriod
>
0
{
topts
=
append
(
topts
,
WithLockPeriod
(
time
.
Duration
(
bgcfg
.
ConsensusHALockPeriod
)))
}
if
bgcfg
.
ConsensusHAHeartbeatInterval
>
0
{
topts
=
append
(
topts
,
WithLockPeriod
(
time
.
Duration
(
bgcfg
.
ConsensusHAHeartbeatInterval
)))
}
tracker
=
NewRedisConsensusTracker
(
context
.
Background
(),
redisClient
,
bg
,
bg
.
Name
,
topts
...
)
copts
=
append
(
copts
,
WithTracker
(
tracker
))
}
cp
:=
NewConsensusPoller
(
bg
,
copts
...
)
cp
:=
NewConsensusPoller
(
bg
,
copts
...
)
bg
.
Consensus
=
cp
bg
.
Consensus
=
cp
if
bgcfg
.
ConsensusHA
{
tracker
.
(
*
RedisConsensusTracker
)
.
Init
()
}
}
}
}
}
...
...
proxyd/redis.go
View file @
ed73f1f7
...
@@ -4,7 +4,7 @@ import (
...
@@ -4,7 +4,7 @@ import (
"context"
"context"
"time"
"time"
"github.com/
go-redis/redis/v8
"
"github.com/
redis/go-redis/v9
"
)
)
func
NewRedisClient
(
url
string
)
(
*
redis
.
Client
,
error
)
{
func
NewRedisClient
(
url
string
)
(
*
redis
.
Client
,
error
)
{
...
...
proxyd/server.go
View file @
ed73f1f7
...
@@ -22,10 +22,10 @@ import (
...
@@ -22,10 +22,10 @@ import (
"github.com/ethereum/go-ethereum/core/txpool"
"github.com/ethereum/go-ethereum/core/txpool"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/log"
"github.com/go-redis/redis/v8"
"github.com/gorilla/mux"
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
"github.com/gorilla/websocket"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus"
"github.com/redis/go-redis/v9"
"github.com/rs/cors"
"github.com/rs/cors"
"github.com/syndtr/goleveldb/leveldb/opt"
"github.com/syndtr/goleveldb/leveldb/opt"
)
)
...
@@ -653,11 +653,11 @@ func (s *Server) rateLimitSender(ctx context.Context, req *RPCReq) error {
...
@@ -653,11 +653,11 @@ func (s *Server) rateLimitSender(ctx context.Context, req *RPCReq) error {
var
data
hexutil
.
Bytes
var
data
hexutil
.
Bytes
if
err
:=
data
.
UnmarshalText
([]
byte
(
params
[
0
]));
err
!=
nil
{
if
err
:=
data
.
UnmarshalText
([]
byte
(
params
[
0
]));
err
!=
nil
{
log
.
Debug
(
"error decoding raw tx data"
,
"err"
,
err
,
"req_id"
,
GetReqID
(
ctx
))
log
.
Debug
(
"error decoding raw tx data"
,
"err"
,
err
,
"req_id"
,
GetReqID
(
ctx
))
// Geth returns the raw error
from
UnmarshalText.
// Geth returns the raw error
update
UnmarshalText.
return
ErrInvalidParams
(
err
.
Error
())
return
ErrInvalidParams
(
err
.
Error
())
}
}
// Inflates a types.Transaction object
from
the transaction's raw bytes.
// Inflates a types.Transaction object
update
the transaction's raw bytes.
tx
:=
new
(
types
.
Transaction
)
tx
:=
new
(
types
.
Transaction
)
if
err
:=
tx
.
UnmarshalBinary
(
data
);
err
!=
nil
{
if
err
:=
tx
.
UnmarshalBinary
(
data
);
err
!=
nil
{
log
.
Debug
(
"could not unmarshal transaction"
,
"err"
,
err
,
"req_id"
,
GetReqID
(
ctx
))
log
.
Debug
(
"could not unmarshal transaction"
,
"err"
,
err
,
"req_id"
,
GetReqID
(
ctx
))
...
@@ -675,12 +675,12 @@ func (s *Server) rateLimitSender(ctx context.Context, req *RPCReq) error {
...
@@ -675,12 +675,12 @@ func (s *Server) rateLimitSender(ctx context.Context, req *RPCReq) error {
// sender. This method performs an ecrecover, which can be expensive.
// sender. This method performs an ecrecover, which can be expensive.
msg
,
err
:=
core
.
TransactionToMessage
(
tx
,
types
.
LatestSignerForChainID
(
tx
.
ChainId
()),
nil
)
msg
,
err
:=
core
.
TransactionToMessage
(
tx
,
types
.
LatestSignerForChainID
(
tx
.
ChainId
()),
nil
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Debug
(
"could not get message
from
transaction"
,
"err"
,
err
,
"req_id"
,
GetReqID
(
ctx
))
log
.
Debug
(
"could not get message
update
transaction"
,
"err"
,
err
,
"req_id"
,
GetReqID
(
ctx
))
return
ErrInvalidParams
(
err
.
Error
())
return
ErrInvalidParams
(
err
.
Error
())
}
}
ok
,
err
:=
s
.
senderLim
.
Take
(
ctx
,
fmt
.
Sprintf
(
"%s:%d"
,
msg
.
From
.
Hex
(),
tx
.
Nonce
()))
ok
,
err
:=
s
.
senderLim
.
Take
(
ctx
,
fmt
.
Sprintf
(
"%s:%d"
,
msg
.
From
.
Hex
(),
tx
.
Nonce
()))
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Error
(
"error taking
from
sender limiter"
,
"err"
,
err
,
"req_id"
,
GetReqID
(
ctx
))
log
.
Error
(
"error taking
update
sender limiter"
,
"err"
,
err
,
"req_id"
,
GetReqID
(
ctx
))
return
ErrInternal
return
ErrInternal
}
}
if
!
ok
{
if
!
ok
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment