diff --git a/packages/relayer/message/estimate_gas.go b/packages/relayer/message/estimate_gas.go new file mode 100644 index 00000000000..bfb59609e9d --- /dev/null +++ b/packages/relayer/message/estimate_gas.go @@ -0,0 +1,30 @@ +package message + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/pkg/errors" + "github.com/taikoxyz/taiko-mono/packages/relayer/contracts/bridge" +) + +func (p *Processor) estimateGas( + ctx context.Context, message bridge.IBridgeMessage, proof []byte) (uint64, *big.Int, error) { + auth, err := bind.NewKeyedTransactorWithChainID(p.ecdsaKey, message.DestChainId) + if err != nil { + return 0, nil, errors.Wrap(err, "bind.NewKeyedTransactorWithChainID") + } + + auth.NoSend = true + + auth.Context = ctx + + // estimate gas with auth.NoSend set to true + tx, err := p.destBridge.ProcessMessage(auth, message, proof) + if err != nil { + return 0, nil, errors.Wrap(err, "p.destBridge.ProcessMessage") + } + + return tx.Gas(), tx.Cost(), nil +} diff --git a/packages/relayer/message/is_profitable.go b/packages/relayer/message/is_profitable.go index 43e35241adf..6728fa3ac63 100644 --- a/packages/relayer/message/is_profitable.go +++ b/packages/relayer/message/is_profitable.go @@ -4,37 +4,18 @@ import ( "context" "math/big" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/pkg/errors" log "github.com/sirupsen/logrus" "github.com/taikoxyz/taiko-mono/packages/relayer/contracts/bridge" ) func (p *Processor) isProfitable( - ctx context.Context, message bridge.IBridgeMessage, proof []byte) (bool, uint64, error) { + ctx context.Context, message bridge.IBridgeMessage, cost *big.Int) (bool, error) { processingFee := message.ProcessingFee if processingFee == nil || processingFee.Cmp(big.NewInt(0)) != 1 { - return false, 0, nil + return false, nil } - auth, err := bind.NewKeyedTransactorWithChainID(p.ecdsaKey, message.DestChainId) - if err != nil { - return false, 0, errors.Wrap(err, "bind.NewKeyedTransactorWithChainID") - } - - auth.NoSend = true - - auth.Context = ctx - - // estimate gas with auth.NoSend set to true - tx, err := p.destBridge.ProcessMessage(auth, message, proof) - if err != nil { - return false, 0, errors.Wrap(err, "p.destBridge.ProcessMessage") - } - - cost := tx.Cost() - shouldProcess := processingFee.Cmp(cost) == 1 log.Infof( @@ -45,8 +26,8 @@ func (p *Processor) isProfitable( ) if !shouldProcess { - return false, 0, nil + return false, nil } - return true, tx.Gas(), nil + return true, nil } diff --git a/packages/relayer/message/is_profitable_test.go b/packages/relayer/message/is_profitable_test.go index aac1c7f5b5b..827d61bd4f0 100644 --- a/packages/relayer/message/is_profitable_test.go +++ b/packages/relayer/message/is_profitable_test.go @@ -16,7 +16,7 @@ func Test_isProfitable(t *testing.T) { tests := []struct { name string message bridge.IBridgeMessage - proof []byte + cost *big.Int wantProfitable bool wantErr error }{ @@ -25,24 +25,24 @@ func Test_isProfitable(t *testing.T) { bridge.IBridgeMessage{ ProcessingFee: big.NewInt(0), }, - nil, + big.NewInt(1), false, nil, }, { "nilProcessingFee", bridge.IBridgeMessage{}, - nil, + big.NewInt(1), false, nil, }, { - "lowProcessingFee", + "lowProcessingFeeHighCost", bridge.IBridgeMessage{ ProcessingFee: new(big.Int).Sub(mock.ProcessMessageTx.Cost(), big.NewInt(1)), DestChainId: big.NewInt(167001), }, - nil, + big.NewInt(1000000), false, nil, }, @@ -52,7 +52,7 @@ func Test_isProfitable(t *testing.T) { ProcessingFee: new(big.Int).Add(mock.ProcessMessageTx.Cost(), big.NewInt(1)), DestChainId: big.NewInt(167001), }, - nil, + big.NewInt(1), true, nil, }, @@ -60,10 +60,10 @@ func Test_isProfitable(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - profitable, _, err := p.isProfitable( + profitable, err := p.isProfitable( context.Background(), tt.message, - tt.proof, + tt.cost, ) assert.Equal(t, tt.wantProfitable, profitable) diff --git a/packages/relayer/message/process_message.go b/packages/relayer/message/process_message.go index c32f2b7be29..6336a1e070d 100644 --- a/packages/relayer/message/process_message.go +++ b/packages/relayer/message/process_message.go @@ -136,18 +136,20 @@ func (p *Processor) sendProcessMessageCall( return nil, errors.New("p.getLatestNonce") } - // profitable, gas, err := p.isProfitable(ctx, event.Message, proof) - // if err != nil { - // return nil, errors.Wrap(err, "p.isProfitable") - // } - - // if bool(p.profitableOnly) && !profitable { - // return nil, relayer.ErrUnprofitable - // } - - // if gas != 0 { - auth.GasLimit = 2500000 - // } + gas, cost, err := p.estimateGas(ctx, event.Message, proof) + if err != nil || gas == 0 { + // we can get unable to estimet gas for contract deployments within the contract code. + // if we get an error or the gas is 0, lets manual set high gas limit and ignore error, + // and try to actually send. + auth.GasLimit = 3000000 + } + + if bool(p.profitableOnly) { + profitable, err := p.isProfitable(ctx, event.Message, cost) + if err != nil || !profitable { + return nil, relayer.ErrUnprofitable + } + } // process the message on the destination bridge. tx, err := p.destBridge.ProcessMessage(auth, event.Message, proof)