Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(relayer): estimate gas for tx, set gas to 2.5mil if not estimatable. works now. #13271

Merged
merged 3 commits into from
Mar 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions packages/relayer/message/estimate_gas.go
Original file line number Diff line number Diff line change
@@ -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
}
27 changes: 4 additions & 23 deletions packages/relayer/message/is_profitable.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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
}
16 changes: 8 additions & 8 deletions packages/relayer/message/is_profitable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}{
Expand All @@ -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,
},
Expand All @@ -52,18 +52,18 @@ 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,
},
}

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)
Expand Down
26 changes: 14 additions & 12 deletions packages/relayer/message/process_message.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down