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
0fd20eba
Commit
0fd20eba
authored
Mar 28, 2023
by
Joshua Gutow
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
txmgr: Configure timeouts better
parent
84773de7
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
95 additions
and
56 deletions
+95
-56
config.go
op-batcher/batcher/config.go
+2
-1
driver.go
op-batcher/batcher/driver.go
+11
-19
l2_proposer.go
op-e2e/actions/l2_proposer.go
+1
-0
setup.go
op-e2e/setup.go
+2
-0
config.go
op-proposer/proposer/config.go
+1
-0
l2_output_submitter.go
op-proposer/proposer/l2_output_submitter.go
+8
-11
utils.go
op-proposer/proposer/utils.go
+3
-1
cli.go
op-service/txmgr/cli.go
+49
-16
txmgr.go
op-service/txmgr/txmgr.go
+16
-6
txmgr_test.go
op-service/txmgr/txmgr_test.go
+2
-2
No files found.
op-batcher/batcher/config.go
View file @
0fd20eba
...
@@ -26,6 +26,7 @@ type Config struct {
...
@@ -26,6 +26,7 @@ type Config struct {
RollupNode
*
sources
.
RollupClient
RollupNode
*
sources
.
RollupClient
TxManager
txmgr
.
TxManager
TxManager
txmgr
.
TxManager
NetworkTimeout
time
.
Duration
PollInterval
time
.
Duration
PollInterval
time
.
Duration
// RollupConfig is queried at startup
// RollupConfig is queried at startup
...
...
op-batcher/batcher/driver.go
View file @
0fd20eba
...
@@ -80,6 +80,7 @@ func NewBatchSubmitterFromCLIConfig(cfg CLIConfig, l log.Logger, m metrics.Metri
...
@@ -80,6 +80,7 @@ func NewBatchSubmitterFromCLIConfig(cfg CLIConfig, l log.Logger, m metrics.Metri
L2Client
:
l2Client
,
L2Client
:
l2Client
,
RollupNode
:
rollupClient
,
RollupNode
:
rollupClient
,
PollInterval
:
cfg
.
PollInterval
,
PollInterval
:
cfg
.
PollInterval
,
NetworkTimeout
:
txManagerConfig
.
NetworkTimeout
,
TxManager
:
txManager
,
TxManager
:
txManager
,
Rollup
:
rcfg
,
Rollup
:
rcfg
,
Channel
:
ChannelConfig
{
Channel
:
ChannelConfig
{
...
@@ -223,7 +224,7 @@ func (l *BatchSubmitter) loadBlocksIntoState(ctx context.Context) {
...
@@ -223,7 +224,7 @@ func (l *BatchSubmitter) loadBlocksIntoState(ctx context.Context) {
// loadBlockIntoState fetches & stores a single block into `state`. It returns the block it loaded.
// loadBlockIntoState fetches & stores a single block into `state`. It returns the block it loaded.
func
(
l
*
BatchSubmitter
)
loadBlockIntoState
(
ctx
context
.
Context
,
blockNumber
uint64
)
(
*
types
.
Block
,
error
)
{
func
(
l
*
BatchSubmitter
)
loadBlockIntoState
(
ctx
context
.
Context
,
blockNumber
uint64
)
(
*
types
.
Block
,
error
)
{
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
txManager
Timeout
)
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
l
.
Network
Timeout
)
defer
cancel
()
defer
cancel
()
block
,
err
:=
l
.
L2Client
.
BlockByNumber
(
ctx
,
new
(
big
.
Int
)
.
SetUint64
(
blockNumber
))
block
,
err
:=
l
.
L2Client
.
BlockByNumber
(
ctx
,
new
(
big
.
Int
)
.
SetUint64
(
blockNumber
))
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -241,9 +242,9 @@ func (l *BatchSubmitter) loadBlockIntoState(ctx context.Context, blockNumber uin
...
@@ -241,9 +242,9 @@ func (l *BatchSubmitter) loadBlockIntoState(ctx context.Context, blockNumber uin
// calculateL2BlockRangeToStore determines the range (start,end] that should be loaded into the local state.
// calculateL2BlockRangeToStore determines the range (start,end] that should be loaded into the local state.
// It also takes care of initializing some local state (i.e. will modify l.lastStoredBlock in certain conditions)
// It also takes care of initializing some local state (i.e. will modify l.lastStoredBlock in certain conditions)
func
(
l
*
BatchSubmitter
)
calculateL2BlockRangeToStore
(
ctx
context
.
Context
)
(
eth
.
BlockID
,
eth
.
BlockID
,
error
)
{
func
(
l
*
BatchSubmitter
)
calculateL2BlockRangeToStore
(
ctx
context
.
Context
)
(
eth
.
BlockID
,
eth
.
BlockID
,
error
)
{
c
hildCtx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
txManager
Timeout
)
c
tx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
l
.
Network
Timeout
)
defer
cancel
()
defer
cancel
()
syncStatus
,
err
:=
l
.
RollupNode
.
SyncStatus
(
c
hildC
tx
)
syncStatus
,
err
:=
l
.
RollupNode
.
SyncStatus
(
ctx
)
// Ensure that we have the sync status
// Ensure that we have the sync status
if
err
!=
nil
{
if
err
!=
nil
{
return
eth
.
BlockID
{},
eth
.
BlockID
{},
fmt
.
Errorf
(
"failed to get sync status: %w"
,
err
)
return
eth
.
BlockID
{},
eth
.
BlockID
{},
fmt
.
Errorf
(
"failed to get sync status: %w"
,
err
)
...
@@ -343,13 +344,6 @@ func (l *BatchSubmitter) publishStateToL1(ctx context.Context) {
...
@@ -343,13 +344,6 @@ func (l *BatchSubmitter) publishStateToL1(ctx context.Context) {
}
}
}
}
const
networkTimeout
=
2
*
time
.
Second
// How long a single network request can take. TODO: put in a config somewhere
// fix(refcell):
// combined with above, these config variables should also be replicated in the op-proposer
// along with op-proposer changes to include the updated tx manager
const
txManagerTimeout
=
2
*
time
.
Minute
// How long the tx manager can take to send a transaction.
// sendTransaction creates & submits a transaction to the batch inbox address with the given `data`.
// sendTransaction creates & submits a transaction to the batch inbox address with the given `data`.
// It currently uses the underlying `txmgr` to handle transaction sending & price management.
// It currently uses the underlying `txmgr` to handle transaction sending & price management.
// This is a blocking method. It should not be called concurrently.
// This is a blocking method. It should not be called concurrently.
...
@@ -361,8 +355,6 @@ func (l *BatchSubmitter) sendTransaction(ctx context.Context, data []byte) (*typ
...
@@ -361,8 +355,6 @@ func (l *BatchSubmitter) sendTransaction(ctx context.Context, data []byte) (*typ
}
}
// Send the transaction through the txmgr
// Send the transaction through the txmgr
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
txManagerTimeout
)
defer
cancel
()
if
receipt
,
err
:=
l
.
txMgr
.
Send
(
ctx
,
txmgr
.
TxCandidate
{
if
receipt
,
err
:=
l
.
txMgr
.
Send
(
ctx
,
txmgr
.
TxCandidate
{
To
:
l
.
Rollup
.
BatchInboxAddress
,
To
:
l
.
Rollup
.
BatchInboxAddress
,
TxData
:
data
,
TxData
:
data
,
...
@@ -399,7 +391,7 @@ func (l *BatchSubmitter) recordConfirmedTx(id txID, receipt *types.Receipt) {
...
@@ -399,7 +391,7 @@ func (l *BatchSubmitter) recordConfirmedTx(id txID, receipt *types.Receipt) {
// l1Tip gets the current L1 tip as a L1BlockRef. The passed context is assumed
// l1Tip gets the current L1 tip as a L1BlockRef. The passed context is assumed
// to be a lifetime context, so it is internally wrapped with a network timeout.
// to be a lifetime context, so it is internally wrapped with a network timeout.
func
(
l
*
BatchSubmitter
)
l1Tip
(
ctx
context
.
Context
)
(
eth
.
L1BlockRef
,
error
)
{
func
(
l
*
BatchSubmitter
)
l1Tip
(
ctx
context
.
Context
)
(
eth
.
L1BlockRef
,
error
)
{
tctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
n
etworkTimeout
)
tctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
l
.
N
etworkTimeout
)
defer
cancel
()
defer
cancel
()
head
,
err
:=
l
.
L1Client
.
HeaderByNumber
(
tctx
,
nil
)
head
,
err
:=
l
.
L1Client
.
HeaderByNumber
(
tctx
,
nil
)
if
err
!=
nil
{
if
err
!=
nil
{
...
...
op-e2e/actions/l2_proposer.go
View file @
0fd20eba
...
@@ -53,6 +53,7 @@ func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Cl
...
@@ -53,6 +53,7 @@ func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Cl
proposerCfg
:=
proposer
.
Config
{
proposerCfg
:=
proposer
.
Config
{
L2OutputOracleAddr
:
cfg
.
OutputOracleAddr
,
L2OutputOracleAddr
:
cfg
.
OutputOracleAddr
,
PollInterval
:
time
.
Second
,
PollInterval
:
time
.
Second
,
NetworkTimeout
:
time
.
Second
,
L1Client
:
l1
,
L1Client
:
l1
,
RollupClient
:
rollupCl
,
RollupClient
:
rollupCl
,
AllowNonFinalized
:
cfg
.
AllowNonFinalized
,
AllowNonFinalized
:
cfg
.
AllowNonFinalized
,
...
...
op-e2e/setup.go
View file @
0fd20eba
...
@@ -579,6 +579,7 @@ func (cfg SystemConfig) Start(_opts ...SystemConfigOption) (*System, error) {
...
@@ -579,6 +579,7 @@ func (cfg SystemConfig) Start(_opts ...SystemConfigOption) (*System, error) {
SafeAbortNonceTooLowCount
:
3
,
SafeAbortNonceTooLowCount
:
3
,
ResubmissionTimeout
:
3
*
time
.
Second
,
ResubmissionTimeout
:
3
*
time
.
Second
,
ReceiptQueryInterval
:
50
*
time
.
Millisecond
,
ReceiptQueryInterval
:
50
*
time
.
Millisecond
,
NetworkTimeout
:
2
*
time
.
Second
,
},
},
AllowNonFinalized
:
cfg
.
NonFinalizedProposals
,
AllowNonFinalized
:
cfg
.
NonFinalizedProposals
,
LogConfig
:
oplog
.
CLIConfig
{
LogConfig
:
oplog
.
CLIConfig
{
...
@@ -613,6 +614,7 @@ func (cfg SystemConfig) Start(_opts ...SystemConfigOption) (*System, error) {
...
@@ -613,6 +614,7 @@ func (cfg SystemConfig) Start(_opts ...SystemConfigOption) (*System, error) {
SafeAbortNonceTooLowCount
:
3
,
SafeAbortNonceTooLowCount
:
3
,
ResubmissionTimeout
:
3
*
time
.
Second
,
ResubmissionTimeout
:
3
*
time
.
Second
,
ReceiptQueryInterval
:
50
*
time
.
Millisecond
,
ReceiptQueryInterval
:
50
*
time
.
Millisecond
,
NetworkTimeout
:
2
*
time
.
Second
,
},
},
LogConfig
:
oplog
.
CLIConfig
{
LogConfig
:
oplog
.
CLIConfig
{
Level
:
"info"
,
Level
:
"info"
,
...
...
op-proposer/proposer/config.go
View file @
0fd20eba
...
@@ -22,6 +22,7 @@ import (
...
@@ -22,6 +22,7 @@ import (
type
Config
struct
{
type
Config
struct
{
L2OutputOracleAddr
common
.
Address
L2OutputOracleAddr
common
.
Address
PollInterval
time
.
Duration
PollInterval
time
.
Duration
NetworkTimeout
time
.
Duration
TxManager
txmgr
.
TxManager
TxManager
txmgr
.
TxManager
L1Client
*
ethclient
.
Client
L1Client
*
ethclient
.
Client
RollupClient
*
sources
.
RollupClient
RollupClient
*
sources
.
RollupClient
...
...
op-proposer/proposer/l2_output_submitter.go
View file @
0fd20eba
...
@@ -28,12 +28,6 @@ import (
...
@@ -28,12 +28,6 @@ import (
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
)
)
const
(
// defaultDialTimeout is default duration the service will wait on
// startup to make a connection to either the L1 or L2 backends.
defaultDialTimeout
=
5
*
time
.
Second
)
var
supportedL2OutputVersion
=
eth
.
Bytes32
{}
var
supportedL2OutputVersion
=
eth
.
Bytes32
{}
// Main is the entrypoint into the L2 Output Submitter. This method executes the
// Main is the entrypoint into the L2 Output Submitter. This method executes the
...
@@ -139,6 +133,7 @@ type L2OutputSubmitter struct {
...
@@ -139,6 +133,7 @@ type L2OutputSubmitter struct {
allowNonFinalized
bool
allowNonFinalized
bool
// How frequently to poll L2 for new finalized outputs
// How frequently to poll L2 for new finalized outputs
pollInterval
time
.
Duration
pollInterval
time
.
Duration
networkTimeout
time
.
Duration
}
}
// NewL2OutputSubmitterFromCLIConfig creates a new L2 Output Submitter given the CLI Config
// NewL2OutputSubmitterFromCLIConfig creates a new L2 Output Submitter given the CLI Config
...
@@ -178,6 +173,7 @@ func NewL2OutputSubmitterConfigFromCLIConfig(cfg CLIConfig, l log.Logger) (*Conf
...
@@ -178,6 +173,7 @@ func NewL2OutputSubmitterConfigFromCLIConfig(cfg CLIConfig, l log.Logger) (*Conf
return
&
Config
{
return
&
Config
{
L2OutputOracleAddr
:
l2ooAddress
,
L2OutputOracleAddr
:
l2ooAddress
,
PollInterval
:
cfg
.
PollInterval
,
PollInterval
:
cfg
.
PollInterval
,
NetworkTimeout
:
txManagerConfig
.
NetworkTimeout
,
L1Client
:
l1Client
,
L1Client
:
l1Client
,
RollupClient
:
rollupClient
,
RollupClient
:
rollupClient
,
AllowNonFinalized
:
cfg
.
AllowNonFinalized
,
AllowNonFinalized
:
cfg
.
AllowNonFinalized
,
...
@@ -196,7 +192,7 @@ func NewL2OutputSubmitter(cfg Config, l log.Logger, m metrics.Metricer) (*L2Outp
...
@@ -196,7 +192,7 @@ func NewL2OutputSubmitter(cfg Config, l log.Logger, m metrics.Metricer) (*L2Outp
return
nil
,
err
return
nil
,
err
}
}
cCtx
,
cCancel
:=
context
.
WithTimeout
(
ctx
,
defaultDial
Timeout
)
cCtx
,
cCancel
:=
context
.
WithTimeout
(
ctx
,
cfg
.
Network
Timeout
)
defer
cCancel
()
defer
cCancel
()
version
,
err
:=
l2ooContract
.
Version
(
&
bind
.
CallOpts
{
Context
:
cCtx
})
version
,
err
:=
l2ooContract
.
Version
(
&
bind
.
CallOpts
{
Context
:
cCtx
})
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -227,6 +223,7 @@ func NewL2OutputSubmitter(cfg Config, l log.Logger, m metrics.Metricer) (*L2Outp
...
@@ -227,6 +223,7 @@ func NewL2OutputSubmitter(cfg Config, l log.Logger, m metrics.Metricer) (*L2Outp
allowNonFinalized
:
cfg
.
AllowNonFinalized
,
allowNonFinalized
:
cfg
.
AllowNonFinalized
,
pollInterval
:
cfg
.
PollInterval
,
pollInterval
:
cfg
.
PollInterval
,
networkTimeout
:
cfg
.
NetworkTimeout
,
},
nil
},
nil
}
}
...
@@ -245,7 +242,7 @@ func (l *L2OutputSubmitter) Stop() {
...
@@ -245,7 +242,7 @@ func (l *L2OutputSubmitter) Stop() {
// FetchNextOutputInfo gets the block number of the next proposal.
// FetchNextOutputInfo gets the block number of the next proposal.
// It returns: the next block number, if the proposal should be made, error
// It returns: the next block number, if the proposal should be made, error
func
(
l
*
L2OutputSubmitter
)
FetchNextOutputInfo
(
ctx
context
.
Context
)
(
*
eth
.
OutputResponse
,
bool
,
error
)
{
func
(
l
*
L2OutputSubmitter
)
FetchNextOutputInfo
(
ctx
context
.
Context
)
(
*
eth
.
OutputResponse
,
bool
,
error
)
{
cCtx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
defaultDial
Timeout
)
cCtx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
l
.
network
Timeout
)
defer
cancel
()
defer
cancel
()
callOpts
:=
&
bind
.
CallOpts
{
callOpts
:=
&
bind
.
CallOpts
{
From
:
l
.
txMgr
.
From
(),
From
:
l
.
txMgr
.
From
(),
...
@@ -257,7 +254,7 @@ func (l *L2OutputSubmitter) FetchNextOutputInfo(ctx context.Context) (*eth.Outpu
...
@@ -257,7 +254,7 @@ func (l *L2OutputSubmitter) FetchNextOutputInfo(ctx context.Context) (*eth.Outpu
return
nil
,
false
,
err
return
nil
,
false
,
err
}
}
// Fetch the current L2 heads
// Fetch the current L2 heads
cCtx
,
cancel
=
context
.
WithTimeout
(
ctx
,
defaultDial
Timeout
)
cCtx
,
cancel
=
context
.
WithTimeout
(
ctx
,
l
.
network
Timeout
)
defer
cancel
()
defer
cancel
()
status
,
err
:=
l
.
rollupClient
.
SyncStatus
(
cCtx
)
status
,
err
:=
l
.
rollupClient
.
SyncStatus
(
cCtx
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -281,7 +278,7 @@ func (l *L2OutputSubmitter) FetchNextOutputInfo(ctx context.Context) (*eth.Outpu
...
@@ -281,7 +278,7 @@ func (l *L2OutputSubmitter) FetchNextOutputInfo(ctx context.Context) (*eth.Outpu
}
}
func
(
l
*
L2OutputSubmitter
)
fetchOuput
(
ctx
context
.
Context
,
block
*
big
.
Int
)
(
*
eth
.
OutputResponse
,
bool
,
error
)
{
func
(
l
*
L2OutputSubmitter
)
fetchOuput
(
ctx
context
.
Context
,
block
*
big
.
Int
)
(
*
eth
.
OutputResponse
,
bool
,
error
)
{
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
defaultDial
Timeout
)
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
l
.
network
Timeout
)
defer
cancel
()
defer
cancel
()
output
,
err
:=
l
.
rollupClient
.
OutputAtBlock
(
ctx
,
block
.
Uint64
())
output
,
err
:=
l
.
rollupClient
.
OutputAtBlock
(
ctx
,
block
.
Uint64
())
if
err
!=
nil
{
if
err
!=
nil
{
...
...
op-proposer/proposer/utils.go
View file @
0fd20eba
...
@@ -3,6 +3,7 @@ package proposer
...
@@ -3,6 +3,7 @@ package proposer
import
(
import
(
"context"
"context"
"fmt"
"fmt"
"time"
"github.com/ethereum-optimism/optimism/op-node/client"
"github.com/ethereum-optimism/optimism/op-node/client"
"github.com/ethereum-optimism/optimism/op-node/sources"
"github.com/ethereum-optimism/optimism/op-node/sources"
...
@@ -11,11 +12,12 @@ import (
...
@@ -11,11 +12,12 @@ import (
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/rpc"
)
)
var
defaultDialTimeout
=
5
*
time
.
Second
// dialEthClientWithTimeout attempts to dial the L1 provider using the provided
// dialEthClientWithTimeout attempts to dial the L1 provider using the provided
// URL. If the dial doesn't complete within defaultDialTimeout seconds, this
// URL. If the dial doesn't complete within defaultDialTimeout seconds, this
// method will return an error.
// method will return an error.
func
dialEthClientWithTimeout
(
ctx
context
.
Context
,
url
string
)
(
*
ethclient
.
Client
,
error
)
{
func
dialEthClientWithTimeout
(
ctx
context
.
Context
,
url
string
)
(
*
ethclient
.
Client
,
error
)
{
ctxt
,
cancel
:=
context
.
WithTimeout
(
ctx
,
defaultDialTimeout
)
ctxt
,
cancel
:=
context
.
WithTimeout
(
ctx
,
defaultDialTimeout
)
defer
cancel
()
defer
cancel
()
...
...
op-service/txmgr/cli.go
View file @
0fd20eba
...
@@ -22,10 +22,13 @@ const (
...
@@ -22,10 +22,13 @@ const (
MnemonicFlagName
=
"mnemonic"
MnemonicFlagName
=
"mnemonic"
HDPathFlagName
=
"hd-path"
HDPathFlagName
=
"hd-path"
PrivateKeyFlagName
=
"private-key"
PrivateKeyFlagName
=
"private-key"
//
Legacy TxMgr Flags
//
TxMgr Flags (new + legacy + some shared flags)
NumConfirmationsFlagName
=
"num-confirmations"
NumConfirmationsFlagName
=
"num-confirmations"
SafeAbortNonceTooLowCountFlagName
=
"safe-abort-nonce-too-low-count"
SafeAbortNonceTooLowCountFlagName
=
"safe-abort-nonce-too-low-count"
ResubmissionTimeoutFlagName
=
"resubmission-timeout"
ResubmissionTimeoutFlagName
=
"resubmission-timeout"
NetworkTimeoutFlagName
=
"network-timeout"
TxSendTimeoutFlagName
=
"txmgr.send-timeout"
ReceiptQueryIntervalFlagName
=
"txmgr.receipt-query-interval"
)
)
var
(
var
(
...
@@ -69,17 +72,35 @@ func CLIFlags(envPrefix string) []cli.Flag {
...
@@ -69,17 +72,35 @@ func CLIFlags(envPrefix string) []cli.Flag {
EnvVar
:
opservice
.
PrefixEnvVar
(
envPrefix
,
"NUM_CONFIRMATIONS"
),
EnvVar
:
opservice
.
PrefixEnvVar
(
envPrefix
,
"NUM_CONFIRMATIONS"
),
},
},
cli
.
Uint64Flag
{
cli
.
Uint64Flag
{
Name
:
"safe-abort-nonce-too-low-count"
,
Name
:
SafeAbortNonceTooLowCountFlagName
,
Usage
:
"Number of ErrNonceTooLow observations required to give up on a tx at a particular nonce without receiving confirmation"
,
Usage
:
"Number of ErrNonceTooLow observations required to give up on a tx at a particular nonce without receiving confirmation"
,
Value
:
3
,
Value
:
3
,
EnvVar
:
opservice
.
PrefixEnvVar
(
envPrefix
,
"SAFE_ABORT_NONCE_TOO_LOW_COUNT"
),
EnvVar
:
opservice
.
PrefixEnvVar
(
envPrefix
,
"SAFE_ABORT_NONCE_TOO_LOW_COUNT"
),
},
},
cli
.
DurationFlag
{
cli
.
DurationFlag
{
Name
:
"resubmission-timeout"
,
Name
:
ResubmissionTimeoutFlagName
,
Usage
:
"Duration we will wait before resubmitting a transaction to L1"
,
Usage
:
"Duration we will wait before resubmitting a transaction to L1"
,
Value
:
30
*
time
.
Second
,
Value
:
30
*
time
.
Second
,
EnvVar
:
opservice
.
PrefixEnvVar
(
envPrefix
,
"RESUBMISSION_TIMEOUT"
),
EnvVar
:
opservice
.
PrefixEnvVar
(
envPrefix
,
"RESUBMISSION_TIMEOUT"
),
},
},
cli
.
DurationFlag
{
Name
:
NetworkTimeoutFlagName
,
Usage
:
"Timeout for all network operations"
,
Value
:
2
*
time
.
Second
,
EnvVar
:
opservice
.
PrefixEnvVar
(
envPrefix
,
"NETWORK_TIMEOUT"
),
},
cli
.
DurationFlag
{
Name
:
TxSendTimeoutFlagName
,
Usage
:
"Timeout for sending transactions. If 0 it is disabled."
,
Value
:
0
,
EnvVar
:
opservice
.
PrefixEnvVar
(
envPrefix
,
"TXMGR_TX_SEND_TIMEOUT"
),
},
cli
.
DurationFlag
{
Name
:
ReceiptQueryIntervalFlagName
,
Usage
:
"Frequency to poll for receipts"
,
Value
:
30
*
time
.
Second
,
EnvVar
:
opservice
.
PrefixEnvVar
(
envPrefix
,
"TXMGR_RECEIPT_QUERY_INTERVAL"
),
},
},
client
.
CLIFlags
(
envPrefix
)
...
)
},
client
.
CLIFlags
(
envPrefix
)
...
)
}
}
...
@@ -95,6 +116,8 @@ type CLIConfig struct {
...
@@ -95,6 +116,8 @@ type CLIConfig struct {
SafeAbortNonceTooLowCount
uint64
SafeAbortNonceTooLowCount
uint64
ResubmissionTimeout
time
.
Duration
ResubmissionTimeout
time
.
Duration
ReceiptQueryInterval
time
.
Duration
ReceiptQueryInterval
time
.
Duration
NetworkTimeout
time
.
Duration
TxSendTimeout
time
.
Duration
}
}
func
(
m
CLIConfig
)
Check
()
error
{
func
(
m
CLIConfig
)
Check
()
error
{
...
@@ -104,6 +127,15 @@ func (m CLIConfig) Check() error {
...
@@ -104,6 +127,15 @@ func (m CLIConfig) Check() error {
if
m
.
NumConfirmations
==
0
{
if
m
.
NumConfirmations
==
0
{
return
errors
.
New
(
"num confirmations must not be 0"
)
return
errors
.
New
(
"num confirmations must not be 0"
)
}
}
if
m
.
NetworkTimeout
==
0
{
return
errors
.
New
(
"must provide a network timeout"
)
}
if
m
.
ResubmissionTimeout
==
0
{
return
errors
.
New
(
"must provide a resumbission interval"
)
}
if
m
.
ReceiptQueryInterval
==
0
{
return
errors
.
New
(
"must provide a receipt query interval"
)
}
if
err
:=
m
.
SignerCLIConfig
.
Check
();
err
!=
nil
{
if
err
:=
m
.
SignerCLIConfig
.
Check
();
err
!=
nil
{
return
err
return
err
}
}
...
@@ -122,6 +154,9 @@ func ReadCLIConfig(ctx *cli.Context) CLIConfig {
...
@@ -122,6 +154,9 @@ func ReadCLIConfig(ctx *cli.Context) CLIConfig {
NumConfirmations
:
ctx
.
GlobalUint64
(
NumConfirmationsFlagName
),
NumConfirmations
:
ctx
.
GlobalUint64
(
NumConfirmationsFlagName
),
SafeAbortNonceTooLowCount
:
ctx
.
GlobalUint64
(
SafeAbortNonceTooLowCountFlagName
),
SafeAbortNonceTooLowCount
:
ctx
.
GlobalUint64
(
SafeAbortNonceTooLowCountFlagName
),
ResubmissionTimeout
:
ctx
.
GlobalDuration
(
ResubmissionTimeoutFlagName
),
ResubmissionTimeout
:
ctx
.
GlobalDuration
(
ResubmissionTimeoutFlagName
),
ReceiptQueryInterval
:
ctx
.
GlobalDuration
(
ReceiptQueryIntervalFlagName
),
NetworkTimeout
:
ctx
.
GlobalDuration
(
NetworkTimeoutFlagName
),
TxSendTimeout
:
ctx
.
GlobalDuration
(
TxSendTimeoutFlagName
),
}
}
}
}
...
@@ -130,21 +165,21 @@ func NewConfig(cfg CLIConfig, l log.Logger) (Config, error) {
...
@@ -130,21 +165,21 @@ func NewConfig(cfg CLIConfig, l log.Logger) (Config, error) {
return
Config
{},
err
return
Config
{},
err
}
}
networkTimeout
:=
2
*
time
.
Second
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
cfg
.
NetworkTimeout
)
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
networkTimeout
)
defer
cancel
()
defer
cancel
()
l1
,
err
:=
ethclient
.
DialContext
(
ctx
,
cfg
.
L1RPCURL
)
l1
,
err
:=
ethclient
.
DialContext
(
ctx
,
cfg
.
L1RPCURL
)
if
err
!=
nil
{
if
err
!=
nil
{
return
Config
{},
err
return
Config
{},
err
}
}
ctx
,
cancel
=
context
.
WithTimeout
(
context
.
Background
(),
n
etworkTimeout
)
ctx
,
cancel
=
context
.
WithTimeout
(
context
.
Background
(),
cfg
.
N
etworkTimeout
)
defer
cancel
()
defer
cancel
()
chainID
,
err
:=
l1
.
ChainID
(
ctx
)
chainID
,
err
:=
l1
.
ChainID
(
ctx
)
if
err
!=
nil
{
if
err
!=
nil
{
return
Config
{},
err
return
Config
{},
err
}
}
// Allow backwards compatible ways of specifying the HD path
hdPath
:=
cfg
.
HDPath
hdPath
:=
cfg
.
HDPath
if
hdPath
==
""
&&
cfg
.
SequencerHDPath
!=
""
{
if
hdPath
==
""
&&
cfg
.
SequencerHDPath
!=
""
{
hdPath
=
cfg
.
SequencerHDPath
hdPath
=
cfg
.
SequencerHDPath
...
@@ -157,17 +192,13 @@ func NewConfig(cfg CLIConfig, l log.Logger) (Config, error) {
...
@@ -157,17 +192,13 @@ func NewConfig(cfg CLIConfig, l log.Logger) (Config, error) {
return
Config
{},
err
return
Config
{},
err
}
}
receiptQueryInterval
:=
30
*
time
.
Second
if
cfg
.
ReceiptQueryInterval
!=
0
{
receiptQueryInterval
=
cfg
.
ReceiptQueryInterval
}
return
Config
{
return
Config
{
Backend
:
l1
,
Backend
:
l1
,
ResubmissionTimeout
:
cfg
.
ResubmissionTimeout
,
ResubmissionTimeout
:
cfg
.
ResubmissionTimeout
,
ChainID
:
chainID
,
ChainID
:
chainID
,
NetworkTimeout
:
networkTimeout
,
TxSendTimeout
:
cfg
.
TxSendTimeout
,
ReceiptQueryInterval
:
receiptQueryInterval
,
NetworkTimeout
:
cfg
.
NetworkTimeout
,
ReceiptQueryInterval
:
cfg
.
ReceiptQueryInterval
,
NumConfirmations
:
cfg
.
NumConfirmations
,
NumConfirmations
:
cfg
.
NumConfirmations
,
SafeAbortNonceTooLowCount
:
cfg
.
SafeAbortNonceTooLowCount
,
SafeAbortNonceTooLowCount
:
cfg
.
SafeAbortNonceTooLowCount
,
Signer
:
signerFactory
(
chainID
),
Signer
:
signerFactory
(
chainID
),
...
@@ -187,10 +218,12 @@ type Config struct {
...
@@ -187,10 +218,12 @@ type Config struct {
// ChainID is the chain ID of the L1 chain.
// ChainID is the chain ID of the L1 chain.
ChainID
*
big
.
Int
ChainID
*
big
.
Int
// TxSendTimeout is how long to wait for sending a transaction.
// By default it is unbounded. If set, this is recommended to be at least 20 minutes.
TxSendTimeout
time
.
Duration
// NetworkTimeout is the allowed duration for a single network request.
// NetworkTimeout is the allowed duration for a single network request.
// This is intended to be used for network requests that can be replayed.
// This is intended to be used for network requests that can be replayed.
//
// If not set, this will default to 2 seconds.
NetworkTimeout
time
.
Duration
NetworkTimeout
time
.
Duration
// RequireQueryInterval is the interval at which the tx manager will
// RequireQueryInterval is the interval at which the tx manager will
...
...
op-service/txmgr/txmgr.go
View file @
0fd20eba
...
@@ -126,6 +126,11 @@ type TxCandidate struct {
...
@@ -126,6 +126,11 @@ type TxCandidate struct {
//
//
// NOTE: Send should be called by AT MOST one caller at a time.
// NOTE: Send should be called by AT MOST one caller at a time.
func
(
m
*
SimpleTxManager
)
Send
(
ctx
context
.
Context
,
candidate
TxCandidate
)
(
*
types
.
Receipt
,
error
)
{
func
(
m
*
SimpleTxManager
)
Send
(
ctx
context
.
Context
,
candidate
TxCandidate
)
(
*
types
.
Receipt
,
error
)
{
if
m
.
cfg
.
TxSendTimeout
!=
0
{
var
cancel
context
.
CancelFunc
ctx
,
cancel
=
context
.
WithTimeout
(
ctx
,
m
.
cfg
.
TxSendTimeout
)
defer
cancel
()
}
tx
,
err
:=
m
.
craftTx
(
ctx
,
candidate
)
tx
,
err
:=
m
.
craftTx
(
ctx
,
candidate
)
if
err
!=
nil
{
if
err
!=
nil
{
m
.
l
.
Error
(
"Failed to create the transaction"
,
"err"
,
err
)
m
.
l
.
Error
(
"Failed to create the transaction"
,
"err"
,
err
)
...
@@ -217,7 +222,9 @@ func (m *SimpleTxManager) send(ctx context.Context, tx *types.Transaction) (*typ
...
@@ -217,7 +222,9 @@ func (m *SimpleTxManager) send(ctx context.Context, tx *types.Transaction) (*typ
log
:=
m
.
l
.
New
(
"txHash"
,
txHash
,
"nonce"
,
nonce
,
"gasTipCap"
,
gasTipCap
,
"gasFeeCap"
,
gasFeeCap
)
log
:=
m
.
l
.
New
(
"txHash"
,
txHash
,
"nonce"
,
nonce
,
"gasTipCap"
,
gasTipCap
,
"gasFeeCap"
,
gasFeeCap
)
log
.
Info
(
"publishing transaction"
)
log
.
Info
(
"publishing transaction"
)
err
:=
m
.
backend
.
SendTransaction
(
ctx
,
tx
)
cCtx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
m
.
cfg
.
NetworkTimeout
)
defer
cancel
()
err
:=
m
.
backend
.
SendTransaction
(
cCtx
,
tx
)
sendState
.
ProcessSendError
(
err
)
sendState
.
ProcessSendError
(
err
)
if
err
!=
nil
{
if
err
!=
nil
{
if
errors
.
Is
(
err
,
context
.
Canceled
)
{
if
errors
.
Is
(
err
,
context
.
Canceled
)
{
...
@@ -232,7 +239,6 @@ func (m *SimpleTxManager) send(ctx context.Context, tx *types.Transaction) (*typ
...
@@ -232,7 +239,6 @@ func (m *SimpleTxManager) send(ctx context.Context, tx *types.Transaction) (*typ
log
.
Warn
(
"Aborting transaction submission"
)
log
.
Warn
(
"Aborting transaction submission"
)
cancel
()
cancel
()
}
}
// TODO(conner): add retry?
return
return
}
}
...
@@ -279,7 +285,7 @@ func (m *SimpleTxManager) send(ctx context.Context, tx *types.Transaction) (*typ
...
@@ -279,7 +285,7 @@ func (m *SimpleTxManager) send(ctx context.Context, tx *types.Transaction) (*typ
}
}
// Increase the gas price & submit the new transaction
// Increase the gas price & submit the new transaction
newTx
,
err
:=
m
.
I
ncreaseGasPrice
(
ctx
,
tx
)
newTx
,
err
:=
m
.
i
ncreaseGasPrice
(
ctx
,
tx
)
if
err
!=
nil
{
if
err
!=
nil
{
m
.
l
.
Error
(
"Failed to increase the gas price for the tx"
,
"err"
,
err
)
m
.
l
.
Error
(
"Failed to increase the gas price for the tx"
,
"err"
,
err
)
// Don't `continue` here so we resubmit the transaction with the same gas price.
// Don't `continue` here so we resubmit the transaction with the same gas price.
...
@@ -311,7 +317,9 @@ func (m *SimpleTxManager) waitMined(ctx context.Context, tx *types.Transaction,
...
@@ -311,7 +317,9 @@ func (m *SimpleTxManager) waitMined(ctx context.Context, tx *types.Transaction,
txHash
:=
tx
.
Hash
()
txHash
:=
tx
.
Hash
()
for
{
for
{
receipt
,
err
:=
m
.
backend
.
TransactionReceipt
(
ctx
,
txHash
)
cCtx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
m
.
cfg
.
NetworkTimeout
)
receipt
,
err
:=
m
.
backend
.
TransactionReceipt
(
cCtx
,
txHash
)
cancel
()
switch
{
switch
{
case
receipt
!=
nil
:
case
receipt
!=
nil
:
if
sendState
!=
nil
{
if
sendState
!=
nil
{
...
@@ -384,14 +392,14 @@ func (m *SimpleTxManager) suggestGasPriceCaps(ctx context.Context) (*big.Int, *b
...
@@ -384,14 +392,14 @@ func (m *SimpleTxManager) suggestGasPriceCaps(ctx context.Context) (*big.Int, *b
return
tip
,
head
.
BaseFee
,
nil
return
tip
,
head
.
BaseFee
,
nil
}
}
//
I
ncreaseGasPrice takes the previous transaction & potentially clones then signs it with a higher tip.
//
i
ncreaseGasPrice takes the previous transaction & potentially clones then signs it with a higher tip.
// If the tip + basefee suggested by the network are not greater than the previous values, the same transaction
// If the tip + basefee suggested by the network are not greater than the previous values, the same transaction
// will be returned. If they are greater, this function will ensure that they are at least greater by 15% than
// will be returned. If they are greater, this function will ensure that they are at least greater by 15% than
// the previous transaction's value to ensure that the price bump is large enough.
// the previous transaction's value to ensure that the price bump is large enough.
//
//
// We do not re-estimate the amount of gas used because for some stateful transactions (like output proposals) the
// We do not re-estimate the amount of gas used because for some stateful transactions (like output proposals) the
// act of including the transaction renders the repeat of the transaction invalid.
// act of including the transaction renders the repeat of the transaction invalid.
func
(
m
*
SimpleTxManager
)
I
ncreaseGasPrice
(
ctx
context
.
Context
,
tx
*
types
.
Transaction
)
(
*
types
.
Transaction
,
error
)
{
func
(
m
*
SimpleTxManager
)
i
ncreaseGasPrice
(
ctx
context
.
Context
,
tx
*
types
.
Transaction
)
(
*
types
.
Transaction
,
error
)
{
tip
,
basefee
,
err
:=
m
.
suggestGasPriceCaps
(
ctx
)
tip
,
basefee
,
err
:=
m
.
suggestGasPriceCaps
(
ctx
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
...
@@ -413,6 +421,8 @@ func (m *SimpleTxManager) IncreaseGasPrice(ctx context.Context, tx *types.Transa
...
@@ -413,6 +421,8 @@ func (m *SimpleTxManager) IncreaseGasPrice(ctx context.Context, tx *types.Transa
Data
:
tx
.
Data
(),
Data
:
tx
.
Data
(),
AccessList
:
tx
.
AccessList
(),
AccessList
:
tx
.
AccessList
(),
}
}
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
m
.
cfg
.
NetworkTimeout
)
defer
cancel
()
return
m
.
cfg
.
Signer
(
ctx
,
m
.
cfg
.
From
,
types
.
NewTx
(
rawTx
))
return
m
.
cfg
.
Signer
(
ctx
,
m
.
cfg
.
From
,
types
.
NewTx
(
rawTx
))
}
}
...
...
op-service/txmgr/txmgr_test.go
View file @
0fd20eba
...
@@ -724,7 +724,7 @@ func doGasPriceIncrease(t *testing.T, txTipCap, txFeeCap, newTip, newBaseFee int
...
@@ -724,7 +724,7 @@ func doGasPriceIncrease(t *testing.T, txTipCap, txFeeCap, newTip, newBaseFee int
GasTipCap
:
big
.
NewInt
(
txTipCap
),
GasTipCap
:
big
.
NewInt
(
txTipCap
),
GasFeeCap
:
big
.
NewInt
(
txFeeCap
),
GasFeeCap
:
big
.
NewInt
(
txFeeCap
),
})
})
newTx
,
err
:=
mgr
.
I
ncreaseGasPrice
(
context
.
Background
(),
tx
)
newTx
,
err
:=
mgr
.
i
ncreaseGasPrice
(
context
.
Background
(),
tx
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
return
tx
,
newTx
return
tx
,
newTx
}
}
...
@@ -831,7 +831,7 @@ func TestIncreaseGasPriceNotExponential(t *testing.T) {
...
@@ -831,7 +831,7 @@ func TestIncreaseGasPriceNotExponential(t *testing.T) {
// Run IncreaseGasPrice a bunch of times in a row to simulate a very fast resubmit loop.
// Run IncreaseGasPrice a bunch of times in a row to simulate a very fast resubmit loop.
for
i
:=
0
;
i
<
20
;
i
++
{
for
i
:=
0
;
i
<
20
;
i
++
{
ctx
:=
context
.
Background
()
ctx
:=
context
.
Background
()
newTx
,
err
:=
mgr
.
I
ncreaseGasPrice
(
ctx
,
tx
)
newTx
,
err
:=
mgr
.
i
ncreaseGasPrice
(
ctx
,
tx
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
require
.
True
(
t
,
newTx
.
GasFeeCap
()
.
Cmp
(
feeCap
)
==
0
,
"new tx fee cap must be equal L1"
)
require
.
True
(
t
,
newTx
.
GasFeeCap
()
.
Cmp
(
feeCap
)
==
0
,
"new tx fee cap must be equal L1"
)
require
.
True
(
t
,
newTx
.
GasTipCap
()
.
Cmp
(
borkedBackend
.
gasTip
)
==
0
,
"new tx tip must be equal L1"
)
require
.
True
(
t
,
newTx
.
GasTipCap
()
.
Cmp
(
borkedBackend
.
gasTip
)
==
0
,
"new tx tip must be equal L1"
)
...
...
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