Skip to content

feat: chain and gas usage metrics #38

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Oct 23, 2024
Merged
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ genmocks:
mockgen -destination=./mock/gas.go -source=./chains/evm/transactor/gas/gas-pricer.go -package mock
mockgen -destination=./mock/relayer.go -source=./relayer/relayer.go -package mock
mockgen -source=chains/evm/transactor/transact.go -destination=./mock/transact.go -package mock
mockgen -source=chains/evm/transactor/signAndSend/signAndSend.go -destination=./mock/signAndSend.go -package mock
mockgen -source=chains/evm/transactor/monitored/monitored.go -destination=./mock/monitored.go -package mock
mockgen -source=./store/store.go -destination=./mock/store.go -package mock
mockgen -source=./relayer/message/handler.go -destination=./mock/message.go -package mock
mockgen -source=./chains/evm/listener/listener.go -destination=./mock/evmListener.go -package mock
Expand Down
39 changes: 34 additions & 5 deletions chains/evm/transactor/monitored/monitored.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"

"github.com/sygmaprotocol/sygma-core/chains/evm/client"
Expand All @@ -19,6 +20,10 @@ type GasPricer interface {
GasPrice(priority *uint8) ([]*big.Int, error)
}

type GasTracker interface {
TrackGasUsage(domainID uint8, gasUsed uint64, gasPrice *big.Int)
}

type RawTx struct {
nonce uint64
to *common.Address
Expand All @@ -30,9 +35,26 @@ type RawTx struct {
creationTime time.Time
}

// GasPrice returns transaction gas price in gwei
//
// It returns base fee for both London and legacy transactions.
func (tx *RawTx) GasPrice() *big.Int {
var gasPrice *big.Int
if len(tx.gasPrice) == 1 {
gasPrice = tx.gasPrice[0]
} else {
gasPrice = tx.gasPrice[1]
}
return new(big.Int).Div(gasPrice, big.NewInt(1e9))
}

type MonitoredTransactor struct {
domainID uint8
log zerolog.Logger

txFabric transaction.TxFabric
gasPriceClient GasPricer
gasTracker GasTracker
client client.Client

maxGasPrice *big.Int
Expand All @@ -49,15 +71,20 @@ type MonitoredTransactor struct {
// Gas price is increased by increasePercentage param which
// is a percentage value with which old gas price should be increased (e.g 15)
func NewMonitoredTransactor(
domainID uint8,
txFabric transaction.TxFabric,
gasPriceClient GasPricer,
gasTracker GasTracker,
client client.Client,
maxGasPrice *big.Int,
increasePercentage *big.Int,
) *MonitoredTransactor {
return &MonitoredTransactor{
domainID: domainID,
log: log.With().Uint8("domainID", domainID).Logger(),
client: client,
gasPriceClient: gasPriceClient,
gasTracker: gasTracker,
txFabric: txFabric,
pendingTxns: make(map[common.Hash]RawTx),
maxGasPrice: maxGasPrice,
Expand Down Expand Up @@ -143,18 +170,20 @@ func (t *MonitoredTransactor) Monitor(
for oldHash, tx := range pendingTxCopy {
receipt, err := t.client.TransactionReceipt(context.Background(), oldHash)
if err == nil {
t.gasTracker.TrackGasUsage(t.domainID, receipt.GasUsed, tx.GasPrice())

if receipt.Status == types.ReceiptStatusSuccessful {
log.Info().Uint64("nonce", tx.nonce).Msgf("Executed transaction %s with nonce %d", oldHash, tx.nonce)
t.log.Info().Uint64("nonce", tx.nonce).Msgf("Executed transaction %s with nonce %d", oldHash, tx.nonce)
} else {
log.Error().Uint64("nonce", tx.nonce).Msgf("Transaction %s failed on chain", oldHash)
t.log.Error().Uint64("nonce", tx.nonce).Msgf("Transaction %s failed on chain", oldHash)
}

delete(t.pendingTxns, oldHash)
continue
}

if time.Since(tx.creationTime) > txTimeout {
log.Error().Uint64("nonce", tx.nonce).Msgf("Transaction %s has timed out", oldHash)
t.log.Error().Uint64("nonce", tx.nonce).Msgf("Transaction %s has timed out", oldHash)
delete(t.pendingTxns, oldHash)
continue
}
Expand All @@ -164,7 +193,7 @@ func (t *MonitoredTransactor) Monitor(

hash, err := t.resendTransaction(&tx)
if err != nil {
log.Warn().Uint64("nonce", tx.nonce).Err(err).Msgf("Failed resending transaction %s", hash)
t.log.Warn().Uint64("nonce", tx.nonce).Err(err).Msgf("Failed resending transaction %s", hash)
continue
}

Expand All @@ -188,7 +217,7 @@ func (t *MonitoredTransactor) resendTransaction(tx *RawTx) (common.Hash, error)
return common.Hash{}, err
}

log.Debug().Uint64("nonce", tx.nonce).Msgf("Resent transaction with hash %s", hash)
t.log.Debug().Uint64("nonce", tx.nonce).Msgf("Resent transaction with hash %s", hash)

return hash, nil
}
Expand Down
19 changes: 19 additions & 0 deletions chains/evm/transactor/monitored/monitored_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type TransactorTestSuite struct {
suite.Suite
gomockController *gomock.Controller
mockClient *mock.MockClient
mockGasTracker *mock.MockGasTracker
mockTransactor *mock.MockTransactor
mockGasPricer *mock.MockGasPricer
}
Expand All @@ -34,6 +35,8 @@ func (s *TransactorTestSuite) SetupTest() {
s.mockClient = mock.NewMockClient(s.gomockController)
s.mockTransactor = mock.NewMockTransactor(s.gomockController)
s.mockGasPricer = mock.NewMockGasPricer(s.gomockController)
s.mockGasTracker = mock.NewMockGasTracker(s.gomockController)
s.mockGasTracker.EXPECT().TrackGasUsage(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
}

func (s *TransactorTestSuite) TestTransactor_SignAndSend_Success() {
Expand All @@ -47,8 +50,10 @@ func (s *TransactorTestSuite) TestTransactor_SignAndSend_Success() {
s.mockClient.EXPECT().UnlockNonce()

t := monitored.NewMonitoredTransactor(
1,
transaction.NewTransaction,
s.mockGasPricer,
s.mockGasTracker,
s.mockClient,
big.NewInt(1000),
big.NewInt(15))
Expand All @@ -72,8 +77,10 @@ func (s *TransactorTestSuite) TestTransactor_SignAndSend_Fail() {
s.mockClient.EXPECT().UnlockNonce()

t := monitored.NewMonitoredTransactor(
1,
transaction.NewTransaction,
s.mockGasPricer,
s.mockGasTracker,
s.mockClient,
big.NewInt(1000),
big.NewInt(15))
Expand All @@ -99,8 +106,10 @@ func (s *TransactorTestSuite) TestTransactor_MonitoredTransaction_SuccessfulExec

ctx, cancel := context.WithCancel(context.Background())
t := monitored.NewMonitoredTransactor(
1,
transaction.NewTransaction,
s.mockGasPricer,
s.mockGasTracker,
s.mockClient,
big.NewInt(1000),
big.NewInt(15))
Expand Down Expand Up @@ -134,8 +143,10 @@ func (s *TransactorTestSuite) TestTransactor_MonitoredTransaction_TxTimeout() {

ctx, cancel := context.WithCancel(context.Background())
t := monitored.NewMonitoredTransactor(
1,
transaction.NewTransaction,
s.mockGasPricer,
s.mockGasTracker,
s.mockClient,
big.NewInt(1000),
big.NewInt(15))
Expand Down Expand Up @@ -169,8 +180,10 @@ func (s *TransactorTestSuite) TestTransactor_MonitoredTransaction_TransactionRes

ctx, cancel := context.WithCancel(context.Background())
t := monitored.NewMonitoredTransactor(
1,
transaction.NewTransaction,
s.mockGasPricer,
s.mockGasTracker,
s.mockClient,
big.NewInt(1000),
big.NewInt(15))
Expand Down Expand Up @@ -208,8 +221,10 @@ func (s *TransactorTestSuite) TestTransactor_MonitoredTransaction_MaxGasPriceRea

ctx, cancel := context.WithCancel(context.Background())
t := monitored.NewMonitoredTransactor(
1,
transaction.NewTransaction,
s.mockGasPricer,
s.mockGasTracker,
s.mockClient,
big.NewInt(10),
big.NewInt(15))
Expand All @@ -233,8 +248,10 @@ func (s *TransactorTestSuite) TestTransactor_MonitoredTransaction_MaxGasPriceRea

func (s *TransactorTestSuite) TestTransactor_IncreaseGas_15PercentIncrease() {
t := monitored.NewMonitoredTransactor(
1,
transaction.NewTransaction,
s.mockGasPricer,
s.mockGasTracker,
s.mockClient,
big.NewInt(150),
big.NewInt(15))
Expand All @@ -246,8 +263,10 @@ func (s *TransactorTestSuite) TestTransactor_IncreaseGas_15PercentIncrease() {

func (s *TransactorTestSuite) TestTransactor_IncreaseGas_MaxGasReached() {
t := monitored.NewMonitoredTransactor(
1,
transaction.NewTransaction,
s.mockGasPricer,
s.mockGasTracker,
s.mockClient,
big.NewInt(15),
big.NewInt(15))
Expand Down
39 changes: 37 additions & 2 deletions mock/signAndSend.go → mock/monitored.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading