diff --git a/op-ufm/op-ufm/.gitignore b/op-ufm/op-ufm/.gitignore index 65e6a82..47ea0d9 100644 --- a/op-ufm/op-ufm/.gitignore +++ b/op-ufm/op-ufm/.gitignore @@ -1,3 +1,4 @@ bin +tls config.toml diff --git a/op-ufm/op-ufm/example.config.toml b/op-ufm/op-ufm/example.config.toml index f4abab7..b3fd6a5 100644 --- a/op-ufm/op-ufm/example.config.toml +++ b/op-ufm/op-ufm/example.config.toml @@ -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 diff --git a/op-ufm/op-ufm/go.mod b/op-ufm/op-ufm/go.mod index 342006e..c840f34 100644 --- a/op-ufm/op-ufm/go.mod +++ b/op-ufm/op-ufm/go.mod @@ -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/golang/protobuf v1.5.2 // indirect + github.com/gorilla/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 - google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect ) diff --git a/op-ufm/op-ufm/go.sum b/op-ufm/op-ufm/go.sum index 520eb79..04974c1 100644 --- a/op-ufm/op-ufm/go.sum +++ b/op-ufm/op-ufm/go.sum @@ -1,43 +1,99 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= +github.com/VictoriaMetrics/fastcache v1.10.0 h1:5hDJnLsKLpnUEToub7ETuRu8RCkb40woBZAUiKonXzY= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/btcsuite/btcd v0.23.3 h1:4KH/JKy9WiCd+iUS9Mu0Zp7Dnj17TGdKrg9xc/FGj24= +github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= +github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 h1:ytcWPaNPhNoGMWEhDvS3zToKcDpRsLuRolQJBVGdozk= +github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= +github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +github.com/ethereum-optimism/optimism/op-service v0.10.14-0.20230209153120-0338ea88dff7 h1:odd+kEgbJ9W1iiXowli5Yk/4mNYrk0Wzgtkph9v74Wc= +github.com/ethereum-optimism/optimism/op-service v0.10.14-0.20230209153120-0338ea88dff7/go.mod h1:Yp5nMIQaPgQu/OI7MPbH7jIUbbEEb1rhIviGFE1b294= +github.com/ethereum-optimism/optimism/op-signer v0.1.1 h1:Ts6aWd5/nTQ8ZRFZhpOrrcWpnVmdp4fRfff1mvybnGs= +github.com/ethereum-optimism/optimism/op-signer v0.1.1/go.mod h1:HK+9do1IJmDr9aEc44ECweYbCLDfGGYO7PBwTqDNrqI= github.com/ethereum/go-ethereum v1.12.0 h1:bdnhLPtqETd4m3mS8BGMNvBTf36bO5bx/hxE2zljOa0= github.com/ethereum/go-ethereum v1.12.0/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDBKDBU6sFIpx1Gs= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8= github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= +github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= -github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= -github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= -github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +github.com/rivo/uniseg v0.3.4 h1:3Z3Eu6FGHZWSfNKJTOUiPatWwfc7DzJRU04jFUqJODw= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= +github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= +github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a h1:1ur3QoCqvE5fl+nylMaIr9PVV1w343YRDtsy+Rwu7XI= +github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= +github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= +github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= +github.com/tklauser/numcpus v0.5.0 h1:ooe7gN0fg6myJ0EKoTAf5hebTZrH52px3New/D9iJ+A= +github.com/tklauser/numcpus v0.5.0/go.mod h1:OGzpTxpcIMNGYQdit2BYL1pvk/dSOaJWjKoflh+RQjo= +github.com/urfave/cli v1.22.9 h1:cv3/KhXGBGjEXLC4bH0sLuJ9BewaAbpk5oyMOveu4pw= +github.com/urfave/cli v1.22.9/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= +github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/exp v0.0.0-20230206171751-46f607a40771 h1:xP7rWLUr1e1n2xkK5YB4LI0hPEy3LJC6Wk+D4pGlOJg= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/op-ufm/op-ufm/pkg/config/config.go b/op-ufm/op-ufm/pkg/config/config.go index bf8416c..c27806a 100644 --- a/op-ufm/op-ufm/pkg/config/config.go +++ b/op-ufm/op-ufm/pkg/config/config.go @@ -1,6 +1,8 @@ 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 uint `toml:"chain_id"` + ChainID big.Int `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 == "" { diff --git a/op-ufm/op-ufm/pkg/provider/handlers.go b/op-ufm/op-ufm/pkg/provider/handlers.go index 46759e6..6ed3c6e 100644 --- a/op-ufm/op-ufm/pkg/provider/handlers.go +++ b/op-ufm/op-ufm/pkg/provider/handlers.go @@ -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 diff --git a/op-ufm/op-ufm/pkg/provider/provider.go b/op-ufm/op-ufm/pkg/provider/provider.go index ea22ae4..f3a553e 100644 --- a/op-ufm/op-ufm/pkg/provider/provider.go +++ b/op-ufm/op-ufm/pkg/provider/provider.go @@ -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, } diff --git a/op-ufm/op-ufm/pkg/service/service.go b/op-ufm/op-ufm/pkg/service/service.go index 483bfff..055ce1a 100644 --- a/op-ufm/op-ufm/pkg/service/service.go +++ b/op-ufm/op-ufm/pkg/service/service.go @@ -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) }