From 660539b3bf930519e71cc7eed0a3aad91bfdbc99 Mon Sep 17 00:00:00 2001 From: Felipe Andrade Date: Wed, 12 Jul 2023 10:28:32 -0700 Subject: [PATCH] round trip receipt --- op-ufm/op-ufm/pkg/config/config.go | 36 +++++++++++++++++++------- op-ufm/op-ufm/pkg/provider/handlers.go | 32 ++++++++++++++++++++++- 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/op-ufm/op-ufm/pkg/config/config.go b/op-ufm/op-ufm/pkg/config/config.go index c27806a..1c24274 100644 --- a/op-ufm/op-ufm/pkg/config/config.go +++ b/op-ufm/op-ufm/pkg/config/config.go @@ -38,10 +38,9 @@ type HealthzConfig struct { } type WalletConfig struct { - // default: 420 (Optimism Goerli) ChainID big.Int `toml:"chain_id"` - // signer | static, default: signer + // signer | static SignerMethod string `toml:"signer_method"` Address string `toml:"address"` // private key is used for static signing @@ -55,12 +54,14 @@ type WalletConfig struct { } type ProviderConfig struct { - Disabled bool `toml:"disabled"` - URL string `toml:"url"` - Wallet string `toml:"wallet"` - ReadOnly bool `toml:"read_only"` - ReadInterval TOMLDuration `toml:"read_interval"` - SendInterval TOMLDuration `toml:"send_interval"` + Disabled bool `toml:"disabled"` + URL string `toml:"url"` + ReadOnly bool `toml:"read_only"` + ReadInterval TOMLDuration `toml:"read_interval"` + SendInterval TOMLDuration `toml:"send_interval"` + Wallet string `toml:"wallet"` + ReceiptRetrievalInterval TOMLDuration `toml:"receipt_retrieval_interval"` + ReceiptRetrievalTimeout TOMLDuration `toml:"receipt_retrieval_timeout"` } func New(file string) (*Config, error) { @@ -120,6 +121,15 @@ func (c *Config) Validate() error { if wallet.Address == "" { return errors.Errorf("wallet [%s] address is missing", name) } + if wallet.TxValue.BitLen() == 0 { + return errors.Errorf("wallet [%s] tx_value is missing", name) + } + if wallet.GasLimit == 0 { + return errors.Errorf("wallet [%s] gas_limit is missing", name) + } + if wallet.GasFeeCap.BitLen() == 0 { + return errors.Errorf("wallet [%s] gas_fee_cap is missing", name) + } } for name, provider := range c.Providers { @@ -127,14 +137,20 @@ func (c *Config) Validate() error { return errors.Errorf("provider [%s] url is missing", name) } if provider.ReadInterval == 0 { - return errors.Errorf("provider [%s] read interval is missing", name) + return errors.Errorf("provider [%s] read_interval is missing", name) } if provider.SendInterval == 0 { - return errors.Errorf("provider [%s] send interval is missing", name) + return errors.Errorf("provider [%s] send_interval is missing", name) } if provider.Wallet == "" { return errors.Errorf("provider [%s] wallet is missing", name) } + if provider.SendInterval == 0 { + return errors.Errorf("provider [%s] receipt_retrieval_interval is missing", name) + } + if provider.SendInterval == 0 { + return errors.Errorf("provider [%s] receipt_retrieval_timeout is missing", name) + } if _, ok := c.Wallets[provider.Wallet]; !ok { return errors.Errorf("provider [%s] has an invalid wallet [%s]", name, provider.Wallet) } diff --git a/op-ufm/op-ufm/pkg/provider/handlers.go b/op-ufm/op-ufm/pkg/provider/handlers.go index 6ed3c6e..adb60e4 100644 --- a/op-ufm/op-ufm/pkg/provider/handlers.go +++ b/op-ufm/op-ufm/pkg/provider/handlers.go @@ -2,9 +2,11 @@ package provider import ( "context" + "time" "github.com/ethereum-optimism/optimism/op-service/tls" signer "github.com/ethereum-optimism/optimism/op-signer/client" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" @@ -39,7 +41,35 @@ func (p *Provider) Heartbeat(ctx context.Context) { if err != nil { log.Error("cant send transaction", "provider", p.name, "err", err) } - log.Info("transaction sent", "hash", signedTx.Hash().Hex()) + txHash := signedTx.Hash() + log.Info("transaction sent", "hash", txHash.Hex()) + + sentAt := time.Now() + var receipt *types.Receipt + attempt := 0 + for receipt == nil { + if time.Since(sentAt) >= time.Duration(p.config.ReceiptRetrievalTimeout) { + log.Error("receipt retrieval timedout", "provider", p.name, "hash", "ellapsed", time.Since(sentAt)) + break + } + time.Sleep(time.Duration(p.config.ReceiptRetrievalInterval)) + if attempt%10 == 0 { + log.Debug("checking for receipt...", "attempt", attempt, "ellapsed", time.Since(sentAt)) + } + receipt, err = ethClient.TransactionReceipt(ctx, txHash) + if err != nil && !errors.Is(err, ethereum.NotFound) { + log.Error("cant get receipt for transaction", "provider", p.name, "hash", txHash.Hex(), "err", err) + break + } + attempt++ + } + roundtrip := time.Since(sentAt) + + log.Info("got transaction receipt", "hash", txHash.Hex(), + "roundtrip", roundtrip, + "blockNumber", receipt.BlockNumber, + "blockHash", receipt.BlockHash, + "gasUsed", receipt.GasUsed) } func (p *Provider) dial(ctx context.Context) (*ethclient.Client, error) {