Skip to content

Commit

Permalink
feat(eth): simulate call before transact
Browse files Browse the repository at this point in the history
  • Loading branch information
Darkness4 committed Feb 16, 2024
1 parent 95e6045 commit b5a9686
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 136 deletions.
14 changes: 6 additions & 8 deletions cli/metascheduler/metascheduler_allowancemanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ package metascheduler

import (
"context"
"fmt"
"math/big"

internallog "github.com/deepsquare-io/grid/cli/internal/log"
"github.com/deepsquare-io/grid/cli/types"
metaschedulerabi "github.com/deepsquare-io/grid/cli/types/abi/metascheduler"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
coretypes "github.com/ethereum/go-ethereum/core/types"
"go.uber.org/zap"
)

Expand All @@ -33,17 +33,15 @@ type allowanceManager struct {
}

func (c *allowanceManager) SetAllowance(ctx context.Context, amount *big.Int) error {
opts, err := c.authOpts(ctx)
tx, err := c.transact(ctx, func(auth *bind.TransactOpts) (*coretypes.Transaction, error) {
return c.Approve(auth, c.MetaschedulerAddress, amount)
})
if err != nil {
return fmt.Errorf("failed get auth options: %w", err)
}
tx, err := c.Approve(opts, c.MetaschedulerAddress, amount)
if err != nil {
return fmt.Errorf("failed to approve credit: %w", err)
return WrapError(err)
}
receipt, err := bind.WaitMined(ctx, c, tx)
if err != nil {
return fmt.Errorf("failed to wait for transaction to be mined: %w", err)
return WrapError(err)
}
internallog.I.Debug("metascheduled job", zap.Any("receipt", receipt))
return CheckReceiptError(ctx, c, tx, receipt)
Expand Down
10 changes: 4 additions & 6 deletions cli/metascheduler/metascheduler_creditmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ package metascheduler

import (
"context"
"fmt"
"math/big"

internallog "github.com/deepsquare-io/grid/cli/internal/log"
"github.com/deepsquare-io/grid/cli/types"
metaschedulerabi "github.com/deepsquare-io/grid/cli/types/abi/metascheduler"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
coretypes "github.com/ethereum/go-ethereum/core/types"
"go.uber.org/zap"
)

Expand All @@ -45,11 +45,9 @@ func (c *creditManager) BalanceOf(ctx context.Context, address common.Address) (
}

func (c *creditManager) Transfer(ctx context.Context, to common.Address, amount *big.Int) error {
opts, err := c.authOpts(ctx)
if err != nil {
return fmt.Errorf("failed to create auth options: %w", err)
}
tx, err := c.IERC20.Transfer(opts, to, amount)
tx, err := c.transact(ctx, func(auth *bind.TransactOpts) (*coretypes.Transaction, error) {
return c.IERC20.Transfer(auth, to, amount)
})
if err != nil {
return WrapError(err)
}
Expand Down
10 changes: 4 additions & 6 deletions cli/metascheduler/metascheduler_error.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
errorsabi "github.com/deepsquare-io/grid/cli/types/abi/errors"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
Expand Down Expand Up @@ -665,7 +664,7 @@ func ParseError(name string, inputs []interface{}) error {

func CheckReceiptError(
ctx context.Context,
client bind.ContractCaller,
client ethereum.GasEstimator,
tx *types.Transaction,
receipt *types.Receipt,
) error {
Expand All @@ -692,7 +691,7 @@ func CheckReceiptError(
}

// Replay transaction to find error reason
_, err = client.CallContract(ctx, ethereum.CallMsg{
if _, err = client.EstimateGas(ctx, ethereum.CallMsg{
To: tx.To(),
From: from,
Gas: tx.Gas(),
Expand All @@ -702,13 +701,12 @@ func CheckReceiptError(
Value: tx.Value(),
Data: tx.Data(),
AccessList: tx.AccessList(),
}, receipt.BlockNumber)
if err != nil {
}); err != nil {
return fmt.Errorf(
"tx failed, tx: %s, status: %d, error: %w",
receipt.TxHash,
receipt.Status,
err,
WrapError(err),
)
}

Expand Down
66 changes: 28 additions & 38 deletions cli/metascheduler/metascheduler_jobscheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
metaschedulerabi "github.com/deepsquare-io/grid/cli/types/abi/metascheduler"
"github.com/deepsquare-io/grid/cli/types/job"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/core/types"
"go.uber.org/zap"
)

Expand All @@ -41,17 +42,15 @@ func (c *jobScheduler) requestNewJob(
jobName [32]byte,
delegateSpendingAuthority bool,
) (id [32]byte, err error) {
opts, err := c.authOpts(ctx)
if err != nil {
return [32]byte{}, fmt.Errorf("failed to create auth options: %w", err)
}
tx, err := c.MetaScheduler.RequestNewJob(
opts,
definition,
lockedCredits,
jobName,
delegateSpendingAuthority,
)
tx, err := c.transact(ctx, func(auth *bind.TransactOpts) (*types.Transaction, error) {
return c.MetaScheduler.RequestNewJob(
auth,
definition,
lockedCredits,
jobName,
delegateSpendingAuthority,
)
})
if err != nil {
return [32]byte{}, WrapError(err)
}
Expand All @@ -61,7 +60,7 @@ func (c *jobScheduler) requestNewJob(
if err != nil {
return [32]byte{}, fmt.Errorf("failed to wait transaction to be mined: %w", err)
}
if CheckReceiptError(ctx, c, tx, receipt) != nil {
if err := CheckReceiptError(ctx, c, tx, receipt); err != nil {
return [32]byte{}, err
}

Expand Down Expand Up @@ -132,39 +131,30 @@ func (c *jobScheduler) SubmitJob(
}

func (c *jobScheduler) CancelJob(ctx context.Context, id [32]byte) error {
opts, err := c.authOpts(ctx)
if err != nil {
return fmt.Errorf("failed to create auth options: %w", err)
}
_, err = c.MetaScheduler.CancelJob(
opts,
id,
)
_, err := c.transact(ctx, func(auth *bind.TransactOpts) (*types.Transaction, error) {
return c.MetaScheduler.CancelJob(auth, id)
})
return WrapError(err)
}

func (c *jobScheduler) PanicJob(ctx context.Context, id [32]byte, reason string) error {
opts, err := c.authOpts(ctx)
if err != nil {
return fmt.Errorf("failed to create auth options: %w", err)
}
_, err = c.MetaScheduler.PanicJob(
opts,
id,
reason,
)
_, err := c.transact(ctx, func(auth *bind.TransactOpts) (*types.Transaction, error) {
return c.MetaScheduler.PanicJob(
auth,
id,
reason,
)
})
return WrapError(err)
}

func (c *jobScheduler) TopUpJob(ctx context.Context, id [32]byte, amount *big.Int) error {
opts, err := c.authOpts(ctx)
if err != nil {
return fmt.Errorf("failed to create auth options: %w", err)
}
_, err = c.MetaScheduler.TopUpJob(
opts,
id,
amount,
)
_, err := c.transact(ctx, func(auth *bind.TransactOpts) (*types.Transaction, error) {
return c.MetaScheduler.TopUpJob(
auth,
id,
amount,
)
})
return WrapError(err)
}
21 changes: 9 additions & 12 deletions cli/metascheduler/metascheduler_providermanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/deepsquare-io/grid/cli/types/provider"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
coretypes "github.com/ethereum/go-ethereum/core/types"
"go.uber.org/zap"
)

Expand All @@ -37,13 +38,11 @@ type providerManager struct {
}

func (c *providerManager) ApproveProvider(ctx context.Context, provider common.Address) error {
opts, err := c.authOpts(ctx)
tx, err := c.transact(ctx, func(auth *bind.TransactOpts) (*coretypes.Transaction, error) {
return c.IProviderManager.Approve(auth, provider)
})
if err != nil {
return fmt.Errorf("failed get auth options: %w", err)
}
tx, err := c.IProviderManager.Approve(opts, provider)
if err != nil {
return fmt.Errorf("failed to approve provider: %w", err)
return WrapError(err)
}
receipt, err := bind.WaitMined(ctx, c, tx)
if err != nil {
Expand All @@ -54,13 +53,11 @@ func (c *providerManager) ApproveProvider(ctx context.Context, provider common.A
}

func (c *providerManager) RemoveProvider(ctx context.Context, provider common.Address) error {
opts, err := c.authOpts(ctx)
if err != nil {
return fmt.Errorf("failed get auth options: %w", err)
}
tx, err := c.IProviderManager.Remove(opts, provider)
tx, err := c.transact(ctx, func(auth *bind.TransactOpts) (*coretypes.Transaction, error) {
return c.IProviderManager.Remove(auth, provider)
})
if err != nil {
return fmt.Errorf("failed to remove provider: %w", err)
return WrapError(err)
}
receipt, err := bind.WaitMined(ctx, c, tx)
if err != nil {
Expand Down
43 changes: 41 additions & 2 deletions cli/metascheduler/metascheduler_rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ import (
"github.com/deepsquare-io/grid/cli/types/credit"
"github.com/deepsquare-io/grid/cli/types/job"
"github.com/deepsquare-io/grid/cli/types/provider"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/core/types"
)

// RPCClientSet is a set of clients that interact with DeepSquare.
Expand All @@ -35,7 +37,10 @@ type RPCClientSet struct {
}

// authOpts generate transact options based on the network.
func (c *RPCClientSet) authOpts(ctx context.Context) (*bind.TransactOpts, error) {
func (c *RPCClientSet) transact(
ctx context.Context,
exec func(auth *bind.TransactOpts) (*types.Transaction, error),
) (*types.Transaction, error) {
nonce, err := c.PendingNonceAt(ctx, c.from())
if err != nil {
return nil, err
Expand All @@ -56,7 +61,41 @@ func (c *RPCClientSet) authOpts(ctx context.Context) (*bind.TransactOpts, error)
auth.GasPrice = gasPrice
auth.Context = ctx

return auth, nil
simulated := &bind.TransactOpts{
From: auth.From,
Signer: auth.Signer,
Nonce: auth.Nonce,
Value: auth.Value,
GasPrice: auth.GasPrice,
GasFeeCap: auth.GasFeeCap,
GasTipCap: auth.GasTipCap,
GasLimit: auth.GasLimit,
Context: auth.Context,
NoSend: true,
}

// Simuate the transaction
tx, err := exec(simulated)
if err != nil {
return nil, err
}

// Play fake transaction to find error reason
if _, err = c.EstimateGas(ctx, ethereum.CallMsg{
To: tx.To(),
From: auth.From,
Gas: tx.Gas(),
GasPrice: tx.GasPrice(),
GasFeeCap: tx.GasFeeCap(),
GasTipCap: tx.GasTipCap(),
Value: tx.Value(),
Data: tx.Data(),
AccessList: tx.AccessList(),
}); err != nil {
return nil, err
}

return exec(auth)
}

// NewRPCClientSet creates an RPCClientSet.
Expand Down
10 changes: 4 additions & 6 deletions sbatch-service/types/types_error.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
errorabi "github.com/deepsquare-io/grid/sbatch-service/abi/error"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
Expand Down Expand Up @@ -654,7 +653,7 @@ func ParseError(name string, inputs []interface{}) error {

func CheckReceiptError(
ctx context.Context,
client bind.ContractCaller,
client ethereum.GasEstimator,
tx *types.Transaction,
receipt *types.Receipt,
) error {
Expand All @@ -681,7 +680,7 @@ func CheckReceiptError(
}

// Replay transaction to find error reason
_, err = client.CallContract(ctx, ethereum.CallMsg{
if _, err = client.EstimateGas(ctx, ethereum.CallMsg{
To: tx.To(),
From: from,
Gas: tx.Gas(),
Expand All @@ -691,13 +690,12 @@ func CheckReceiptError(
Value: tx.Value(),
Data: tx.Data(),
AccessList: tx.AccessList(),
}, receipt.BlockNumber)
if err != nil {
}); err != nil {
return fmt.Errorf(
"tx failed, tx: %s, status: %d, error: %w",
receipt.TxHash,
receipt.Status,
err,
WrapError(err),
)
}

Expand Down
Loading

0 comments on commit b5a9686

Please sign in to comment.