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
0537c858
Unverified
Commit
0537c858
authored
Jun 25, 2023
by
Roberto Bayardo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix typo & log more fields for output proposal tx failure
parent
8ddf2cd4
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
90 additions
and
7 deletions
+90
-7
responder_test.go
op-challenger/fault/responder_test.go
+4
-0
l2_proposer.go
op-e2e/actions/l2_proposer.go
+3
-0
l2_output_submitter.go
op-proposer/proposer/l2_output_submitter.go
+46
-6
TxManager.go
op-service/txmgr/mocks/TxManager.go
+24
-0
txmgr.go
op-service/txmgr/txmgr.go
+13
-1
No files found.
op-challenger/fault/responder_test.go
View file @
0537c858
...
@@ -40,6 +40,10 @@ func (m *mockTxManager) Send(ctx context.Context, candidate txmgr.TxCandidate) (
...
@@ -40,6 +40,10 @@ func (m *mockTxManager) Send(ctx context.Context, candidate txmgr.TxCandidate) (
),
nil
),
nil
}
}
func
(
m
*
mockTxManager
)
BlockNumber
(
ctx
context
.
Context
)
(
uint64
,
error
)
{
panic
(
"not implemented"
)
}
func
(
m
*
mockTxManager
)
From
()
common
.
Address
{
func
(
m
*
mockTxManager
)
From
()
common
.
Address
{
return
m
.
from
return
m
.
from
}
}
...
...
op-e2e/actions/l2_proposer.go
View file @
0537c858
...
@@ -44,6 +44,9 @@ type fakeTxMgr struct {
...
@@ -44,6 +44,9 @@ type fakeTxMgr struct {
func
(
f
fakeTxMgr
)
From
()
common
.
Address
{
func
(
f
fakeTxMgr
)
From
()
common
.
Address
{
return
f
.
from
return
f
.
from
}
}
func
(
f
fakeTxMgr
)
BlockNumber
(
_
context
.
Context
)
(
uint64
,
error
)
{
panic
(
"unimplemented"
)
}
func
(
f
fakeTxMgr
)
Send
(
_
context
.
Context
,
_
txmgr
.
TxCandidate
)
(
*
types
.
Receipt
,
error
)
{
func
(
f
fakeTxMgr
)
Send
(
_
context
.
Context
,
_
txmgr
.
TxCandidate
)
(
*
types
.
Receipt
,
error
)
{
panic
(
"unimplemented"
)
panic
(
"unimplemented"
)
}
}
...
...
op-proposer/proposer/l2_output_submitter.go
View file @
0537c858
...
@@ -259,6 +259,7 @@ func (l *L2OutputSubmitter) FetchNextOutputInfo(ctx context.Context) (*eth.Outpu
...
@@ -259,6 +259,7 @@ func (l *L2OutputSubmitter) FetchNextOutputInfo(ctx context.Context) (*eth.Outpu
l
.
log
.
Error
(
"proposer unable to get sync status"
,
"err"
,
err
)
l
.
log
.
Error
(
"proposer unable to get sync status"
,
"err"
,
err
)
return
nil
,
false
,
err
return
nil
,
false
,
err
}
}
// Use either the finalized or safe head depending on the config. Finalized head is default & safer.
// Use either the finalized or safe head depending on the config. Finalized head is default & safer.
var
currentBlockNumber
*
big
.
Int
var
currentBlockNumber
*
big
.
Int
if
l
.
allowNonFinalized
{
if
l
.
allowNonFinalized
{
...
@@ -268,14 +269,14 @@ func (l *L2OutputSubmitter) FetchNextOutputInfo(ctx context.Context) (*eth.Outpu
...
@@ -268,14 +269,14 @@ func (l *L2OutputSubmitter) FetchNextOutputInfo(ctx context.Context) (*eth.Outpu
}
}
// Ensure that we do not submit a block in the future
// Ensure that we do not submit a block in the future
if
currentBlockNumber
.
Cmp
(
nextCheckpointBlock
)
<
0
{
if
currentBlockNumber
.
Cmp
(
nextCheckpointBlock
)
<
0
{
l
.
log
.
Info
(
"proposer submission interval has not elapsed"
,
"currentBlockNumber"
,
currentBlockNumber
,
"nextBlockNumber"
,
nextCheckpointBlock
)
l
.
log
.
Debug
(
"proposer submission interval has not elapsed"
,
"currentBlockNumber"
,
currentBlockNumber
,
"nextBlockNumber"
,
nextCheckpointBlock
)
return
nil
,
false
,
nil
return
nil
,
false
,
nil
}
}
return
l
.
fetchOuput
(
ctx
,
nextCheckpointBlock
)
return
l
.
fetchOu
t
put
(
ctx
,
nextCheckpointBlock
)
}
}
func
(
l
*
L2OutputSubmitter
)
fetchOuput
(
ctx
context
.
Context
,
block
*
big
.
Int
)
(
*
eth
.
OutputResponse
,
bool
,
error
)
{
func
(
l
*
L2OutputSubmitter
)
fetchOu
t
put
(
ctx
context
.
Context
,
block
*
big
.
Int
)
(
*
eth
.
OutputResponse
,
bool
,
error
)
{
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
l
.
networkTimeout
)
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
l
.
networkTimeout
)
defer
cancel
()
defer
cancel
()
output
,
err
:=
l
.
rollupClient
.
OutputAtBlock
(
ctx
,
block
.
Uint64
())
output
,
err
:=
l
.
rollupClient
.
OutputAtBlock
(
ctx
,
block
.
Uint64
())
...
@@ -319,8 +320,41 @@ func proposeL2OutputTxData(abi *abi.ABI, output *eth.OutputResponse) ([]byte, er
...
@@ -319,8 +320,41 @@ func proposeL2OutputTxData(abi *abi.ABI, output *eth.OutputResponse) ([]byte, er
new
(
big
.
Int
)
.
SetUint64
(
output
.
Status
.
CurrentL1
.
Number
))
new
(
big
.
Int
)
.
SetUint64
(
output
.
Status
.
CurrentL1
.
Number
))
}
}
// We wait until l1head advances beyond blocknum. This is used to make sure proposal tx won't
// immediately fail when checking the l1 blockhash. Note that EstimateGas uses "latest" state to
// execute the transaction by default, meaning inside the call, the head block is considered
// "pending" instead of committed. In the case l1blocknum == l1head then, blockhash(l1blocknum)
// will produce a value of 0 within EstimateGas, and the call will fail when the contract checks
// that l1blockhash matches blockhash(l1blocknum).
func
(
l
*
L2OutputSubmitter
)
waitForL1Head
(
ctx
context
.
Context
,
blockNum
uint64
)
error
{
ticker
:=
time
.
NewTicker
(
l
.
pollInterval
)
defer
ticker
.
Stop
()
l1head
,
err
:=
l
.
txMgr
.
BlockNumber
(
ctx
)
if
err
!=
nil
{
return
err
}
for
l1head
<=
blockNum
{
l
.
log
.
Debug
(
"waiting for l1 head > l1blocknum1+1"
,
"l1head"
,
l1head
,
"l1blocknum"
,
blockNum
)
select
{
case
<-
ticker
.
C
:
l1head
,
err
=
l
.
txMgr
.
BlockNumber
(
ctx
)
if
err
!=
nil
{
return
err
}
break
case
<-
l
.
done
:
return
fmt
.
Errorf
(
"L2OutputSubmitter is done()"
)
}
}
return
nil
}
// sendTransaction creates & sends transactions through the underlying transaction manager.
// sendTransaction creates & sends transactions through the underlying transaction manager.
func
(
l
*
L2OutputSubmitter
)
sendTransaction
(
ctx
context
.
Context
,
output
*
eth
.
OutputResponse
)
error
{
func
(
l
*
L2OutputSubmitter
)
sendTransaction
(
ctx
context
.
Context
,
output
*
eth
.
OutputResponse
)
error
{
err
:=
l
.
waitForL1Head
(
ctx
,
output
.
Status
.
HeadL1
.
Number
+
1
)
if
err
!=
nil
{
return
err
}
data
,
err
:=
l
.
ProposeL2OutputTxData
(
output
)
data
,
err
:=
l
.
ProposeL2OutputTxData
(
output
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
...
@@ -336,7 +370,10 @@ func (l *L2OutputSubmitter) sendTransaction(ctx context.Context, output *eth.Out
...
@@ -336,7 +370,10 @@ func (l *L2OutputSubmitter) sendTransaction(ctx context.Context, output *eth.Out
if
receipt
.
Status
==
types
.
ReceiptStatusFailed
{
if
receipt
.
Status
==
types
.
ReceiptStatusFailed
{
l
.
log
.
Error
(
"proposer tx successfully published but reverted"
,
"tx_hash"
,
receipt
.
TxHash
)
l
.
log
.
Error
(
"proposer tx successfully published but reverted"
,
"tx_hash"
,
receipt
.
TxHash
)
}
else
{
}
else
{
l
.
log
.
Info
(
"proposer tx successfully published"
,
"tx_hash"
,
receipt
.
TxHash
)
l
.
log
.
Info
(
"proposer tx successfully published"
,
"tx_hash"
,
receipt
.
TxHash
,
"l1blocknum"
,
output
.
Status
.
CurrentL1
.
Number
,
"l1blockhash"
,
output
.
Status
.
CurrentL1
.
Hash
)
}
}
return
nil
return
nil
}
}
...
@@ -359,10 +396,13 @@ func (l *L2OutputSubmitter) loop() {
...
@@ -359,10 +396,13 @@ func (l *L2OutputSubmitter) loop() {
if
!
shouldPropose
{
if
!
shouldPropose
{
break
break
}
}
cCtx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
10
*
time
.
Minute
)
cCtx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
10
*
time
.
Minute
)
if
err
:=
l
.
sendTransaction
(
cCtx
,
output
);
err
!=
nil
{
if
err
:=
l
.
sendTransaction
(
cCtx
,
output
);
err
!=
nil
{
l
.
log
.
Error
(
"Failed to send proposal transaction"
,
"err"
,
err
)
l
.
log
.
Error
(
"Failed to send proposal transaction"
,
"err"
,
err
,
"l1blocknum"
,
output
.
Status
.
CurrentL1
.
Number
,
"l1blockhash"
,
output
.
Status
.
CurrentL1
.
Hash
,
"l1head"
,
output
.
Status
.
HeadL1
.
Number
)
cancel
()
cancel
()
break
break
}
}
...
...
op-service/txmgr/mocks/TxManager.go
View file @
0537c858
...
@@ -19,6 +19,30 @@ type TxManager struct {
...
@@ -19,6 +19,30 @@ type TxManager struct {
mock
.
Mock
mock
.
Mock
}
}
// BlockNumber provides a mock function with given fields: ctx
func
(
_m
*
TxManager
)
BlockNumber
(
ctx
context
.
Context
)
(
uint64
,
error
)
{
ret
:=
_m
.
Called
(
ctx
)
var
r0
uint64
var
r1
error
if
rf
,
ok
:=
ret
.
Get
(
0
)
.
(
func
(
context
.
Context
)
(
uint64
,
error
));
ok
{
return
rf
(
ctx
)
}
if
rf
,
ok
:=
ret
.
Get
(
0
)
.
(
func
(
context
.
Context
)
uint64
);
ok
{
r0
=
rf
(
ctx
)
}
else
{
r0
=
ret
.
Get
(
0
)
.
(
uint64
)
}
if
rf
,
ok
:=
ret
.
Get
(
1
)
.
(
func
(
context
.
Context
)
error
);
ok
{
r1
=
rf
(
ctx
)
}
else
{
r1
=
ret
.
Error
(
1
)
}
return
r0
,
r1
}
// From provides a mock function with given fields:
// From provides a mock function with given fields:
func
(
_m
*
TxManager
)
From
()
common
.
Address
{
func
(
_m
*
TxManager
)
From
()
common
.
Address
{
ret
:=
_m
.
Called
()
ret
:=
_m
.
Called
()
...
...
op-service/txmgr/txmgr.go
View file @
0537c858
...
@@ -48,6 +48,9 @@ type TxManager interface {
...
@@ -48,6 +48,9 @@ type TxManager interface {
// From returns the sending address associated with the instance of the transaction manager.
// From returns the sending address associated with the instance of the transaction manager.
// It is static for a single instance of a TxManager.
// It is static for a single instance of a TxManager.
From
()
common
.
Address
From
()
common
.
Address
// BlockNumber returns the most recent block number from the underlying network.
BlockNumber
(
ctx
context
.
Context
)
(
uint64
,
error
)
}
}
// ETHBackend is the set of methods that the transaction manager uses to resubmit gas & determine
// ETHBackend is the set of methods that the transaction manager uses to resubmit gas & determine
...
@@ -116,6 +119,10 @@ func (m *SimpleTxManager) From() common.Address {
...
@@ -116,6 +119,10 @@ func (m *SimpleTxManager) From() common.Address {
return
m
.
cfg
.
From
return
m
.
cfg
.
From
}
}
func
(
m
*
SimpleTxManager
)
BlockNumber
(
ctx
context
.
Context
)
(
uint64
,
error
)
{
return
m
.
backend
.
BlockNumber
(
ctx
)
}
// TxCandidate is a transaction candidate that can be submitted to ask the
// TxCandidate is a transaction candidate that can be submitted to ask the
// [TxManager] to construct a transaction with gas price bounds.
// [TxManager] to construct a transaction with gas price bounds.
type
TxCandidate
struct
{
type
TxCandidate
struct
{
...
@@ -353,7 +360,8 @@ func (m *SimpleTxManager) publishAndWaitForTx(ctx context.Context, tx *types.Tra
...
@@ -353,7 +360,8 @@ func (m *SimpleTxManager) publishAndWaitForTx(ctx context.Context, tx *types.Tra
// Poll for the transaction to be ready & then send the result to receiptChan
// Poll for the transaction to be ready & then send the result to receiptChan
receipt
,
err
:=
m
.
waitMined
(
ctx
,
tx
,
sendState
)
receipt
,
err
:=
m
.
waitMined
(
ctx
,
tx
,
sendState
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Warn
(
"Transaction receipt not found"
,
"err"
,
err
)
// this will happen if the tx was successfully replaced by a tx with bumped fees
log
.
Info
(
"Transaction receipt not found"
,
"err"
,
err
)
return
return
}
}
select
{
select
{
...
@@ -475,6 +483,10 @@ func (m *SimpleTxManager) increaseGasPrice(ctx context.Context, tx *types.Transa
...
@@ -475,6 +483,10 @@ func (m *SimpleTxManager) increaseGasPrice(ctx context.Context, tx *types.Transa
Data
:
rawTx
.
Data
,
Data
:
rawTx
.
Data
,
})
})
if
err
!=
nil
{
if
err
!=
nil
{
// If this is a transaction resubmission, we sometimes see this outcome because the
// original tx can get included in a block just before the above call. In this case the
// error is due to the tx reverting with message "block number must be equal to next
// expected block number"
m
.
l
.
Warn
(
"failed to re-estimate gas"
,
"err"
,
err
,
"gaslimit"
,
tx
.
Gas
())
m
.
l
.
Warn
(
"failed to re-estimate gas"
,
"err"
,
err
,
"gaslimit"
,
tx
.
Gas
())
return
nil
,
err
return
nil
,
err
}
}
...
...
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