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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: tx status forward port #3816

Merged
merged 8 commits into from
Aug 28, 2024
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
5 changes: 3 additions & 2 deletions app/test/big_blob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,9 @@ func (s *BigBlobSuite) TestErrBlobsTooLarge() {
defer cancel()
res, err := txClient.SubmitPayForBlob(subCtx, []*share.Blob{tc.blob}, user.SetGasLimitAndGasPrice(1e9, appconsts.DefaultMinGasPrice))
require.Error(t, err)
require.NotNil(t, res)
require.Equal(t, tc.want, res.Code, err.Error())
require.Nil(t, res)
code := err.(*user.BroadcastTxError).Code
require.Equal(t, tc.want, code, err.Error())
})
}
}
16 changes: 11 additions & 5 deletions app/test/std_sdk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,20 +317,26 @@ func (s *StandardSDKIntegrationTestSuite) TestStandardSDK() {
// sign and submit the transactions
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
serviceClient := sdktx.NewServiceClient(s.cctx.GRPCClient)
msgs, signer := tt.msgFunc()
txClient, err := user.SetupTxClient(s.cctx.GoContext(), s.cctx.Keyring, s.cctx.GRPCClient, s.ecfg, user.WithDefaultAccount(signer))
require.NoError(t, err)
res, err := txClient.SubmitTx(s.cctx.GoContext(), msgs, blobfactory.DefaultTxOpts()...)
if tt.expectedCode != abci.CodeTypeOK {
require.Error(t, err)
require.Nil(t, res)
txHash := err.(*user.ExecutionError).TxHash
code := err.(*user.ExecutionError).Code
getTxResp, err := serviceClient.GetTx(s.cctx.GoContext(), &sdktx.GetTxRequest{Hash: txHash})
require.NoError(t, err)
assert.Equal(t, tt.expectedCode, code, getTxResp.TxResponse.RawLog)
} else {
require.NoError(t, err)
require.NotNil(t, res)
getTxResp, err := serviceClient.GetTx(s.cctx.GoContext(), &sdktx.GetTxRequest{Hash: res.TxHash})
require.NoError(t, err)
assert.Equal(t, tt.expectedCode, res.Code, getTxResp.TxResponse.RawLog)
}
serviceClient := sdktx.NewServiceClient(s.cctx.GRPCClient)
getTxResp, err := serviceClient.GetTx(s.cctx.GoContext(), &sdktx.GetTxRequest{Hash: res.TxHash})
require.NoError(t, err)
require.NotNil(t, res)
assert.Equal(t, tt.expectedCode, res.Code, getTxResp.TxResponse.RawLog)
})
}
}
Expand Down
66 changes: 47 additions & 19 deletions pkg/user/tx_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
sdktx "github.com/cosmos/cosmos-sdk/types/tx"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/rpc/core"
"google.golang.org/grpc"

"github.com/celestiaorg/celestia-app/v3/app"
Expand All @@ -31,7 +32,6 @@ import (
"github.com/celestiaorg/celestia-app/v3/pkg/appconsts"
"github.com/celestiaorg/celestia-app/v3/x/blob/types"
"github.com/celestiaorg/celestia-app/v3/x/minfee"
"github.com/tendermint/tendermint/rpc/core"
)

const (
Expand All @@ -44,11 +44,36 @@ type Option func(client *TxClient)
// TxResponse is a response from the chain after
// a transaction has been submitted.
type TxResponse struct {
// Height is the block height at which the transaction was included on-chain.
Height int64
TxHash string
Code uint32
}

// BroadcastTxError is an error that occurs when broadcasting a transaction.
type BroadcastTxError struct {
TxHash string
Code uint32
// ErrorLog is the error output of the app's logger
ErrorLog string
}

func (e *BroadcastTxError) Error() string {
return fmt.Sprintf("broadcast tx error: %s", e.ErrorLog)
}

// ExecutionError is an error that occurs when a transaction gets executed.
type ExecutionError struct {
TxHash string
Code uint32
// ErrorLog is the error output of the app's logger
ErrorLog string
}

func (e *ExecutionError) Error() string {
return fmt.Sprintf("tx execution failed with code %d: %s", e.Code, e.ErrorLog)
}

// WithGasMultiplier is a functional option allows to configure the gas multiplier.
func WithGasMultiplier(multiplier float64) Option {
return func(c *TxClient) {
Expand Down Expand Up @@ -213,7 +238,7 @@ func SetupTxClient(
func (client *TxClient) SubmitPayForBlob(ctx context.Context, blobs []*share.Blob, opts ...TxOption) (*TxResponse, error) {
resp, err := client.BroadcastPayForBlob(ctx, blobs, opts...)
if err != nil {
return parseTxResponse(resp, fmt.Errorf("failed to broadcast pay for blob: %v", err))
return nil, err
}

return client.ConfirmTx(ctx, resp.TxHash)
Expand All @@ -224,7 +249,7 @@ func (client *TxClient) SubmitPayForBlob(ctx context.Context, blobs []*share.Blo
func (client *TxClient) SubmitPayForBlobWithAccount(ctx context.Context, account string, blobs []*share.Blob, opts ...TxOption) (*TxResponse, error) {
resp, err := client.BroadcastPayForBlobWithAccount(ctx, account, blobs, opts...)
if err != nil {
return parseTxResponse(resp, fmt.Errorf("failed to broadcast pay for blob with account: %v", err))
return nil, err
}

return client.ConfirmTx(ctx, resp.TxHash)
Expand Down Expand Up @@ -268,7 +293,7 @@ func (client *TxClient) BroadcastPayForBlobWithAccount(ctx context.Context, acco
func (client *TxClient) SubmitTx(ctx context.Context, msgs []sdktypes.Msg, opts ...TxOption) (*TxResponse, error) {
resp, err := client.BroadcastTx(ctx, msgs, opts...)
if err != nil {
return parseTxResponse(resp, fmt.Errorf("failed to broadcast tx: %v", err))
return nil, err
}

return client.ConfirmTx(ctx, resp.TxHash)
Expand Down Expand Up @@ -354,7 +379,12 @@ func (client *TxClient) broadcastTx(ctx context.Context, txBytes []byte, signer
}
return client.retryBroadcastingTx(ctx, txBytes)
}
return resp.TxResponse, fmt.Errorf("tx failed with code %d: %s", resp.TxResponse.Code, resp.TxResponse.RawLog)
broadcastTxErr := &BroadcastTxError{
TxHash: resp.TxResponse.TxHash,
Code: resp.TxResponse.Code,
ErrorLog: resp.TxResponse.RawLog,
}
return resp.TxResponse, broadcastTxErr
}

// after the transaction has been submitted, we can increment the
Expand Down Expand Up @@ -435,16 +465,16 @@ func (client *TxClient) ConfirmTx(ctx context.Context, txHash string) (*TxRespon
for {
resp, err := txClient.TxStatus(ctx, &tx.TxStatusRequest{TxId: txHash})
if err != nil {
return &TxResponse{}, err
return nil, err
}

if err == nil && resp != nil {
if resp != nil {
switch resp.Status {
case core.TxStatusPending:
// Continue polling if the transaction is still pending
select {
case <-ctx.Done():
return &TxResponse{}, ctx.Err()
return nil, ctx.Err()
case <-pollTicker.C:
continue
}
Expand All @@ -454,14 +484,19 @@ func (client *TxClient) ConfirmTx(ctx context.Context, txHash string) (*TxRespon
TxHash: txHash,
Code: resp.ExecutionCode,
}
if resp.ExecutionCode != 0 {
return txResponse, fmt.Errorf("tx was committed but failed with code %d: %s", resp.ExecutionCode, resp.Error)
if resp.ExecutionCode != abci.CodeTypeOK {
executionErr := &ExecutionError{
TxHash: txHash,
Code: resp.ExecutionCode,
ErrorLog: resp.Error,
}
return nil, executionErr
}
return txResponse, nil
case core.TxStatusEvicted:
return &TxResponse{TxHash: txHash}, fmt.Errorf("tx: %s was evicted from the mempool", txHash)
return nil, fmt.Errorf("tx was evicted from the mempool")
default:
return &TxResponse{}, fmt.Errorf("unknown tx: %s", txHash)
return nil, fmt.Errorf("unknown tx: %s", txHash)
}
}
}
Expand Down Expand Up @@ -569,13 +604,6 @@ func (client *TxClient) getAccountNameFromMsgs(msgs []sdktypes.Msg) (string, err
return record.Name, nil
}

func parseTxResponse(resp *sdktypes.TxResponse, err error) (*TxResponse, error) {
if resp != nil {
return &TxResponse{Code: resp.Code, TxHash: resp.TxHash}, err
}
return &TxResponse{}, err
}

// Signer exposes the tx clients underlying signer
func (client *TxClient) Signer() *Signer {
return client.signer
Expand Down
7 changes: 4 additions & 3 deletions pkg/user/tx_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

sdk "github.com/cosmos/cosmos-sdk/types"
sdktx "github.com/cosmos/cosmos-sdk/types/tx"
"github.com/cosmos/cosmos-sdk/x/authz"
bank "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
Expand All @@ -19,7 +20,6 @@ import (
"github.com/celestiaorg/celestia-app/v3/pkg/user"
"github.com/celestiaorg/celestia-app/v3/test/util/blobfactory"
"github.com/celestiaorg/celestia-app/v3/test/util/testnode"
"github.com/cosmos/cosmos-sdk/x/authz"
)

func TestTxClientTestSuite(t *testing.T) {
Expand Down Expand Up @@ -209,9 +209,10 @@ func (suite *TxClientTestSuite) TestConfirmTx() {
resp, err := suite.txClient.BroadcastTx(suite.ctx.GoContext(), []sdk.Msg{msg}, fee, gas)
require.NoError(t, err)
require.NotNil(t, resp)
confirmTxResp, err := suite.txClient.ConfirmTx(suite.ctx.GoContext(), resp.TxHash)
_, err = suite.txClient.ConfirmTx(suite.ctx.GoContext(), resp.TxHash)
require.Error(t, err)
require.NotEqual(t, abci.CodeTypeOK, confirmTxResp.Code)
code := err.(*user.ExecutionError).Code
require.NotEqual(t, abci.CodeTypeOK, code)
})
}

Expand Down
16 changes: 11 additions & 5 deletions x/blobstream/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,20 +81,26 @@ func (s *BlobstreamIntegrationSuite) TestBlobstream() {
// sign and submit the transactions
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
serviceClient := sdktx.NewServiceClient(s.cctx.GRPCClient)
msgs, _ := tt.msgFunc()
txClient, err := user.SetupTxClient(s.cctx.GoContext(), s.cctx.Keyring, s.cctx.GRPCClient, s.ecfg)
require.NoError(t, err)
res, err := txClient.SubmitTx(s.cctx.GoContext(), msgs, blobfactory.DefaultTxOpts()...)
if tt.expectedTxCode == abci.CodeTypeOK {
require.NoError(t, err)
require.NotNil(t, res)
getTxResp, err := serviceClient.GetTx(s.cctx.GoContext(), &sdktx.GetTxRequest{Hash: res.TxHash})
require.NoError(t, err)
require.Equal(t, tt.expectedTxCode, res.Code, getTxResp.TxResponse.RawLog)
} else {
require.Error(t, err)
require.Nil(t, res)
txHash := err.(*user.ExecutionError).TxHash
code := err.(*user.ExecutionError).Code
getTxResp, err := serviceClient.GetTx(s.cctx.GoContext(), &sdktx.GetTxRequest{Hash: txHash})
require.NoError(t, err)
require.Equal(t, tt.expectedTxCode, code, getTxResp.TxResponse.RawLog)
}
serviceClient := sdktx.NewServiceClient(s.cctx.GRPCClient)
getTxResp, err := serviceClient.GetTx(s.cctx.GoContext(), &sdktx.GetTxRequest{Hash: res.TxHash})
require.NoError(t, err)
require.NotNil(t, res)
require.Equal(t, tt.expectedTxCode, res.Code, getTxResp.TxResponse.RawLog)
})
}
}
23 changes: 13 additions & 10 deletions x/signal/legacy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/celestiaorg/celestia-app/v3/app"
"github.com/celestiaorg/celestia-app/v3/app/encoding"
"github.com/celestiaorg/celestia-app/v3/pkg/user"
testutil "github.com/celestiaorg/celestia-app/v3/test/util"
"github.com/celestiaorg/celestia-app/v3/test/util/blobfactory"
"github.com/celestiaorg/celestia-app/v3/test/util/genesis"
Expand Down Expand Up @@ -120,14 +121,14 @@ func (s *LegacyUpgradeTestSuite) TestLegacyGovUpgradeFailure() {
require.NoError(t, err)

// submit the transaction and wait a block for it to be included
signer, err := testnode.NewTxClientFromContext(s.cctx)
txClient, err := testnode.NewTxClientFromContext(s.cctx)
require.NoError(t, err)
subCtx, cancel := context.WithTimeout(s.cctx.GoContext(), time.Minute)
defer cancel()
res, err := signer.SubmitTx(subCtx, []sdk.Msg{msg}, blobfactory.DefaultTxOpts()...)
require.Error(t, err)
_, err = txClient.SubmitTx(subCtx, []sdk.Msg{msg}, blobfactory.DefaultTxOpts()...)
code := err.(*user.BroadcastTxError).Code
// As the type is not registered, the message will fail with unable to resolve type URL
require.EqualValues(t, 2, res.Code)
require.EqualValues(t, 2, code, err.Error())
}

// TestNewGovUpgradeFailure verifies that a transaction with a
Expand All @@ -149,14 +150,15 @@ func (s *LegacyUpgradeTestSuite) TestNewGovUpgradeFailure() {
require.NoError(t, err)

// submit the transaction and wait a block for it to be included
signer, err := testnode.NewTxClientFromContext(s.cctx)
txClient, err := testnode.NewTxClientFromContext(s.cctx)
require.NoError(t, err)
subCtx, cancel := context.WithTimeout(s.cctx.GoContext(), time.Minute)
defer cancel()
res, err := signer.SubmitTx(subCtx, []sdk.Msg{msg}, blobfactory.DefaultTxOpts()...)
require.Error(t, err)
_, err = txClient.SubmitTx(subCtx, []sdk.Msg{msg}, blobfactory.DefaultTxOpts()...)
// As the type is not registered, the message will fail with unable to resolve type URL
require.EqualValues(t, 2, res.Code)
require.Error(t, err)
code := err.(*user.BroadcastTxError).Code
require.EqualValues(t, 2, code, err.Error())
}

func (s *LegacyUpgradeTestSuite) TestIBCUpgradeFailure() {
Expand All @@ -182,9 +184,10 @@ func (s *LegacyUpgradeTestSuite) TestIBCUpgradeFailure() {
require.NoError(t, err)
subCtx, cancel := context.WithTimeout(s.cctx.GoContext(), time.Minute)
defer cancel()
res, err := txClient.SubmitTx(subCtx, []sdk.Msg{msg}, blobfactory.DefaultTxOpts()...)
_, err = txClient.SubmitTx(subCtx, []sdk.Msg{msg}, blobfactory.DefaultTxOpts()...)
require.Error(t, err)
require.EqualValues(t, 9, res.Code) // we're only submitting the tx, so we expect everything to work
code := err.(*user.ExecutionError).Code
require.EqualValues(t, 9, code) // we're only submitting the tx, so we expect everything to work
assert.Contains(t, err.Error(), "ibc upgrade proposal not supported")
}

Expand Down
Loading