From 4faae92298d73d3c95f938d0e75614ea9f1311c3 Mon Sep 17 00:00:00 2001 From: mrekucci Date: Fri, 29 Sep 2023 17:58:44 +0400 Subject: [PATCH] fix: include the reason when the redistribution contract call fails (#4358) --- pkg/postage/postagecontract/contract.go | 15 ++++++--------- pkg/storageincentives/agent.go | 2 +- .../redistribution/redistribution.go | 6 ++++-- pkg/transaction/mock/transaction.go | 4 ++++ pkg/transaction/transaction.go | 18 ++++++++++++++++++ 5 files changed, 33 insertions(+), 12 deletions(-) diff --git a/pkg/postage/postagecontract/contract.go b/pkg/postage/postagecontract/contract.go index 94c3dc99061..666037c39d6 100644 --- a/pkg/postage/postagecontract/contract.go +++ b/pkg/postage/postagecontract/contract.go @@ -178,7 +178,7 @@ func (c *postageContract) sendApproveTransaction(ctx context.Context, amount *bi return receipt, nil } -func (c *postageContract) sendTransaction(ctx context.Context, callData []byte, desc string) (*types.Receipt, error) { +func (c *postageContract) sendTransaction(ctx context.Context, callData []byte, desc string) (receipt *types.Receipt, err error) { request := &transaction.TxRequest{ To: &c.postageStampContractAddress, Data: callData, @@ -187,25 +187,22 @@ func (c *postageContract) sendTransaction(ctx context.Context, callData []byte, Value: big.NewInt(0), Description: desc, } + defer func() { + err = c.transactionService.UnwrapRevertReason(ctx, request, err) + }() txHash, err := c.transactionService.Send(ctx, request, transaction.DefaultTipBoostPercent) if err != nil { return nil, err } - receipt, err := c.transactionService.WaitForReceipt(ctx, txHash) + receipt, err = c.transactionService.WaitForReceipt(ctx, txHash) if err != nil { return nil, err } if receipt.Status == 0 { - err := transaction.ErrTransactionReverted - if res, cErr := c.transactionService.Call(ctx, request); cErr == nil { - if reason, uErr := abi.UnpackRevert(res); uErr == nil { - err = fmt.Errorf("%w: reason: %s", err, reason) - } - } - return nil, err + return nil, transaction.ErrTransactionReverted } return receipt, nil diff --git a/pkg/storageincentives/agent.go b/pkg/storageincentives/agent.go index b856625025e..16e7770c859 100644 --- a/pkg/storageincentives/agent.go +++ b/pkg/storageincentives/agent.go @@ -24,7 +24,7 @@ import ( "github.com/ethersphere/bee/pkg/storage" "github.com/ethersphere/bee/pkg/storageincentives/redistribution" "github.com/ethersphere/bee/pkg/storageincentives/staking" - storer "github.com/ethersphere/bee/pkg/storer" + "github.com/ethersphere/bee/pkg/storer" "github.com/ethersphere/bee/pkg/swarm" "github.com/ethersphere/bee/pkg/transaction" ) diff --git a/pkg/storageincentives/redistribution/redistribution.go b/pkg/storageincentives/redistribution/redistribution.go index 2c163f5a76c..ce0692da943 100644 --- a/pkg/storageincentives/redistribution/redistribution.go +++ b/pkg/storageincentives/redistribution/redistribution.go @@ -180,8 +180,10 @@ func (c *contract) ReserveSalt(ctx context.Context) ([]byte, error) { return salt[:], nil } -func (c *contract) sendAndWait(ctx context.Context, request *transaction.TxRequest, boostPercent int) (common.Hash, error) { - txHash, err := c.txService.Send(ctx, request, boostPercent) +func (c *contract) sendAndWait(ctx context.Context, request *transaction.TxRequest, boostPercent int) (txHash common.Hash, err error) { + defer func() { err = c.txService.UnwrapRevertReason(ctx, request, err) }() + + txHash, err = c.txService.Send(ctx, request, boostPercent) if err != nil { return txHash, err } diff --git a/pkg/transaction/mock/transaction.go b/pkg/transaction/mock/transaction.go index f9a557f00be..6110dfeea1d 100644 --- a/pkg/transaction/mock/transaction.go +++ b/pkg/transaction/mock/transaction.go @@ -97,6 +97,10 @@ func (m *transactionServiceMock) TransactionFee(ctx context.Context, txHash comm return big.NewInt(0), nil } +func (m *transactionServiceMock) UnwrapRevertReason(_ context.Context, _ *transaction.TxRequest, err error) error { + return err +} + // Option is the option passed to the mock Chequebook service type Option interface { apply(*transactionServiceMock) diff --git a/pkg/transaction/transaction.go b/pkg/transaction/transaction.go index f000965992d..906ca295ebe 100644 --- a/pkg/transaction/transaction.go +++ b/pkg/transaction/transaction.go @@ -14,6 +14,7 @@ import ( "time" "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethersphere/bee/pkg/crypto" @@ -94,6 +95,9 @@ type Service interface { CancelTransaction(ctx context.Context, originalTxHash common.Hash) (common.Hash, error) // TransactionFee retrieves the transaction fee TransactionFee(ctx context.Context, txHash common.Hash) (*big.Int, error) + // UnwrapRevertReason tries to unwrap the revert reason if the given error is not nil. + // The original error is wrapped in case the revert reason exists. + UnwrapRevertReason(ctx context.Context, req *TxRequest, err error) error } type transactionService struct { @@ -584,3 +588,17 @@ func (t *transactionService) TransactionFee(ctx context.Context, txHash common.H } return trx.Cost(), nil } + +func (t *transactionService) UnwrapRevertReason(ctx context.Context, req *TxRequest, err error) error { + if err == nil { + return nil + } + + if res, cErr := t.Call(ctx, req); cErr == nil { + if reason, uErr := abi.UnpackRevert(res); uErr == nil { + err = fmt.Errorf("%w: reason: %s", err, reason) + } + } + + return err +}