From 9e2970d48e5f0ca4463ef21de6f8234733ce3add Mon Sep 17 00:00:00 2001 From: Alok Date: Wed, 5 Jun 2024 01:06:37 +0530 Subject: [PATCH] fix: use simple encrypted keysigner --- oracle/cmd/main.go | 4 +- p2p/cmd/main.go | 4 +- p2p/pkg/p2p/libp2p/libp2p.go | 1 - x/contracts/txmonitor/txmonitor.go | 20 ++++++- x/keysigner/keysigner.go | 1 - x/keysigner/keystoresigner.go | 91 ------------------------------ x/keysigner/privatekeysigner.go | 41 +++++++++----- 7 files changed, 48 insertions(+), 114 deletions(-) delete mode 100644 x/keysigner/keystoresigner.go diff --git a/oracle/cmd/main.go b/oracle/cmd/main.go index e0dd72f66..f426c8e90 100644 --- a/oracle/cmd/main.go +++ b/oracle/cmd/main.go @@ -398,7 +398,7 @@ func newLogger(lvl, logFmt, tags string, sink io.Writer) (*slog.Logger, error) { func setupKeySigner(c *cli.Context) (keysigner.KeySigner, error) { if c.IsSet(optionKeystorePath.Name) { - return keysigner.NewKeystoreSigner(c.String(optionKeystorePath.Name), c.String(optionKeystorePassword.Name)) + return keysigner.NewEncryptedSigner(c.String(optionKeystorePath.Name), c.String(optionKeystorePassword.Name)) } - return keysigner.NewPrivateKeySigner(c.String(optionPrivKeyFile.Name)) + return keysigner.NewSigner(c.String(optionPrivKeyFile.Name)) } diff --git a/p2p/cmd/main.go b/p2p/cmd/main.go index 3ba7e98d1..0db9e9df0 100644 --- a/p2p/cmd/main.go +++ b/p2p/cmd/main.go @@ -381,7 +381,7 @@ func launchNodeWithConfig(c *cli.Context) error { func newKeySigner(c *cli.Context) (ks.KeySigner, error) { if c.IsSet(optionKeystorePath.Name) { - return ks.NewKeystoreSigner(c.String(optionKeystorePath.Name), c.String(optionKeystorePassword.Name)) + return ks.NewEncryptedSigner(c.String(optionKeystorePath.Name), c.String(optionKeystorePassword.Name)) } - return ks.NewPrivateKeySigner(c.String(optionPrivKeyFile.Name)) + return ks.NewSigner(c.String(optionPrivKeyFile.Name)) } diff --git a/p2p/pkg/p2p/libp2p/libp2p.go b/p2p/pkg/p2p/libp2p/libp2p.go index 184e88d84..29bc54857 100644 --- a/p2p/pkg/p2p/libp2p/libp2p.go +++ b/p2p/pkg/p2p/libp2p/libp2p.go @@ -76,7 +76,6 @@ func New(opts *Options) (*Service, error) { if err != nil { return nil, fmt.Errorf("failed to get priv key: %w", err) } - defer opts.KeySigner.ZeroPrivateKey(privKey) padded32BytePrivKey := util.PadKeyTo32Bytes(privKey.D) libp2pKey, err := libp2pcrypto.UnmarshalSecp256k1PrivateKey(padded32BytePrivKey) diff --git a/x/contracts/txmonitor/txmonitor.go b/x/contracts/txmonitor/txmonitor.go index c84a6a204..0826d2003 100644 --- a/x/contracts/txmonitor/txmonitor.go +++ b/x/contracts/txmonitor/txmonitor.go @@ -22,6 +22,7 @@ var ( var ( ErrTxnCancelled = errors.New("transaction was cancelled") + ErrTxnFailed = errors.New("transaction failed") ErrMonitorClosed = errors.New("monitor was closed") ) @@ -222,7 +223,6 @@ func (m *Monitor) Sent(ctx context.Context, tx *types.Transaction) { r := <-res status := "success" if r.Err != nil { - m.logger.Error("transaction failed", "err", r.Err) status = fmt.Sprintf("failed: %v", r.Err) } if err := m.saver.Update(context.Background(), tx.Hash(), status); err != nil { @@ -353,13 +353,27 @@ func (m *Monitor) check(ctx context.Context, newBlock uint64, lastNonce uint64) m.notify(nonce, txHashes[start+i], Result{nil, ErrTxnCancelled}) continue } + m.logger.Error("failed to get receipt", "error", r.Err, "txHash", txHashes[start+i]) + continue + } + if r.Receipt.Status != types.ReceiptStatusSuccessful { tt, err := m.helper.TraceTransaction(ctx, txHashes[start+i]) if err != nil { - m.logger.Error("retrieving transaction trace failed", "error", err) + m.logger.Error( + "retrieving transaction trace failed", + "error", err, + "txHash", txHashes[start+i], + ) + } else { + m.logger.Error("transaction failed", + "transaction_trace", tt, + "txHash", txHashes[start+i], + ) } - m.logger.Error("failed to get receipt", "error", r.Err, "transaction_trace", tt) + m.notify(nonce, txHashes[start+i], Result{r.Receipt, ErrTxnFailed}) continue } + m.notify(nonce, txHashes[start+i], Result{r.Receipt, nil}) } } diff --git a/x/keysigner/keysigner.go b/x/keysigner/keysigner.go index f848c8c75..ad246ca85 100644 --- a/x/keysigner/keysigner.go +++ b/x/keysigner/keysigner.go @@ -18,7 +18,6 @@ type KeySigner interface { SignTx(tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) GetAddress() common.Address GetPrivateKey() (*ecdsa.PrivateKey, error) - ZeroPrivateKey(key *ecdsa.PrivateKey) GetAuth(chainID *big.Int) (*bind.TransactOpts, error) GetAuthWithCtx(ctx context.Context, chainID *big.Int) (*bind.TransactOpts, error) } diff --git a/x/keysigner/keystoresigner.go b/x/keysigner/keystoresigner.go deleted file mode 100644 index 74cef2ec8..000000000 --- a/x/keysigner/keystoresigner.go +++ /dev/null @@ -1,91 +0,0 @@ -package keysigner - -import ( - "context" - "crypto/ecdsa" - "fmt" - "math/big" - "runtime" - - "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/core/types" -) - -type KeystoreSigner struct { - keystore *keystore.KeyStore - password string - account accounts.Account -} - -func NewKeystoreSigner(path, password string) (*KeystoreSigner, error) { - // lightscripts are using 4MB memory and taking approximately 100ms CPU time on a modern processor to decrypt - keystore := keystore.NewKeyStore(path, keystore.LightScryptN, keystore.LightScryptP) - ksAccounts := keystore.Accounts() - - var account accounts.Account - if len(ksAccounts) == 0 { - var err error - account, err = keystore.NewAccount(password) - if err != nil { - return nil, fmt.Errorf("failed to create account: %w", err) - } - } else { - account = ksAccounts[0] - } - - if err := keystore.Unlock(account, password); err != nil { - return nil, err - } - - return &KeystoreSigner{ - keystore: keystore, - password: password, - account: account, - }, nil -} - -func (kss *KeystoreSigner) SignHash(hash []byte) ([]byte, error) { - return kss.keystore.SignHash(kss.account, hash) -} - -func (kss *KeystoreSigner) SignTx(tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { - return kss.keystore.SignTx(kss.account, tx, chainID) -} - -func (kss *KeystoreSigner) GetAddress() common.Address { - return kss.account.Address -} - -func (kss *KeystoreSigner) GetPrivateKey() (*ecdsa.PrivateKey, error) { - return extractPrivateKey(kss.account.URL.Path, kss.password) -} - -func (kss *KeystoreSigner) ZeroPrivateKey(key *ecdsa.PrivateKey) { - b := key.D.Bits() - for i := range b { - b[i] = 0 - } - // Force garbage collection to remove the key from memory - runtime.GC() -} - -func (kss *KeystoreSigner) String() string { - return kss.account.URL.String() -} - -func (kss *KeystoreSigner) GetAuth(chainID *big.Int) (*bind.TransactOpts, error) { - return bind.NewKeyStoreTransactorWithChainID(kss.keystore, kss.account, chainID) -} - -func (kss *KeystoreSigner) GetAuthWithCtx(ctx context.Context, chainID *big.Int) (*bind.TransactOpts, error) { - opts, err := kss.GetAuth(chainID) - if err != nil { - return nil, err - } - - opts.Context = ctx - return opts, nil -} diff --git a/x/keysigner/privatekeysigner.go b/x/keysigner/privatekeysigner.go index ccbfae319..34287b199 100644 --- a/x/keysigner/privatekeysigner.go +++ b/x/keysigner/privatekeysigner.go @@ -16,12 +16,12 @@ import ( "github.com/ethereum/go-ethereum/crypto" ) -type PrivateKeySigner struct { +type Signer struct { path string privKey *ecdsa.PrivateKey } -func NewPrivateKeySigner(path string) (*PrivateKeySigner, error) { +func NewSigner(path string) (*Signer, error) { privKeyFile, err := resolveFilePath(path) if err != nil { return nil, fmt.Errorf("failed to get private key file path: %w", err) @@ -36,33 +36,50 @@ func NewPrivateKeySigner(path string) (*PrivateKeySigner, error) { return nil, fmt.Errorf("failed to load private key from file '%s': %w", privKeyFile, err) } - return &PrivateKeySigner{ + return &Signer{ path: privKeyFile, privKey: privKey, }, nil } -func (pks *PrivateKeySigner) SignHash(hash []byte) ([]byte, error) { +func NewEncryptedSigner(path, password string) (*Signer, error) { + privKeyFile, err := resolveFilePath(path) + if err != nil { + return nil, fmt.Errorf("failed to get private key file path: %w", err) + } + + privKey, err := extractPrivateKey(privKeyFile, password) + if err != nil { + return nil, fmt.Errorf("failed to extract private key: %w", err) + } + + return &Signer{ + path: privKeyFile, + privKey: privKey, + }, nil +} + +func (pks *Signer) SignHash(hash []byte) ([]byte, error) { return crypto.Sign(hash, pks.privKey) } -func (pks *PrivateKeySigner) SignTx(tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { +func (pks *Signer) SignTx(tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { return types.SignTx(tx, types.NewLondonSigner(chainID), pks.privKey) } -func (pks *PrivateKeySigner) GetAddress() common.Address { +func (pks *Signer) GetAddress() common.Address { return crypto.PubkeyToAddress(pks.privKey.PublicKey) } -func (pks *PrivateKeySigner) GetPrivateKey() (*ecdsa.PrivateKey, error) { +func (pks *Signer) GetPrivateKey() (*ecdsa.PrivateKey, error) { return pks.privKey, nil } -func (pks *PrivateKeySigner) GetAuth(chainID *big.Int) (*bind.TransactOpts, error) { +func (pks *Signer) GetAuth(chainID *big.Int) (*bind.TransactOpts, error) { return bind.NewKeyedTransactorWithChainID(pks.privKey, chainID) } -func (pks *PrivateKeySigner) GetAuthWithCtx(ctx context.Context, chainID *big.Int) (*bind.TransactOpts, error) { +func (pks *Signer) GetAuthWithCtx(ctx context.Context, chainID *big.Int) (*bind.TransactOpts, error) { opts, err := pks.GetAuth(chainID) if err != nil { return nil, err @@ -71,11 +88,7 @@ func (pks *PrivateKeySigner) GetAuthWithCtx(ctx context.Context, chainID *big.In return opts, nil } -// ZeroPrivateKey does nothing because the private key for PKS persists in memory -// and should not be deleted. -func (pks *PrivateKeySigner) ZeroPrivateKey(key *ecdsa.PrivateKey) {} - -func (pks *PrivateKeySigner) String() string { +func (pks *Signer) String() string { return pks.path }