Commit 08ca42bc authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge branch 'develop' into jg/makefile_changes

parents 339fd1e0 4fa47249
...@@ -28,11 +28,8 @@ func (e *EthBridge) GetDepositsByBlockRange(ctx context.Context, start, end uint ...@@ -28,11 +28,8 @@ func (e *EthBridge) GetDepositsByBlockRange(ctx context.Context, start, end uint
End: &end, End: &end,
} }
var iter *bindings.L1StandardBridgeETHDepositInitiatedIterator iter, err := backoff.Do(ctx, 3, backoff.Exponential(), func() (*bindings.L1StandardBridgeETHDepositInitiatedIterator, error) {
err := backoff.Do(3, backoff.Exponential(), func() error { return e.contract.FilterETHDepositInitiated(opts, nil, nil)
var err error
iter, err = e.contract.FilterETHDepositInitiated(opts, nil, nil)
return err
}) })
if err != nil { if err != nil {
return nil, err return nil, err
......
...@@ -37,11 +37,8 @@ func (p *Portal) GetProvenWithdrawalsByBlockRange(ctx context.Context, start, en ...@@ -37,11 +37,8 @@ func (p *Portal) GetProvenWithdrawalsByBlockRange(ctx context.Context, start, en
End: &end, End: &end,
} }
var iter *bindings.OptimismPortalWithdrawalProvenIterator iter, err := backoff.Do(ctx, 3, backoff.Exponential(), func() (*bindings.OptimismPortalWithdrawalProvenIterator, error) {
err := backoff.Do(3, backoff.Exponential(), func() error { return p.contract.FilterWithdrawalProven(opts, nil, nil, nil)
var err error
iter, err = p.contract.FilterWithdrawalProven(opts, nil, nil, nil)
return err
}) })
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -71,11 +68,8 @@ func (p *Portal) GetFinalizedWithdrawalsByBlockRange(ctx context.Context, start, ...@@ -71,11 +68,8 @@ func (p *Portal) GetFinalizedWithdrawalsByBlockRange(ctx context.Context, start,
End: &end, End: &end,
} }
var iter *bindings.OptimismPortalWithdrawalFinalizedIterator iter, err := backoff.Do(ctx, 3, backoff.Exponential(), func() (*bindings.OptimismPortalWithdrawalFinalizedIterator, error) {
err := backoff.Do(3, backoff.Exponential(), func() error { return p.contract.FilterWithdrawalFinalized(opts, nil)
var err error
iter, err = p.contract.FilterWithdrawalFinalized(opts, nil)
return err
}) })
if err != nil { if err != nil {
return nil, err return nil, err
......
...@@ -28,11 +28,8 @@ func (s *StandardBridge) GetDepositsByBlockRange(ctx context.Context, start, end ...@@ -28,11 +28,8 @@ func (s *StandardBridge) GetDepositsByBlockRange(ctx context.Context, start, end
End: &end, End: &end,
} }
var iter *bindings.L1StandardBridgeERC20DepositInitiatedIterator iter, err := backoff.Do(ctx, 3, backoff.Exponential(), func() (*bindings.L1StandardBridgeERC20DepositInitiatedIterator, error) {
err := backoff.Do(3, backoff.Exponential(), func() error { return s.contract.FilterERC20DepositInitiated(opts, nil, nil, nil)
var err error
iter, err = s.contract.FilterERC20DepositInitiated(opts, nil, nil, nil)
return err
}) })
if err != nil { if err != nil {
return nil, err return nil, err
......
...@@ -35,11 +35,8 @@ func (s *StandardBridge) GetWithdrawalsByBlockRange(ctx context.Context, start, ...@@ -35,11 +35,8 @@ func (s *StandardBridge) GetWithdrawalsByBlockRange(ctx context.Context, start,
End: &end, End: &end,
} }
var iter *bindings.L2StandardBridgeWithdrawalInitiatedIterator iter, err := backoff.Do(ctx, 3, backoff.Exponential(), func() (*bindings.L2StandardBridgeWithdrawalInitiatedIterator, error) {
err := backoff.Do(3, backoff.Exponential(), func() error { return s.l2SB.FilterWithdrawalInitiated(opts, nil, nil, nil)
var err error
iter, err = s.l2SB.FilterWithdrawalInitiated(opts, nil, nil, nil)
return err
}) })
if err != nil { if err != nil {
return nil, err return nil, err
......
...@@ -10,11 +10,7 @@ import ( ...@@ -10,11 +10,7 @@ import (
// HeaderByNumberWithRetry retries getting headers. // HeaderByNumberWithRetry retries getting headers.
func HeaderByNumberWithRetry(ctx context.Context, client *ethclient.Client) (*types.Header, error) { func HeaderByNumberWithRetry(ctx context.Context, client *ethclient.Client) (*types.Header, error) {
var res *types.Header return backoff.Do(ctx, 3, backoff.Exponential(), func() (*types.Header, error) {
err := backoff.DoCtx(ctx, 3, backoff.Exponential(), func() error { return client.HeaderByNumber(ctx, nil)
var err error
res, err = client.HeaderByNumber(ctx, nil)
return err
}) })
return res, err
} }
...@@ -50,17 +50,17 @@ func NewBatchSubmitterFromCLIConfig(cfg CLIConfig, l log.Logger, m metrics.Metri ...@@ -50,17 +50,17 @@ func NewBatchSubmitterFromCLIConfig(cfg CLIConfig, l log.Logger, m metrics.Metri
// Connect to L1 and L2 providers. Perform these last since they are the // Connect to L1 and L2 providers. Perform these last since they are the
// most expensive. // most expensive.
l1Client, err := opclient.DialEthClientWithTimeout(ctx, cfg.L1EthRpc, opclient.DefaultDialTimeout) l1Client, err := opclient.DialEthClientWithTimeout(opclient.DefaultDialTimeout, l, cfg.L1EthRpc)
if err != nil { if err != nil {
return nil, err return nil, err
} }
l2Client, err := opclient.DialEthClientWithTimeout(ctx, cfg.L2EthRpc, opclient.DefaultDialTimeout) l2Client, err := opclient.DialEthClientWithTimeout(opclient.DefaultDialTimeout, l, cfg.L2EthRpc)
if err != nil { if err != nil {
return nil, err return nil, err
} }
rollupClient, err := opclient.DialRollupClientWithTimeout(ctx, cfg.RollupRpc, opclient.DefaultDialTimeout) rollupClient, err := opclient.DialRollupClientWithTimeout(opclient.DefaultDialTimeout, l, cfg.RollupRpc)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -102,22 +102,16 @@ func NewRPC(ctx context.Context, lgr log.Logger, addr string, opts ...RPCOption) ...@@ -102,22 +102,16 @@ func NewRPC(ctx context.Context, lgr log.Logger, addr string, opts ...RPCOption)
// Dials a JSON-RPC endpoint repeatedly, with a backoff, until a client connection is established. Auth is optional. // Dials a JSON-RPC endpoint repeatedly, with a backoff, until a client connection is established. Auth is optional.
func dialRPCClientWithBackoff(ctx context.Context, log log.Logger, addr string, attempts int, opts ...rpc.ClientOption) (*rpc.Client, error) { func dialRPCClientWithBackoff(ctx context.Context, log log.Logger, addr string, attempts int, opts ...rpc.ClientOption) (*rpc.Client, error) {
bOff := backoff.Exponential() bOff := backoff.Exponential()
var ret *rpc.Client return backoff.Do(ctx, attempts, bOff, func() (*rpc.Client, error) {
err := backoff.DoCtx(ctx, attempts, bOff, func() error {
client, err := rpc.DialOptions(ctx, addr, opts...) client, err := rpc.DialOptions(ctx, addr, opts...)
if err != nil { if err != nil {
if client == nil { if client == nil {
return fmt.Errorf("failed to dial address (%s): %w", addr, err) return nil, fmt.Errorf("failed to dial address (%s): %w", addr, err)
} }
log.Warn("failed to dial address, but may connect later", "addr", addr, "err", err) log.Warn("failed to dial address, but may connect later", "addr", addr, "err", err)
} }
ret = client return client, nil
return nil
}) })
if err != nil {
return nil, err
}
return ret, nil
} }
// BaseRPCClient is a wrapper around a concrete *rpc.Client instance to make it compliant // BaseRPCClient is a wrapper around a concrete *rpc.Client instance to make it compliant
......
...@@ -142,12 +142,12 @@ func (s *SyncClient) eventLoop() { ...@@ -142,12 +142,12 @@ func (s *SyncClient) eventLoop() {
s.log.Debug("Shutting down RPC sync worker") s.log.Debug("Shutting down RPC sync worker")
return return
case reqNum := <-s.requests: case reqNum := <-s.requests:
err := backoff.DoCtx(s.resCtx, 5, backoffStrategy, func() error { _, err := backoff.Do(s.resCtx, 5, backoffStrategy, func() (interface{}, error) {
// Limit the maximum time for fetching payloads // Limit the maximum time for fetching payloads
ctx, cancel := context.WithTimeout(s.resCtx, time.Second*10) ctx, cancel := context.WithTimeout(s.resCtx, time.Second*10)
defer cancel() defer cancel()
// We are only fetching one block at a time here. // We are only fetching one block at a time here.
return s.fetchUnsafeBlockFromRpc(ctx, reqNum) return nil, s.fetchUnsafeBlockFromRpc(ctx, reqNum)
}) })
if err != nil { if err != nil {
if err == s.resCtx.Err() { if err == s.resCtx.Err() {
......
...@@ -28,49 +28,33 @@ func NewRetryingL1Source(logger log.Logger, source L1Source) *RetryingL1Source { ...@@ -28,49 +28,33 @@ func NewRetryingL1Source(logger log.Logger, source L1Source) *RetryingL1Source {
} }
func (s *RetryingL1Source) InfoByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, error) { func (s *RetryingL1Source) InfoByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, error) {
var info eth.BlockInfo return backoff.Do(ctx, maxAttempts, s.strategy, func() (eth.BlockInfo, error) {
err := backoff.DoCtx(ctx, maxAttempts, s.strategy, func() error {
res, err := s.source.InfoByHash(ctx, blockHash) res, err := s.source.InfoByHash(ctx, blockHash)
if err != nil { if err != nil {
s.logger.Warn("Failed to retrieve info", "hash", blockHash, "err", err) s.logger.Warn("Failed to retrieve info", "hash", blockHash, "err", err)
return err
} }
info = res return res, err
return nil
}) })
return info, err
} }
func (s *RetryingL1Source) InfoAndTxsByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Transactions, error) { func (s *RetryingL1Source) InfoAndTxsByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Transactions, error) {
var info eth.BlockInfo return backoff.Do2(ctx, maxAttempts, s.strategy, func() (eth.BlockInfo, types.Transactions, error) {
var txs types.Transactions
err := backoff.DoCtx(ctx, maxAttempts, s.strategy, func() error {
i, t, err := s.source.InfoAndTxsByHash(ctx, blockHash) i, t, err := s.source.InfoAndTxsByHash(ctx, blockHash)
if err != nil { if err != nil {
s.logger.Warn("Failed to retrieve l1 info and txs", "hash", blockHash, "err", err) s.logger.Warn("Failed to retrieve l1 info and txs", "hash", blockHash, "err", err)
return err
} }
info = i return i, t, err
txs = t
return nil
}) })
return info, txs, err
} }
func (s *RetryingL1Source) FetchReceipts(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Receipts, error) { func (s *RetryingL1Source) FetchReceipts(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Receipts, error) {
var info eth.BlockInfo return backoff.Do2(ctx, maxAttempts, s.strategy, func() (eth.BlockInfo, types.Receipts, error) {
var rcpts types.Receipts
err := backoff.DoCtx(ctx, maxAttempts, s.strategy, func() error {
i, r, err := s.source.FetchReceipts(ctx, blockHash) i, r, err := s.source.FetchReceipts(ctx, blockHash)
if err != nil { if err != nil {
s.logger.Warn("Failed to fetch receipts", "hash", blockHash, "err", err) s.logger.Warn("Failed to fetch receipts", "hash", blockHash, "err", err)
return err
} }
info = i return i, r, err
rcpts = r
return nil
}) })
return info, rcpts, err
} }
var _ L1Source = (*RetryingL1Source)(nil) var _ L1Source = (*RetryingL1Source)(nil)
...@@ -82,61 +66,44 @@ type RetryingL2Source struct { ...@@ -82,61 +66,44 @@ type RetryingL2Source struct {
} }
func (s *RetryingL2Source) InfoAndTxsByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Transactions, error) { func (s *RetryingL2Source) InfoAndTxsByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Transactions, error) {
var info eth.BlockInfo return backoff.Do2(ctx, maxAttempts, s.strategy, func() (eth.BlockInfo, types.Transactions, error) {
var txs types.Transactions
err := backoff.DoCtx(ctx, maxAttempts, s.strategy, func() error {
i, t, err := s.source.InfoAndTxsByHash(ctx, blockHash) i, t, err := s.source.InfoAndTxsByHash(ctx, blockHash)
if err != nil { if err != nil {
s.logger.Warn("Failed to retrieve l2 info and txs", "hash", blockHash, "err", err) s.logger.Warn("Failed to retrieve l2 info and txs", "hash", blockHash, "err", err)
return err
} }
info = i return i, t, err
txs = t
return nil
}) })
return info, txs, err
} }
func (s *RetryingL2Source) NodeByHash(ctx context.Context, hash common.Hash) ([]byte, error) { func (s *RetryingL2Source) NodeByHash(ctx context.Context, hash common.Hash) ([]byte, error) {
var node []byte return backoff.Do(ctx, maxAttempts, s.strategy, func() ([]byte, error) {
err := backoff.DoCtx(ctx, maxAttempts, s.strategy, func() error {
n, err := s.source.NodeByHash(ctx, hash) n, err := s.source.NodeByHash(ctx, hash)
if err != nil { if err != nil {
s.logger.Warn("Failed to retrieve node", "hash", hash, "err", err) s.logger.Warn("Failed to retrieve node", "hash", hash, "err", err)
return err
} }
node = n return n, err
return nil
}) })
return node, err
} }
func (s *RetryingL2Source) CodeByHash(ctx context.Context, hash common.Hash) ([]byte, error) { func (s *RetryingL2Source) CodeByHash(ctx context.Context, hash common.Hash) ([]byte, error) {
var code []byte return backoff.Do(ctx, maxAttempts, s.strategy, func() ([]byte, error) {
err := backoff.DoCtx(ctx, maxAttempts, s.strategy, func() error {
c, err := s.source.CodeByHash(ctx, hash) c, err := s.source.CodeByHash(ctx, hash)
if err != nil { if err != nil {
s.logger.Warn("Failed to retrieve code", "hash", hash, "err", err) s.logger.Warn("Failed to retrieve code", "hash", hash, "err", err)
return err
} }
code = c return c, err
return nil
}) })
return code, err
} }
func (s *RetryingL2Source) OutputByRoot(ctx context.Context, root common.Hash) (eth.Output, error) { func (s *RetryingL2Source) OutputByRoot(ctx context.Context, root common.Hash) (eth.Output, error) {
var output eth.Output return backoff.Do(ctx, maxAttempts, s.strategy, func() (eth.Output, error) {
err := backoff.DoCtx(ctx, maxAttempts, s.strategy, func() error {
o, err := s.source.OutputByRoot(ctx, root) o, err := s.source.OutputByRoot(ctx, root)
if err != nil { if err != nil {
s.logger.Warn("Failed to fetch l2 output", "root", root, "err", err) s.logger.Warn("Failed to fetch l2 output", "root", root, "err", err)
return err return o, err
} }
output = o return o, nil
return nil
}) })
return output, err
} }
func NewRetryingL2Source(logger log.Logger, source L2Source) *RetryingL2Source { func NewRetryingL2Source(logger log.Logger, source L2Source) *RetryingL2Source {
......
...@@ -157,13 +157,12 @@ func NewL2OutputSubmitterConfigFromCLIConfig(cfg CLIConfig, l log.Logger, m metr ...@@ -157,13 +157,12 @@ func NewL2OutputSubmitterConfigFromCLIConfig(cfg CLIConfig, l log.Logger, m metr
} }
// Connect to L1 and L2 providers. Perform these last since they are the most expensive. // Connect to L1 and L2 providers. Perform these last since they are the most expensive.
ctx := context.Background() l1Client, err := opclient.DialEthClientWithTimeout(opclient.DefaultDialTimeout, l, cfg.L1EthRpc)
l1Client, err := opclient.DialEthClientWithTimeout(ctx, cfg.L1EthRpc, opclient.DefaultDialTimeout)
if err != nil { if err != nil {
return nil, err return nil, err
} }
rollupClient, err := opclient.DialRollupClientWithTimeout(ctx, cfg.RollupRpc, opclient.DefaultDialTimeout) rollupClient, err := opclient.DialRollupClientWithTimeout(opclient.DefaultDialTimeout, l, cfg.RollupRpc)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -6,10 +6,6 @@ import ( ...@@ -6,10 +6,6 @@ import (
"time" "time"
) )
// Operation represents an operation that will be retried
// based on some backoff strategy if it fails.
type Operation func() error
// ErrFailedPermanently is an error raised by Do when the // ErrFailedPermanently is an error raised by Do when the
// underlying Operation has been retried maxAttempts times. // underlying Operation has been retried maxAttempts times.
type ErrFailedPermanently struct { type ErrFailedPermanently struct {
...@@ -21,16 +17,27 @@ func (e *ErrFailedPermanently) Error() string { ...@@ -21,16 +17,27 @@ func (e *ErrFailedPermanently) Error() string {
return fmt.Sprintf("operation failed permanently after %d attempts: %v", e.attempts, e.LastErr) return fmt.Sprintf("operation failed permanently after %d attempts: %v", e.attempts, e.LastErr)
} }
type pair[T, U any] struct {
a T
b U
}
func Do2[T, U any](ctx context.Context, maxAttempts int, strategy Strategy, op func() (T, U, error)) (T, U, error) {
f := func() (pair[T, U], error) {
a, b, err := op()
return pair[T, U]{a, b}, err
}
res, err := Do(ctx, maxAttempts, strategy, f)
return res.a, res.b, err
}
// Do performs the provided Operation up to maxAttempts times // Do performs the provided Operation up to maxAttempts times
// with delays in between each retry according to the provided // with delays in between each retry according to the provided
// Strategy. // Strategy.
func Do(maxAttempts int, strategy Strategy, op Operation) error { func Do[T any](ctx context.Context, maxAttempts int, strategy Strategy, op func() (T, error)) (T, error) {
return DoCtx(context.Background(), maxAttempts, strategy, op) var empty T
}
func DoCtx(ctx context.Context, maxAttempts int, strategy Strategy, op Operation) error {
if maxAttempts < 1 { if maxAttempts < 1 {
return fmt.Errorf("need at least 1 attempt to run op, but have %d max attempts", maxAttempts) return empty, fmt.Errorf("need at least 1 attempt to run op, but have %d max attempts", maxAttempts)
} }
var attempt int var attempt int
...@@ -43,16 +50,16 @@ func DoCtx(ctx context.Context, maxAttempts int, strategy Strategy, op Operation ...@@ -43,16 +50,16 @@ func DoCtx(ctx context.Context, maxAttempts int, strategy Strategy, op Operation
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
return ctx.Err() return empty, ctx.Err()
case <-reattemptCh: case <-reattemptCh:
attempt++ attempt++
err := op() ret, err := op()
if err == nil { if err == nil {
return nil return ret, nil
} }
if attempt == maxAttempts { if attempt == maxAttempts {
return &ErrFailedPermanently{ return empty, &ErrFailedPermanently{
attempts: maxAttempts, attempts: maxAttempts,
LastErr: err, LastErr: err,
} }
......
package backoff package backoff
import ( import (
"context"
"errors" "errors"
"testing" "testing"
"time" "time"
...@@ -14,20 +15,19 @@ func TestDo(t *testing.T) { ...@@ -14,20 +15,19 @@ func TestDo(t *testing.T) {
start := time.Now() start := time.Now()
var i int var i int
require.NoError(t, Do(2, strategy, func() error { _, err := Do(context.Background(), 2, strategy, func() (int, error) {
if i == 1 { if i == 1 {
return nil return 0, nil
} }
i++ i++
return dummyErr return 0, dummyErr
})) })
require.NoError(t, err)
require.True(t, time.Since(start) > 10*time.Millisecond) require.True(t, time.Since(start) > 10*time.Millisecond)
start = time.Now() start = time.Now()
// add one because the first attempt counts // add one because the first attempt counts
err := Do(3, strategy, func() error { _, err = Do(context.Background(), 3, strategy, func() (int, error) {
return dummyErr return 0, dummyErr
}) })
require.Equal(t, dummyErr, err.(*ErrFailedPermanently).LastErr) require.Equal(t, dummyErr, err.(*ErrFailedPermanently).LastErr)
require.True(t, time.Since(start) > 20*time.Millisecond) require.True(t, time.Since(start) > 20*time.Millisecond)
......
package client
import (
"context"
"fmt"
"net"
"net/url"
"time"
"github.com/ethereum-optimism/optimism/op-node/client"
"github.com/ethereum-optimism/optimism/op-node/sources"
"github.com/ethereum-optimism/optimism/op-service/backoff"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc"
)
// DefaultDialTimeout is a default timeout for dialing a client.
const DefaultDialTimeout = 1 * time.Minute
const defaultRetryCount = 30
const defaultRetryTime = 2 * time.Second
// DialEthClientWithTimeout attempts to dial the L1 provider using the provided
// URL. If the dial doesn't complete within defaultDialTimeout seconds, this
// method will return an error.
func DialEthClientWithTimeout(timeout time.Duration, log log.Logger, url string) (*ethclient.Client, error) {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
c, err := dialRPCClientWithBackoff(ctx, log, url)
if err != nil {
return nil, err
}
return ethclient.NewClient(c), nil
}
// DialRollupClientWithTimeout attempts to dial the RPC provider using the provided URL.
// If the dial doesn't complete within timeout seconds, this method will return an error.
func DialRollupClientWithTimeout(timeout time.Duration, log log.Logger, url string) (*sources.RollupClient, error) {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
rpcCl, err := dialRPCClientWithBackoff(ctx, log, url)
if err != nil {
return nil, err
}
return sources.NewRollupClient(client.NewBaseRPCClient(rpcCl)), nil
}
// Dials a JSON-RPC endpoint repeatedly, with a backoff, until a client connection is established. Auth is optional.
func dialRPCClientWithBackoff(ctx context.Context, log log.Logger, addr string) (*rpc.Client, error) {
bOff := backoff.Fixed(defaultRetryTime)
return backoff.Do(ctx, defaultRetryCount, bOff, func() (*rpc.Client, error) {
if !IsURLAvailable(addr) {
log.Warn("failed to dial address, but may connect later", "addr", addr)
return nil, fmt.Errorf("address unavailable (%s)", addr)
}
client, err := rpc.DialOptions(ctx, addr)
if err != nil {
return nil, fmt.Errorf("failed to dial address (%s): %w", addr, err)
}
return client, nil
})
}
func IsURLAvailable(address string) bool {
u, err := url.Parse(address)
if err != nil {
return false
}
conn, err := net.DialTimeout("tcp", u.Host, 5*time.Second)
if err != nil {
return false
}
conn.Close()
return true
}
package client
import (
"fmt"
"net"
"strings"
"testing"
"github.com/stretchr/testify/require"
)
func TestIsURLAvailable(t *testing.T) {
listener, err := net.Listen("tcp4", ":0")
require.NoError(t, err)
defer listener.Close()
a := listener.Addr().String()
parts := strings.Split(a, ":")
addr := fmt.Sprintf("http://localhost:%s", parts[1])
require.True(t, IsURLAvailable(addr))
require.False(t, IsURLAvailable("http://localhost:0"))
}
package client
import (
"context"
"time"
"github.com/ethereum/go-ethereum/ethclient"
)
// DialEthClientWithTimeout attempts to dial the L1 provider using the provided
// URL. If the dial doesn't complete within defaultDialTimeout seconds, this
// method will return an error.
func DialEthClientWithTimeout(ctx context.Context, url string, timeout time.Duration) (*ethclient.Client, error) {
ctxt, cancel := context.WithTimeout(ctx, timeout)
defer cancel()
return ethclient.DialContext(ctxt, url)
}
package client
import (
"context"
"time"
"github.com/ethereum-optimism/optimism/op-node/client"
"github.com/ethereum-optimism/optimism/op-node/sources"
"github.com/ethereum/go-ethereum/rpc"
)
// DialRollupClientWithTimeout attempts to dial the RPC provider using the provided
// URL. If the dial doesn't complete within defaultDialTimeout seconds, this
// method will return an error.
func DialRollupClientWithTimeout(ctx context.Context, url string, timeout time.Duration) (*sources.RollupClient, error) {
ctxt, cancel := context.WithTimeout(ctx, timeout)
defer cancel()
rpcCl, err := rpc.DialContext(ctxt, url)
if err != nil {
return nil, err
}
return sources.NewRollupClient(client.NewBaseRPCClient(rpcCl)), nil
}
package client
import (
"time"
)
// DefaultDialTimeout is a default timeout for dialing a client.
const DefaultDialTimeout = 5 * time.Second
...@@ -11,10 +11,11 @@ RUN apt-get update && \ ...@@ -11,10 +11,11 @@ RUN apt-get update && \
chmod +x ./rustup.sh && \ chmod +x ./rustup.sh && \
./rustup.sh -y ./rustup.sh -y
COPY ./.foundryrc ./.foundryrc COPY ./.abigenrc ./.abigenrc
# Only diff from upstream docker image is this clone instead # Only diff from upstream docker image is this clone instead
# of COPY. We select a specific commit to use. # of COPY. We select a specific commit to use.
COPY ./.foundryrc ./.foundryrc
RUN git clone https://github.com/foundry-rs/foundry.git ./foundry \ RUN git clone https://github.com/foundry-rs/foundry.git ./foundry \
&& cd foundry && git checkout $(cat ../.foundryrc) && cd foundry && git checkout $(cat ../.foundryrc)
...@@ -39,7 +40,6 @@ ENV DEBIAN_FRONTEND=noninteractive ...@@ -39,7 +40,6 @@ ENV DEBIAN_FRONTEND=noninteractive
COPY --from=foundry-build /opt/foundry/target/release/forge /usr/local/bin/forge COPY --from=foundry-build /opt/foundry/target/release/forge /usr/local/bin/forge
COPY --from=foundry-build /opt/foundry/target/release/cast /usr/local/bin/cast COPY --from=foundry-build /opt/foundry/target/release/cast /usr/local/bin/cast
COPY --from=foundry-build /opt/foundry/target/release/anvil /usr/local/bin/anvil COPY --from=foundry-build /opt/foundry/target/release/anvil /usr/local/bin/anvil
COPY --from=geth /usr/local/bin/abigen /usr/local/bin/abigen
COPY --from=echidna-test /usr/local/bin/echidna-test /usr/local/bin/echidna-test COPY --from=echidna-test /usr/local/bin/echidna-test /usr/local/bin/echidna-test
RUN apt-get update && \ RUN apt-get update && \
...@@ -56,6 +56,9 @@ RUN apt-get update && \ ...@@ -56,6 +56,9 @@ RUN apt-get update && \
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.53.3 && \ curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.53.3 && \
curl -fLSs https://raw.githubusercontent.com/CircleCI-Public/circleci-cli/master/install.sh | bash curl -fLSs https://raw.githubusercontent.com/CircleCI-Public/circleci-cli/master/install.sh | bash
# Install the specific version of abigen from .abigenrc
RUN go install github.com/ethereum/go-ethereum/cmd/abigen@$(cat .abigenrc)
# We need to isntall yarn because a bespoke dependency installed from github https://codeload.github.com/Saw-mon-and-Natalie/clones-with-immutable-arg needs it # We need to isntall yarn because a bespoke dependency installed from github https://codeload.github.com/Saw-mon-and-Natalie/clones-with-immutable-arg needs it
# it is installed from github which means it's postpack script which uses yarn is ran when unpacked into node_modules # it is installed from github which means it's postpack script which uses yarn is ran when unpacked into node_modules
RUN echo "downloading pnpm and yarn" && npm i -g pnpm && npm i -g yarn@1 && pnpm --version && yarn --version RUN echo "downloading pnpm and yarn" && npm i -g pnpm && npm i -g yarn@1 && pnpm --version && yarn --version
......
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
"@testing-library/jest-dom": "^5.17.0", "@testing-library/jest-dom": "^5.17.0",
"@testing-library/react-hooks": "^8.0.1", "@testing-library/react-hooks": "^8.0.1",
"@types/glob": "^8.1.0", "@types/glob": "^8.1.0",
"@vitest/coverage-istanbul": "^0.33.0", "@vitest/coverage-istanbul": "^0.34.1",
"@wagmi/cli": "^1.3.0", "@wagmi/cli": "^1.3.0",
"@wagmi/core": "^1.3.8", "@wagmi/core": "^1.3.8",
"abitype": "^0.9.3", "abitype": "^0.9.3",
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
"@eth-optimism/contracts-ts": "workspace:^", "@eth-optimism/contracts-ts": "workspace:^",
"@testing-library/jest-dom": "^5.17.0", "@testing-library/jest-dom": "^5.17.0",
"@testing-library/react-hooks": "^8.0.1", "@testing-library/react-hooks": "^8.0.1",
"@vitest/coverage-istanbul": "^0.33.0", "@vitest/coverage-istanbul": "^0.34.1",
"abitype": "^0.9.3", "abitype": "^0.9.3",
"isomorphic-fetch": "^3.0.0", "isomorphic-fetch": "^3.0.0",
"jest-dom": "link:@types/@testing-library/jest-dom", "jest-dom": "link:@types/@testing-library/jest-dom",
......
...@@ -314,8 +314,8 @@ importers: ...@@ -314,8 +314,8 @@ importers:
specifier: ^8.1.0 specifier: ^8.1.0
version: 8.1.0 version: 8.1.0
'@vitest/coverage-istanbul': '@vitest/coverage-istanbul':
specifier: ^0.33.0 specifier: ^0.34.1
version: 0.33.0(vitest@0.33.0) version: 0.34.1(vitest@0.33.0)
'@wagmi/cli': '@wagmi/cli':
specifier: ^1.3.0 specifier: ^1.3.0
version: 1.3.0(@wagmi/core@1.3.8)(typescript@5.1.6)(wagmi@1.0.1) version: 1.3.0(@wagmi/core@1.3.8)(typescript@5.1.6)(wagmi@1.0.1)
...@@ -414,8 +414,8 @@ importers: ...@@ -414,8 +414,8 @@ importers:
specifier: ^8.0.1 specifier: ^8.0.1
version: 8.0.1(react@17.0.2) version: 8.0.1(react@17.0.2)
'@vitest/coverage-istanbul': '@vitest/coverage-istanbul':
specifier: ^0.33.0 specifier: ^0.34.1
version: 0.33.0(vitest@0.33.0) version: 0.34.1(vitest@0.33.0)
abitype: abitype:
specifier: ^0.9.3 specifier: ^0.9.3
version: 0.9.3(typescript@5.1.6)(zod@3.21.4) version: 0.9.3(typescript@5.1.6)(zod@3.21.4)
...@@ -587,16 +587,6 @@ packages: ...@@ -587,16 +587,6 @@ packages:
semver: 6.3.0 semver: 6.3.0
dev: true dev: true
/@babel/generator@7.22.5:
resolution: {integrity: sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.22.5
'@jridgewell/gen-mapping': 0.3.3
'@jridgewell/trace-mapping': 0.3.18
jsesc: 2.5.2
dev: true
/@babel/generator@7.22.9: /@babel/generator@7.22.9:
resolution: {integrity: sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw==} resolution: {integrity: sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
...@@ -621,24 +611,11 @@ packages: ...@@ -621,24 +611,11 @@ packages:
semver: 6.3.1 semver: 6.3.1
dev: true dev: true
/@babel/helper-environment-visitor@7.18.2:
resolution: {integrity: sha512-14GQKWkX9oJzPiQQ7/J36FTXcD4kSp8egKjO9nINlSKiHITRA9q/R74qu8S9xlc/b/yjsJItQUeeh3xnGN0voQ==}
engines: {node: '>=6.9.0'}
dev: true
/@babel/helper-environment-visitor@7.22.5: /@babel/helper-environment-visitor@7.22.5:
resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dev: true dev: true
/@babel/helper-function-name@7.17.9:
resolution: {integrity: sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/template': 7.22.5
'@babel/types': 7.22.5
dev: true
/@babel/helper-function-name@7.22.5: /@babel/helper-function-name@7.22.5:
resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==} resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
...@@ -647,13 +624,6 @@ packages: ...@@ -647,13 +624,6 @@ packages:
'@babel/types': 7.22.5 '@babel/types': 7.22.5
dev: true dev: true
/@babel/helper-hoist-variables@7.16.7:
resolution: {integrity: sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.22.5
dev: true
/@babel/helper-hoist-variables@7.22.5: /@babel/helper-hoist-variables@7.22.5:
resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
...@@ -689,13 +659,6 @@ packages: ...@@ -689,13 +659,6 @@ packages:
'@babel/types': 7.22.5 '@babel/types': 7.22.5
dev: true dev: true
/@babel/helper-split-export-declaration@7.16.7:
resolution: {integrity: sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.22.5
dev: true
/@babel/helper-split-export-declaration@7.22.6: /@babel/helper-split-export-declaration@7.22.6:
resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
...@@ -749,14 +712,6 @@ packages: ...@@ -749,14 +712,6 @@ packages:
'@babel/types': 7.22.5 '@babel/types': 7.22.5
dev: true dev: true
/@babel/parser@7.22.5:
resolution: {integrity: sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==}
engines: {node: '>=6.0.0'}
hasBin: true
dependencies:
'@babel/types': 7.22.5
dev: true
/@babel/parser@7.22.7: /@babel/parser@7.22.7:
resolution: {integrity: sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==} resolution: {integrity: sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==}
engines: {node: '>=6.0.0'} engines: {node: '>=6.0.0'}
...@@ -792,12 +747,12 @@ packages: ...@@ -792,12 +747,12 @@ packages:
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/code-frame': 7.22.5 '@babel/code-frame': 7.22.5
'@babel/generator': 7.22.5 '@babel/generator': 7.22.9
'@babel/helper-environment-visitor': 7.18.2 '@babel/helper-environment-visitor': 7.22.5
'@babel/helper-function-name': 7.17.9 '@babel/helper-function-name': 7.22.5
'@babel/helper-hoist-variables': 7.16.7 '@babel/helper-hoist-variables': 7.22.5
'@babel/helper-split-export-declaration': 7.16.7 '@babel/helper-split-export-declaration': 7.22.6
'@babel/parser': 7.22.5 '@babel/parser': 7.22.7
'@babel/types': 7.22.5 '@babel/types': 7.22.5
debug: 4.3.4(supports-color@8.1.1) debug: 4.3.4(supports-color@8.1.1)
globals: 11.12.0 globals: 11.12.0
...@@ -4121,14 +4076,14 @@ packages: ...@@ -4121,14 +4076,14 @@ packages:
resolution: {integrity: sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==} resolution: {integrity: sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==}
dev: true dev: true
/@vitest/coverage-istanbul@0.33.0(vitest@0.33.0): /@vitest/coverage-istanbul@0.34.1(vitest@0.33.0):
resolution: {integrity: sha512-DGv6ybomCbLFGlNOGHgVCsaqHPWJWLp8JPrwzZo8I4vZ/O3muqTyZq5R52CZl0ENqgjFGWjra7yNPFUgxKf5pw==} resolution: {integrity: sha512-5GprlyY2t1g6+RrssWcN/w5RnZV3qIOM0eoaSDJw3jXbHpBpMvAfTg791zXo7PIqNYs5ORUqBWXIIU0gyAfZxA==}
peerDependencies: peerDependencies:
vitest: '>=0.32.0 <1' vitest: '>=0.32.0 <1'
dependencies: dependencies:
istanbul-lib-coverage: 3.2.0 istanbul-lib-coverage: 3.2.0
istanbul-lib-instrument: 5.2.1 istanbul-lib-instrument: 6.0.0
istanbul-lib-report: 3.0.0 istanbul-lib-report: 3.0.1
istanbul-lib-source-maps: 4.0.1 istanbul-lib-source-maps: 4.0.1
istanbul-reports: 3.1.5 istanbul-reports: 3.1.5
test-exclude: 6.0.0 test-exclude: 6.0.0
...@@ -4210,7 +4165,7 @@ packages: ...@@ -4210,7 +4165,7 @@ packages:
/@vue/compiler-core@3.2.36: /@vue/compiler-core@3.2.36:
resolution: {integrity: sha512-bbyZM5hvBicv0PW3KUfVi+x3ylHnfKG7DOn5wM+f2OztTzTjLEyBb/5yrarIYpmnGitVGbjZqDbODyW4iK8hqw==} resolution: {integrity: sha512-bbyZM5hvBicv0PW3KUfVi+x3ylHnfKG7DOn5wM+f2OztTzTjLEyBb/5yrarIYpmnGitVGbjZqDbODyW4iK8hqw==}
dependencies: dependencies:
'@babel/parser': 7.22.5 '@babel/parser': 7.22.7
'@vue/shared': 3.2.36 '@vue/shared': 3.2.36
estree-walker: 2.0.2 estree-walker: 2.0.2
source-map: 0.6.1 source-map: 0.6.1
...@@ -4226,7 +4181,7 @@ packages: ...@@ -4226,7 +4181,7 @@ packages:
/@vue/compiler-sfc@3.2.36: /@vue/compiler-sfc@3.2.36:
resolution: {integrity: sha512-AvGb4bTj4W8uQ4BqaSxo7UwTEqX5utdRSMyHy58OragWlt8nEACQ9mIeQh3K4di4/SX+41+pJrLIY01lHAOFOA==} resolution: {integrity: sha512-AvGb4bTj4W8uQ4BqaSxo7UwTEqX5utdRSMyHy58OragWlt8nEACQ9mIeQh3K4di4/SX+41+pJrLIY01lHAOFOA==}
dependencies: dependencies:
'@babel/parser': 7.22.5 '@babel/parser': 7.22.7
'@vue/compiler-core': 3.2.36 '@vue/compiler-core': 3.2.36
'@vue/compiler-dom': 3.2.36 '@vue/compiler-dom': 3.2.36
'@vue/compiler-ssr': 3.2.36 '@vue/compiler-ssr': 3.2.36
...@@ -4248,7 +4203,7 @@ packages: ...@@ -4248,7 +4203,7 @@ packages:
/@vue/reactivity-transform@3.2.36: /@vue/reactivity-transform@3.2.36:
resolution: {integrity: sha512-Jk5o2BhpODC9XTA7o4EL8hSJ4JyrFWErLtClG3NH8wDS7ri9jBDWxI7/549T7JY9uilKsaNM+4pJASLj5dtRwA==} resolution: {integrity: sha512-Jk5o2BhpODC9XTA7o4EL8hSJ4JyrFWErLtClG3NH8wDS7ri9jBDWxI7/549T7JY9uilKsaNM+4pJASLj5dtRwA==}
dependencies: dependencies:
'@babel/parser': 7.22.5 '@babel/parser': 7.22.7
'@vue/compiler-core': 3.2.36 '@vue/compiler-core': 3.2.36
'@vue/shared': 3.2.36 '@vue/shared': 3.2.36
estree-walker: 2.0.2 estree-walker: 2.0.2
...@@ -7493,6 +7448,7 @@ packages: ...@@ -7493,6 +7448,7 @@ packages:
/cookiejar@2.1.4: /cookiejar@2.1.4:
resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==}
requiresBuild: true
dev: true dev: true
/copy-descriptor@0.1.1: /copy-descriptor@0.1.1:
...@@ -12154,21 +12110,21 @@ packages: ...@@ -12154,21 +12110,21 @@ packages:
dependencies: dependencies:
'@babel/core': 7.22.9 '@babel/core': 7.22.9
'@istanbuljs/schema': 0.1.3 '@istanbuljs/schema': 0.1.3
istanbul-lib-coverage: 3.0.0 istanbul-lib-coverage: 3.2.0
semver: 6.3.1 semver: 6.3.1
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
/istanbul-lib-instrument@5.2.1: /istanbul-lib-instrument@6.0.0:
resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} resolution: {integrity: sha512-x58orMzEVfzPUKqlbLd1hXCnySCxKdDKa6Rjg97CwuLLRI4g3FHTdnExu1OqffVFay6zeMW+T6/DowFLndWnIw==}
engines: {node: '>=8'} engines: {node: '>=10'}
dependencies: dependencies:
'@babel/core': 7.22.9 '@babel/core': 7.22.9
'@babel/parser': 7.22.7 '@babel/parser': 7.22.7
'@istanbuljs/schema': 0.1.3 '@istanbuljs/schema': 0.1.3
istanbul-lib-coverage: 3.2.0 istanbul-lib-coverage: 3.2.0
semver: 6.3.1 semver: 7.5.4
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
...@@ -12179,7 +12135,7 @@ packages: ...@@ -12179,7 +12135,7 @@ packages:
dependencies: dependencies:
archy: 1.0.0 archy: 1.0.0
cross-spawn: 7.0.3 cross-spawn: 7.0.3
istanbul-lib-coverage: 3.0.0 istanbul-lib-coverage: 3.2.0
make-dir: 3.1.0 make-dir: 3.1.0
p-map: 3.0.0 p-map: 3.0.0
rimraf: 3.0.2 rimraf: 3.0.2
...@@ -12195,12 +12151,21 @@ packages: ...@@ -12195,12 +12151,21 @@ packages:
supports-color: 7.2.0 supports-color: 7.2.0
dev: true dev: true
/istanbul-lib-report@3.0.1:
resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==}
engines: {node: '>=10'}
dependencies:
istanbul-lib-coverage: 3.2.0
make-dir: 4.0.0
supports-color: 7.2.0
dev: true
/istanbul-lib-source-maps@4.0.0: /istanbul-lib-source-maps@4.0.0:
resolution: {integrity: sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==} resolution: {integrity: sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==}
engines: {node: '>=8'} engines: {node: '>=8'}
dependencies: dependencies:
debug: 4.3.4(supports-color@8.1.1) debug: 4.3.4(supports-color@8.1.1)
istanbul-lib-coverage: 3.0.0 istanbul-lib-coverage: 3.2.0
source-map: 0.6.1 source-map: 0.6.1
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
...@@ -12222,7 +12187,7 @@ packages: ...@@ -12222,7 +12187,7 @@ packages:
engines: {node: '>=8'} engines: {node: '>=8'}
dependencies: dependencies:
html-escaper: 2.0.2 html-escaper: 2.0.2
istanbul-lib-report: 3.0.0 istanbul-lib-report: 3.0.1
dev: true dev: true
/istanbul-reports@3.1.5: /istanbul-reports@3.1.5:
...@@ -12230,7 +12195,7 @@ packages: ...@@ -12230,7 +12195,7 @@ packages:
engines: {node: '>=8'} engines: {node: '>=8'}
dependencies: dependencies:
html-escaper: 2.0.2 html-escaper: 2.0.2
istanbul-lib-report: 3.0.0 istanbul-lib-report: 3.0.1
dev: true dev: true
/isurl@1.0.0: /isurl@1.0.0:
...@@ -13321,6 +13286,13 @@ packages: ...@@ -13321,6 +13286,13 @@ packages:
semver: 6.3.1 semver: 6.3.1
dev: true dev: true
/make-dir@4.0.0:
resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
engines: {node: '>=10'}
dependencies:
semver: 7.5.4
dev: true
/make-error@1.3.6: /make-error@1.3.6:
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment