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
676efd21
Commit
676efd21
authored
Jul 12, 2023
by
Felipe Andrade
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
signer tls, send tx on heartbeat
parent
135a6e1d
Changes
8
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
244 additions
and
43 deletions
+244
-43
.gitignore
op-ufm/.gitignore
+1
-0
example.config.toml
op-ufm/example.config.toml
+13
-0
go.mod
op-ufm/go.mod
+18
-10
go.sum
op-ufm/go.sum
+76
-20
config.go
op-ufm/pkg/config/config.go
+26
-6
handlers.go
op-ufm/pkg/provider/handlers.go
+93
-0
provider.go
op-ufm/pkg/provider/provider.go
+12
-6
service.go
op-ufm/pkg/service/service.go
+5
-1
No files found.
op-ufm/.gitignore
View file @
676efd21
bin
tls
config.toml
op-ufm/example.config.toml
View file @
676efd21
...
...
@@ -6,6 +6,9 @@ log_level = "debug"
[signer_service]
# URL to the signer service
url
=
"http://localhost:1234"
tls_ca_cert
=
"tls/ca.crt"
tls_cert
=
"tls/tls.crt"
tls_key
=
"tls/tls.key"
[healthz]
# Whether or not to enable healthz endpoint
...
...
@@ -34,6 +37,14 @@ signer_method = "signer"
address
=
"0x0123"
# For static signer method, the private key to use
# private_key=""
# Transaction value in wei
tx_value
=
100000000000000
# Gas limit
gas_limit
=
21000
# Gas tip cap
gas_tip_cap
=
2000000000
# Fee cap
gas_fee_cap
=
20000000000
[providers.p1]
# URL to the RPC provider
...
...
@@ -48,6 +59,8 @@ send_interval = "5s"
wallet
=
"default"
[providers.p2]
# Uncomment to disable this provider
# disabled=true
# URL to the RPC provider
url
=
"http://localhost:8552"
# Read only providers are only used to check for transactions
...
...
op-ufm/go.mod
View file @
676efd21
...
...
@@ -4,23 +4,31 @@ go 1.20
require (
github.com/BurntSushi/toml v1.3.2
github.com/ethereum-optimism/optimism/op-signer v0.1.1
github.com/ethereum/go-ethereum v1.12.0
github.com/gorilla/mux v1.8.0
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.14.0
github.com/rs/cors v1.7.0
github.com/rs/cors v1.8.2
)
require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/deckarep/golang-set/v2 v2.1.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
github.com/ethereum-optimism/optimism/op-service v0.10.14-0.20230209153120-0338ea88dff7 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/go
lang/protobuf v1.5.2
// indirect
github.com/go
rilla/websocket v1.5.0
// indirect
github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.39.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/tklauser/go-sysconf v0.3.10 // indirect
github.com/tklauser/numcpus v0.5.0 // indirect
github.com/urfave/cli v1.22.9 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/crypto v0.1.0 // indirect
golang.org/x/sys v0.7.0 // indirect
go
ogle.golang.org/protobuf v1.28.1
// indirect
go
pkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce
// indirect
)
op-ufm/go.sum
View file @
676efd21
This diff is collapsed.
Click to expand it.
op-ufm/pkg/config/config.go
View file @
676efd21
package
config
import
(
"math/big"
"github.com/BurntSushi/toml"
"github.com/pkg/errors"
)
...
...
@@ -17,7 +19,10 @@ type Config struct {
}
type
SignerServiceConfig
struct
{
URL
string
`toml:"url"`
URL
string
`toml:"url"`
TLSCaCert
string
`toml:"tls_ca_cert"`
TLSCert
string
`toml:"tls_cert"`
TLSKey
string
`toml:"tls_key"`
}
type
MetricsConfig
struct
{
...
...
@@ -34,17 +39,23 @@ type HealthzConfig struct {
type
WalletConfig
struct
{
// default: 420 (Optimism Goerli)
ChainID
ui
nt
`toml:"chain_id"`
ChainID
big
.
I
nt
`toml:"chain_id"`
// signer | static, default: signer
SignerMethod
string
`toml:"signer_method"`
// for static signing
Address
string
`toml:"address"`
Address
string
`toml:"address"`
// private key is used for static signing
PrivateKey
string
`toml:"private_key"`
// transaction parameters
TxValue
big
.
Int
`toml:"tx_value"`
GasLimit
uint64
`toml:"gas_limit"`
GasTipCap
big
.
Int
`toml:"gas_tip_cap"`
GasFeeCap
big
.
Int
`toml:"gas_fee_cap"`
}
type
ProviderConfig
struct
{
Disabled
bool
`toml:"disabled"`
URL
string
`toml:"url"`
Wallet
string
`toml:"wallet"`
ReadOnly
bool
`toml:"read_only"`
...
...
@@ -81,7 +92,7 @@ func (c *Config) Validate() error {
}
for
name
,
wallet
:=
range
c
.
Wallets
{
if
wallet
.
ChainID
==
0
{
if
wallet
.
ChainID
.
BitLen
()
==
0
{
return
errors
.
Errorf
(
"wallet [%s] chain_id is missing"
,
name
)
}
if
wallet
.
SignerMethod
!=
"signer"
&&
wallet
.
SignerMethod
!=
"static"
{
...
...
@@ -91,6 +102,15 @@ func (c *Config) Validate() error {
if
c
.
Signer
.
URL
==
""
{
return
errors
.
New
(
"signer url is missing"
)
}
if
c
.
Signer
.
TLSCaCert
==
""
{
return
errors
.
New
(
"signer tls_ca_cert is missing"
)
}
if
c
.
Signer
.
TLSCert
==
""
{
return
errors
.
New
(
"signer tls_cert is missing"
)
}
if
c
.
Signer
.
TLSKey
==
""
{
return
errors
.
New
(
"signer tls_key is missing"
)
}
}
if
wallet
.
SignerMethod
==
"static"
{
if
wallet
.
PrivateKey
==
""
{
...
...
op-ufm/pkg/provider/handlers.go
View file @
676efd21
...
...
@@ -3,12 +3,105 @@ package provider
import
(
"context"
"github.com/ethereum-optimism/optimism/op-service/tls"
signer
"github.com/ethereum-optimism/optimism/op-signer/client"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/pkg/errors"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
)
// Heartbeat poll for expected transactions
func
(
p
*
Provider
)
Heartbeat
(
ctx
context
.
Context
)
{
log
.
Debug
(
"heartbeat"
,
"provider"
,
p
.
name
)
ethClient
,
err
:=
p
.
dial
(
ctx
)
if
err
!=
nil
{
log
.
Error
(
"cant dial to provider"
,
"provider"
,
p
.
name
,
"url"
,
p
.
config
.
URL
,
"err"
,
err
)
}
nonce
,
err
:=
p
.
nonce
(
ctx
,
ethClient
)
if
err
!=
nil
{
log
.
Error
(
"cant get nounce"
,
"provider"
,
p
.
name
,
"err"
,
err
)
}
tx
:=
p
.
createTx
(
nonce
)
signedTx
,
err
:=
p
.
sign
(
ctx
,
tx
)
if
err
!=
nil
{
log
.
Error
(
"cant sign tx"
,
"tx"
,
tx
,
"err"
,
err
)
}
err
=
ethClient
.
SendTransaction
(
ctx
,
signedTx
)
if
err
!=
nil
{
log
.
Error
(
"cant send transaction"
,
"provider"
,
p
.
name
,
"err"
,
err
)
}
log
.
Info
(
"transaction sent"
,
"hash"
,
signedTx
.
Hash
()
.
Hex
())
}
func
(
p
*
Provider
)
dial
(
ctx
context
.
Context
)
(
*
ethclient
.
Client
,
error
)
{
return
ethclient
.
Dial
(
p
.
config
.
URL
)
}
func
(
p
*
Provider
)
createTx
(
nonce
uint64
)
*
types
.
Transaction
{
toAddress
:=
common
.
HexToAddress
(
p
.
walletConfig
.
Address
)
var
data
[]
byte
tx
:=
types
.
NewTx
(
&
types
.
DynamicFeeTx
{
ChainID
:
&
p
.
walletConfig
.
ChainID
,
Nonce
:
nonce
,
GasFeeCap
:
&
p
.
walletConfig
.
GasFeeCap
,
GasTipCap
:
&
p
.
walletConfig
.
GasTipCap
,
Gas
:
p
.
walletConfig
.
GasLimit
,
To
:
&
toAddress
,
Value
:
&
p
.
walletConfig
.
TxValue
,
Data
:
data
,
})
log
.
Debug
(
"tx"
,
"tx"
,
tx
)
return
tx
}
func
(
p
*
Provider
)
sign
(
ctx
context
.
Context
,
tx
*
types
.
Transaction
)
(
*
types
.
Transaction
,
error
)
{
if
p
.
walletConfig
.
SignerMethod
==
"static"
{
log
.
Debug
(
"using static signer"
)
privateKey
,
err
:=
crypto
.
HexToECDSA
(
p
.
walletConfig
.
PrivateKey
)
if
err
!=
nil
{
return
nil
,
err
}
return
types
.
SignTx
(
tx
,
types
.
LatestSignerForChainID
(
&
p
.
walletConfig
.
ChainID
),
privateKey
)
}
else
if
p
.
walletConfig
.
SignerMethod
==
"signer"
{
tlsConfig
:=
tls
.
CLIConfig
{
TLSCaCert
:
p
.
signerConfig
.
TLSCaCert
,
TLSCert
:
p
.
signerConfig
.
TLSCert
,
TLSKey
:
p
.
signerConfig
.
TLSKey
,
}
client
,
err
:=
signer
.
NewSignerClient
(
log
.
Root
(),
p
.
signerConfig
.
URL
,
tlsConfig
)
log
.
Debug
(
"signerclient"
,
"client"
,
client
,
"err"
,
err
)
if
err
!=
nil
{
return
nil
,
err
}
if
client
==
nil
{
return
nil
,
errors
.
New
(
"could not initialize signer client"
)
}
signedTx
,
err
:=
client
.
SignTransaction
(
ctx
,
&
p
.
walletConfig
.
ChainID
,
tx
)
log
.
Debug
(
"signedtx"
,
"tx"
,
signedTx
,
"err"
,
err
)
if
err
!=
nil
{
return
nil
,
err
}
return
signedTx
,
nil
}
else
{
return
nil
,
errors
.
New
(
"invalid signer method"
)
}
}
func
(
p
*
Provider
)
nonce
(
ctx
context
.
Context
,
client
*
ethclient
.
Client
)
(
uint64
,
error
)
{
fromAddress
:=
common
.
HexToAddress
(
p
.
walletConfig
.
Address
)
return
client
.
PendingNonceAt
(
ctx
,
fromAddress
)
}
// Roundtrip send a new transaction to measure round trip latency
...
...
op-ufm/pkg/provider/provider.go
View file @
676efd21
...
...
@@ -8,17 +8,23 @@ import (
)
type
Provider
struct
{
name
string
config
*
config
.
ProviderConfig
cancelFunc
context
.
CancelFunc
name
string
config
*
config
.
ProviderConfig
signerConfig
*
config
.
SignerServiceConfig
walletConfig
*
config
.
WalletConfig
cancelFunc
context
.
CancelFunc
client
*
http
.
Client
}
func
New
(
name
string
,
cfg
*
config
.
ProviderConfig
)
*
Provider
{
func
New
(
name
string
,
cfg
*
config
.
ProviderConfig
,
signerConfig
*
config
.
SignerServiceConfig
,
walletConfig
*
config
.
WalletConfig
)
*
Provider
{
p
:=
&
Provider
{
name
:
name
,
config
:
cfg
,
name
:
name
,
config
:
cfg
,
signerConfig
:
signerConfig
,
walletConfig
:
walletConfig
,
client
:
http
.
DefaultClient
,
}
...
...
op-ufm/pkg/service/service.go
View file @
676efd21
...
...
@@ -30,7 +30,11 @@ func (s *Service) Start(ctx context.Context) {
log
.
Info
(
"healthz started"
)
}
for
name
,
providerConfig
:=
range
s
.
Config
.
Providers
{
s
.
Providers
[
name
]
=
provider
.
New
(
name
,
providerConfig
)
if
providerConfig
.
Disabled
{
log
.
Info
(
"provider is disabled"
,
"provider"
,
name
)
continue
}
s
.
Providers
[
name
]
=
provider
.
New
(
name
,
providerConfig
,
&
s
.
Config
.
Signer
,
s
.
Config
.
Wallets
[
providerConfig
.
Wallet
])
s
.
Providers
[
name
]
.
Start
(
ctx
)
log
.
Info
(
"provider started"
,
"provider"
,
name
)
}
...
...
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