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
29f283e5
Unverified
Commit
29f283e5
authored
Aug 30, 2023
by
mergify[bot]
Committed by
GitHub
Aug 30, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into require-cannon-tests
parents
4ba81f58
70be0fe8
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
199 additions
and
1 deletion
+199
-1
cli.go
op-service/txmgr/cli.go
+31
-0
txmgr.go
op-service/txmgr/txmgr.go
+11
-0
txmgr_test.go
op-service/txmgr/txmgr_test.go
+10
-1
commands.go
op-wheel/commands.go
+59
-0
engine.go
op-wheel/engine/engine.go
+88
-0
No files found.
op-service/txmgr/cli.go
View file @
29f283e5
...
...
@@ -290,3 +290,34 @@ type Config struct {
Signer
opcrypto
.
SignerFn
From
common
.
Address
}
func
(
m
Config
)
Check
()
error
{
if
m
.
Backend
==
nil
{
return
errors
.
New
(
"must provide the Backend"
)
}
if
m
.
NumConfirmations
==
0
{
return
errors
.
New
(
"NumConfirmations must not be 0"
)
}
if
m
.
NetworkTimeout
==
0
{
return
errors
.
New
(
"must provide NetworkTimeout"
)
}
if
m
.
ResubmissionTimeout
==
0
{
return
errors
.
New
(
"must provide ResubmissionTimeout"
)
}
if
m
.
ReceiptQueryInterval
==
0
{
return
errors
.
New
(
"must provide ReceiptQueryInterval"
)
}
if
m
.
TxNotInMempoolTimeout
==
0
{
return
errors
.
New
(
"must provide TxNotInMempoolTimeout"
)
}
if
m
.
SafeAbortNonceTooLowCount
==
0
{
return
errors
.
New
(
"SafeAbortNonceTooLowCount must not be 0"
)
}
if
m
.
Signer
==
nil
{
return
errors
.
New
(
"must provide the Signer"
)
}
if
m
.
ChainID
==
nil
{
return
errors
.
New
(
"must provide the ChainID"
)
}
return
nil
}
op-service/txmgr/txmgr.go
View file @
29f283e5
...
...
@@ -112,7 +112,14 @@ func NewSimpleTxManager(name string, l log.Logger, m metrics.TxMetricer, cfg CLI
if
err
!=
nil
{
return
nil
,
err
}
return
NewSimpleTxManagerFromConfig
(
name
,
l
,
m
,
conf
)
}
// NewSimpleTxManager initializes a new SimpleTxManager with the passed Config.
func
NewSimpleTxManagerFromConfig
(
name
string
,
l
log
.
Logger
,
m
metrics
.
TxMetricer
,
conf
Config
)
(
*
SimpleTxManager
,
error
)
{
if
err
:=
conf
.
Check
();
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"invalid config: %w"
,
err
)
}
return
&
SimpleTxManager
{
chainID
:
conf
.
ChainID
,
name
:
name
,
...
...
@@ -140,6 +147,8 @@ type TxCandidate struct {
To
*
common
.
Address
// GasLimit is the gas limit to be used in the constructed tx.
GasLimit
uint64
// Value is the value to be used in the constructed tx.
Value
*
big
.
Int
}
// Send is used to publish a transaction with incrementally higher gas prices
...
...
@@ -214,6 +223,7 @@ func (m *SimpleTxManager) craftTx(ctx context.Context, candidate TxCandidate) (*
GasTipCap
:
gasTipCap
,
GasFeeCap
:
gasFeeCap
,
Data
:
candidate
.
TxData
,
Value
:
candidate
.
Value
,
}
m
.
l
.
Info
(
"Creating tx"
,
"to"
,
rawTx
.
To
,
"from"
,
m
.
cfg
.
From
)
...
...
@@ -229,6 +239,7 @@ func (m *SimpleTxManager) craftTx(ctx context.Context, candidate TxCandidate) (*
GasFeeCap
:
gasFeeCap
,
GasTipCap
:
gasTipCap
,
Data
:
rawTx
.
Data
,
Value
:
rawTx
.
Value
,
})
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to estimate gas: %w"
,
err
)
...
...
op-service/txmgr/txmgr_test.go
View file @
29f283e5
...
...
@@ -603,12 +603,21 @@ func TestWaitMinedMultipleConfs(t *testing.T) {
require
.
Equal
(
t
,
txHash
,
receipt
.
TxHash
)
}
// TestManagerErrsOnZeroCLIConfs ensures that the NewSimpleTxManager will error
// when attempting to configure with NumConfirmations set to zero.
func
TestManagerErrsOnZeroCLIConfs
(
t
*
testing
.
T
)
{
t
.
Parallel
()
_
,
err
:=
NewSimpleTxManager
(
"TEST"
,
testlog
.
Logger
(
t
,
log
.
LvlCrit
),
&
metrics
.
NoopTxMetrics
{},
CLIConfig
{})
require
.
Error
(
t
,
err
)
}
// TestManagerErrsOnZeroConfs ensures that the NewSimpleTxManager will error
// when attempting to configure with NumConfirmations set to zero.
func
TestManagerErrsOnZeroConfs
(
t
*
testing
.
T
)
{
t
.
Parallel
()
_
,
err
:=
NewSimpleTxManager
(
"TEST"
,
testlog
.
Logger
(
t
,
log
.
LvlCrit
),
&
metrics
.
NoopTxMetrics
{},
CLI
Config
{})
_
,
err
:=
NewSimpleTxManager
FromConfig
(
"TEST"
,
testlog
.
Logger
(
t
,
log
.
LvlCrit
),
&
metrics
.
NoopTxMetrics
{},
Config
{})
require
.
Error
(
t
,
err
)
}
...
...
op-wheel/commands.go
View file @
29f283e5
...
...
@@ -454,6 +454,63 @@ var (
return
engine
.
Copy
(
context
.
Background
(),
source
,
dest
)
}),
}
EngineSetForkchoiceCmd
=
&
cli
.
Command
{
Name
:
"set-forkchoice"
,
Description
:
"Set forkchoice, specify unsafe, safe and finalized blocks by number"
,
Flags
:
[]
cli
.
Flag
{
EngineEndpoint
,
EngineJWTPath
,
&
cli
.
Uint64Flag
{
Name
:
"unsafe"
,
Usage
:
"Block number of block to set as latest block"
,
Required
:
true
,
EnvVars
:
prefixEnvVars
(
"UNSAFE"
),
},
&
cli
.
Uint64Flag
{
Name
:
"safe"
,
Usage
:
"Block number of block to set as safe block"
,
Required
:
true
,
EnvVars
:
prefixEnvVars
(
"SAFE"
),
},
&
cli
.
Uint64Flag
{
Name
:
"finalized"
,
Usage
:
"Block number of block to set as finalized block"
,
Required
:
true
,
EnvVars
:
prefixEnvVars
(
"FINALIZED"
),
},
},
Action
:
EngineAction
(
func
(
ctx
*
cli
.
Context
,
client
client
.
RPC
)
error
{
return
engine
.
SetForkchoice
(
ctx
.
Context
,
client
,
ctx
.
Uint64
(
"finalized"
),
ctx
.
Uint64
(
"safe"
),
ctx
.
Uint64
(
"unsafe"
))
}),
}
EngineJSONCmd
=
&
cli
.
Command
{
Name
:
"json"
,
Description
:
"read json values from remaining args, or STDIN, and use them as RPC params to call the engine RPC method (first arg)"
,
Flags
:
[]
cli
.
Flag
{
EngineEndpoint
,
EngineJWTPath
,
&
cli
.
BoolFlag
{
Name
:
"stdin"
,
Usage
:
"Read params from stdin instead"
,
Required
:
false
,
EnvVars
:
prefixEnvVars
(
"STDIN"
),
},
},
ArgsUsage
:
"<rpc-method-name> [params...]"
,
Action
:
EngineAction
(
func
(
ctx
*
cli
.
Context
,
client
client
.
RPC
)
error
{
if
ctx
.
NArg
()
==
0
{
return
fmt
.
Errorf
(
"expected at least 1 argument: RPC method name"
)
}
var
r
io
.
Reader
var
args
[]
string
if
ctx
.
Bool
(
"stdin"
)
{
r
=
ctx
.
App
.
Reader
}
else
{
args
=
ctx
.
Args
()
.
Tail
()
}
return
engine
.
RawJSONInteraction
(
ctx
.
Context
,
client
,
ctx
.
Args
()
.
Get
(
0
),
args
,
r
,
ctx
.
App
.
Writer
)
}),
}
)
var
CheatCmd
=
&
cli
.
Command
{
...
...
@@ -481,5 +538,7 @@ var EngineCmd = &cli.Command{
EngineAutoCmd
,
EngineStatusCmd
,
EngineCopyCmd
,
EngineSetForkchoiceCmd
,
EngineJSONCmd
,
},
}
op-wheel/engine/engine.go
View file @
29f283e5
...
...
@@ -3,8 +3,11 @@ package engine
import
(
"context"
"encoding/json"
"errors"
"fmt"
"io"
"math/big"
"strings"
"time"
"github.com/ethereum/go-ethereum/beacon/engine"
...
...
@@ -306,3 +309,88 @@ func Copy(ctx context.Context, copyFrom client.RPC, copyTo client.RPC) error {
}
return
nil
}
func
SetForkchoice
(
ctx
context
.
Context
,
client
client
.
RPC
,
finalizedNum
,
safeNum
,
unsafeNum
uint64
)
error
{
if
unsafeNum
<
safeNum
{
return
fmt
.
Errorf
(
"cannot set unsafe (%d) < safe (%d)"
,
unsafeNum
,
safeNum
)
}
if
safeNum
<
finalizedNum
{
return
fmt
.
Errorf
(
"cannot set safe (%d) < finalized (%d)"
,
safeNum
,
finalizedNum
)
}
head
,
err
:=
getHeader
(
ctx
,
client
,
"eth_getBlockByNumber"
,
"latest"
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to get latest block: %w"
,
err
)
}
if
unsafeNum
>
head
.
Number
.
Uint64
()
{
return
fmt
.
Errorf
(
"cannot set unsafe (%d) > latest (%d)"
,
unsafeNum
,
head
.
Number
.
Uint64
())
}
finalizedHeader
,
err
:=
getHeader
(
ctx
,
client
,
"eth_getBlockByNumber"
,
hexutil
.
Uint64
(
finalizedNum
)
.
String
())
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to get block %d to mark finalized: %w"
,
finalizedNum
,
err
)
}
safeHeader
,
err
:=
getHeader
(
ctx
,
client
,
"eth_getBlockByNumber"
,
hexutil
.
Uint64
(
safeNum
)
.
String
())
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to get block %d to mark safe: %w"
,
safeNum
,
err
)
}
if
err
:=
updateForkchoice
(
ctx
,
client
,
head
.
Hash
(),
safeHeader
.
Hash
(),
finalizedHeader
.
Hash
());
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to update forkchoice: %w"
,
err
)
}
return
nil
}
func
RawJSONInteraction
(
ctx
context
.
Context
,
client
client
.
RPC
,
method
string
,
args
[]
string
,
input
io
.
Reader
,
output
io
.
Writer
)
error
{
var
params
[]
any
if
input
!=
nil
{
r
:=
json
.
NewDecoder
(
input
)
for
{
var
param
json
.
RawMessage
if
err
:=
r
.
Decode
(
&
param
);
err
!=
nil
{
if
errors
.
Is
(
err
,
io
.
EOF
)
{
break
}
return
fmt
.
Errorf
(
"unexpected error while reading json params: %w"
,
err
)
}
params
=
append
(
params
,
param
)
}
}
else
{
for
_
,
arg
:=
range
args
{
// add quotes to unquoted strings, but not to other json data
if
isUnquotedJsonString
(
arg
)
{
arg
=
fmt
.
Sprintf
(
"%q"
,
arg
)
}
params
=
append
(
params
,
json
.
RawMessage
(
arg
))
}
}
var
result
json
.
RawMessage
if
err
:=
client
.
CallContext
(
ctx
,
&
result
,
method
,
params
...
);
err
!=
nil
{
return
fmt
.
Errorf
(
"failed RPC call: %w"
,
err
)
}
if
_
,
err
:=
output
.
Write
(
result
);
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to write RPC output: %w"
,
err
)
}
return
nil
}
func
isUnquotedJsonString
(
v
string
)
bool
{
v
=
strings
.
TrimSpace
(
v
)
// check if empty string (must get quotes)
if
len
(
v
)
==
0
{
return
true
}
// check if special value
switch
v
{
case
"null"
,
"true"
,
"false"
:
return
false
}
// check if it looks like a json structure
switch
v
[
0
]
{
case
'['
,
'{'
,
'"'
:
return
false
}
// check if a number
var
n
json
.
Number
if
err
:=
json
.
Unmarshal
([]
byte
(
v
),
&
n
);
err
==
nil
{
return
false
}
return
true
}
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