Skip to content

Commit

Permalink
implemented keystore support
Browse files Browse the repository at this point in the history
  • Loading branch information
Mikelle committed Feb 3, 2024
1 parent 060fa0e commit 56aa1b4
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 26 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ FROM alpine:latest

COPY --from=builder /app/mev-commit-oracle /usr/local/bin/mev-commit-oracle
COPY --from=builder /app/key /key
COPY --from=builder /app/keystore /keystore
COPY --from=builder /app/config.yaml /config.yaml
COPY --from=builder /app/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
Expand Down
61 changes: 46 additions & 15 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import (
"strings"
"time"

"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/primevprotocol/mev-oracle/pkg/keysigner"
"github.com/primevprotocol/mev-oracle/pkg/node"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
Expand Down Expand Up @@ -53,6 +55,8 @@ func main() {

type config struct {
PrivKeyFile string `yaml:"priv_key_file" json:"priv_key_file"`
KeystorePath string `yaml:"keystore_path" json:"keystore_path"`
KeystorePassword string `yaml:"keystore_password" json:"keystore_password"`
HTTPPort int `yaml:"http_port" json:"http_port"`
LogLevel string `yaml:"log_level" json:"log_level"`
L1RPCUrl string `yaml:"l1_rpc_url" json:"l1_rpc_url"`
Expand All @@ -69,8 +73,8 @@ type config struct {
}

func checkConfig(cfg *config) error {
if cfg.PrivKeyFile == "" {
return fmt.Errorf("priv_key_file is required")
if cfg.PrivKeyFile == "" && (cfg.KeystorePath == "" || cfg.KeystorePassword == "") {
return fmt.Errorf("priv_key_file or keystore_path and keystore_password are required")
}

if cfg.HTTPPort == 0 {
Expand Down Expand Up @@ -131,25 +135,15 @@ func start(c *cli.Context) error {
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
log.Logger = log.Output(os.Stdout).With().Caller().Logger()

privKeyFile := cfg.PrivKeyFile
if strings.HasPrefix(privKeyFile, "~/") {
homeDir, err := os.UserHomeDir()
if err != nil {
return fmt.Errorf("failed to get user home directory: %w", err)
}

privKeyFile = filepath.Join(homeDir, privKeyFile[2:])
}

privKey, err := crypto.LoadECDSA(privKeyFile)
keySigner, err := setupKeySigner(&cfg)
if err != nil {
return fmt.Errorf("failed to load private key from file '%s': %w", cfg.PrivKeyFile, err)
return fmt.Errorf("failed to setup key signer: %w", err)
}

common.HexToAddress(cfg.OracleContractAddr)

nd, err := node.NewNode(&node.Options{
PrivateKey: privKey,
KeySigner: keySigner,
HTTPPort: cfg.HTTPPort,
L1RPCUrl: cfg.L1RPCUrl,
SettlementRPCUrl: cfg.SettlementRPCUrl,
Expand Down Expand Up @@ -188,3 +182,40 @@ func start(c *cli.Context) error {

return nil
}

func setupKeySigner(cfg *config) (keysigner.KeySigner, error) {
if cfg.PrivKeyFile == "" {
return setupKeystoreSigner(cfg)
}
return setupPrivateKeySigner(cfg)
}

func setupKeystoreSigner(cfg *config) (keysigner.KeySigner, error) {
// Load the keystore file
ks := keystore.NewKeyStore(cfg.KeystorePath, keystore.LightScryptN, keystore.LightScryptP)
accounts := ks.Accounts()
if len(accounts) == 0 {
return nil, fmt.Errorf("no accounts found in keystore, path: %s", cfg.KeystorePath)
}

account := accounts[0]
return keysigner.NewKeystoreSigner(ks, cfg.KeystorePassword, account), nil
}

func setupPrivateKeySigner(cfg *config) (keysigner.KeySigner, error) {
privKeyFile := cfg.PrivKeyFile
if strings.HasPrefix(privKeyFile, "~/") {
homeDir, err := os.UserHomeDir()
if err != nil {
return nil, fmt.Errorf("failed to get user home directory: %w", err)
}

privKeyFile = filepath.Join(homeDir, privKeyFile[2:])
}

privKey, err := crypto.LoadECDSA(privKeyFile)
if err != nil {
return nil, fmt.Errorf("failed to load private key from file '%s': %w", cfg.PrivKeyFile, err)
}
return keysigner.NewPrivateKeySigner(privKey), nil
}
2 changes: 2 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
priv_key_file: /key
keystore_path: /keystore
keystore_password: primev
log_level: debug
l1_rpc_url: <L1_URL>
settlement_rpc_url: http://sl-bootnode:8545
Expand Down
1 change: 1 addition & 0 deletions integrationtest/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ FROM alpine:latest

COPY --from=builder /app/mev-commit-oracle /usr/local/bin/mev-commit-oracle
COPY --from=builder /app/integrationtest/key /key
COPY --from=builder /app/keystore /keystore
COPY --from=builder /app/integrationtest/config.yaml /config.yaml
COPY --from=builder /app/integrationtest/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
Expand Down
2 changes: 2 additions & 0 deletions integrationtest/config.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
priv_key_file: /key
keystore_path: /keystore
keystore_password: primev
log_level: debug
l1_rpc_url: <L1_URL>
settlement_rpc_url: http://sl-bootnode:8545
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"address":"f39fd6e51aad88f6f4ce6ab8827279cfffb92266","crypto":{"cipher":"aes-128-ctr","ciphertext":"76c45c365f221cc9974ac51045cb947d053ace020d9d1343ddc8100b6d5ad5e4","cipherparams":{"iv":"751c74fd7dbce2e9c17cddff2ed36724"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"852baf4e7508c9da75956846da3b5a47e4f978f9068adb91c4e4ef18ce7b30ba"},"mac":"dce583625ec4e9821153bfec9d923752bc8d5161f7622c01afc227d537cceff5"},"id":"589bc600-ce98-4051-9d97-6aba0d6fc2fb","version":3}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"address":"f39fd6e51aad88f6f4ce6ab8827279cfffb92266","crypto":{"cipher":"aes-128-ctr","ciphertext":"76c45c365f221cc9974ac51045cb947d053ace020d9d1343ddc8100b6d5ad5e4","cipherparams":{"iv":"751c74fd7dbce2e9c17cddff2ed36724"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"852baf4e7508c9da75956846da3b5a47e4f978f9068adb91c4e4ef18ce7b30ba"},"mac":"dce583625ec4e9821153bfec9d923752bc8d5161f7622c01afc227d537cceff5"},"id":"589bc600-ce98-4051-9d97-6aba0d6fc2fb","version":3}
61 changes: 61 additions & 0 deletions pkg/keysigner/keysigner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package keysigner

import (
"crypto/ecdsa"
"math/big"

"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)

type KeySigner interface {
GetAddress() common.Address
GetAuth(chainID *big.Int) (*bind.TransactOpts, error)
}

type privateKeySigner struct {
privKey *ecdsa.PrivateKey
}

func NewPrivateKeySigner(privKey *ecdsa.PrivateKey) *privateKeySigner {
return &privateKeySigner{
privKey: privKey,
}
}

func (pks *privateKeySigner) GetAddress() common.Address {
return crypto.PubkeyToAddress(pks.privKey.PublicKey)
}

func (pks *privateKeySigner) GetAuth(chainID *big.Int) (*bind.TransactOpts, error) {
return bind.NewKeyedTransactorWithChainID(pks.privKey, chainID)
}

type keystoreSigner struct {
keystore *keystore.KeyStore
password string
account accounts.Account
}

func NewKeystoreSigner(keystore *keystore.KeyStore, password string, account accounts.Account) *keystoreSigner {
return &keystoreSigner{
keystore: keystore,
password: password,
account: account,
}
}

func (kss *keystoreSigner) GetAddress() common.Address {
return kss.account.Address
}

func (kss *keystoreSigner) GetAuth(chainID *big.Int) (*bind.TransactOpts, error) {
if err := kss.keystore.Unlock(kss.account, kss.password); err != nil {
return nil, err
}

return bind.NewKeyStoreTransactorWithChainID(kss.keystore, kss.account, chainID)
}
13 changes: 7 additions & 6 deletions pkg/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
rollupclient "github.com/primevprotocol/contracts-abi/clients/Oracle"
preconf "github.com/primevprotocol/contracts-abi/clients/PreConfCommitmentStore"
"github.com/primevprotocol/mev-oracle/pkg/apiserver"
"github.com/primevprotocol/mev-oracle/pkg/keysigner"
"github.com/primevprotocol/mev-oracle/pkg/l1Listener"
"github.com/primevprotocol/mev-oracle/pkg/settler"
"github.com/primevprotocol/mev-oracle/pkg/store"
Expand All @@ -27,7 +28,7 @@ import (
)

type Options struct {
PrivateKey *ecdsa.PrivateKey
KeySigner keysigner.KeySigner
HTTPPort int
SettlementRPCUrl string
L1RPCUrl string
Expand Down Expand Up @@ -63,7 +64,7 @@ func NewNode(opts *Options) (*Node, error) {
return nil, err
}

owner := getEthAddressFromPubKey(opts.PrivateKey.Public().(*ecdsa.PublicKey))
owner := opts.KeySigner.GetAddress()

settlementClient, err := ethclient.Dial(opts.SettlementRPCUrl)
if err != nil {
Expand Down Expand Up @@ -114,7 +115,7 @@ func NewNode(opts *Options) (*Node, error) {
for _, winner := range opts.OverrideWinners {
err := setBuilderMapping(
ctx,
opts.PrivateKey,
opts.KeySigner,
chainID,
settlementClient,
oracleContract,
Expand Down Expand Up @@ -148,7 +149,7 @@ func NewNode(opts *Options) (*Node, error) {
updtrClosed := updtr.Start(ctx)

settlr := settler.NewSettler(
opts.PrivateKey,
opts.KeySigner,
chainID,
owner,
oracleContract,
Expand Down Expand Up @@ -276,14 +277,14 @@ func (w *winnerOverrideL1Client) HeaderByNumber(ctx context.Context, number *big

func setBuilderMapping(
ctx context.Context,
privateKey *ecdsa.PrivateKey,
keySigner keysigner.KeySigner,
chainID *big.Int,
client *ethclient.Client,
rc *rollupclient.Oracle,
builderName string,
builderAddress string,
) error {
auth, err := bind.NewKeyedTransactorWithChainID(privateKey, chainID)
auth, err := keySigner.GetAuth(chainID)
if err != nil {
return err
}
Expand Down
10 changes: 5 additions & 5 deletions pkg/settler/settler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ package settler

import (
"context"
"crypto/ecdsa"
"errors"
"math/big"
"time"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/primevprotocol/mev-oracle/pkg/keysigner"
"github.com/prometheus/client_golang/prometheus"
"github.com/rs/zerolog/log"
)
Expand Down Expand Up @@ -51,7 +51,7 @@ type Transactor interface {
}

type Settler struct {
privateKey *ecdsa.PrivateKey
keySigner keysigner.KeySigner
chainID *big.Int
owner common.Address
rollupClient Oracle
Expand All @@ -61,7 +61,7 @@ type Settler struct {
}

func NewSettler(
privateKey *ecdsa.PrivateKey,
keySigner keysigner.KeySigner,
chainID *big.Int,
owner common.Address,
rollupClient Oracle,
Expand All @@ -73,14 +73,14 @@ func NewSettler(
settlerRegister: settlerRegister,
owner: owner,
client: client,
privateKey: privateKey,
keySigner: keySigner,
chainID: chainID,
metrics: newMetrics(),
}
}

func (s *Settler) getTransactOpts(ctx context.Context) (*bind.TransactOpts, error) {
auth, err := bind.NewKeyedTransactorWithChainID(s.privateKey, s.chainID)
auth, err := s.keySigner.GetAuth(s.chainID)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 56aa1b4

Please sign in to comment.