Skip to content

Commit

Permalink
Expose precheck errors from tx
Browse files Browse the repository at this point in the history
  • Loading branch information
tnachen committed Sep 4, 2019
1 parent f010d2c commit a904f67
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 0 deletions.
39 changes: 39 additions & 0 deletions client/context/broadcast.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package context
import (
"fmt"

"github.com/tendermint/tendermint/mempool"

"github.com/cosmos/cosmos-sdk/client/flags"
sdk "github.com/cosmos/cosmos-sdk/types"
)
Expand All @@ -29,6 +31,27 @@ func (ctx CLIContext) BroadcastTx(txBytes []byte) (res sdk.TxResponse, err error
return res, err
}

func CheckTendermintError(err error) *sdk.TxResponse {
if err == nil {
return nil
}

if err == mempool.ErrTxInCache {
return &sdk.TxResponse{Code: uint32(sdk.CodeTxInCache)}
}

switch err.(type) {
case mempool.ErrMempoolIsFull:
return &sdk.TxResponse{Code: uint32(sdk.CodeMempoolIsFull)}
case mempool.ErrPreCheck:
return &sdk.TxResponse{Code: uint32(sdk.CodeFailedPreCheck)}
case mempool.ErrTxTooLarge:
return &sdk.TxResponse{Code: uint32(sdk.CodeTxTooLarge)}
}

return nil
}

// BroadcastTxCommit broadcasts transaction bytes to a Tendermint node and
// waits for a commit. An error is only returned if there is no RPC node
// connection or if broadcasting fails.
Expand All @@ -44,6 +67,10 @@ func (ctx CLIContext) BroadcastTxCommit(txBytes []byte) (sdk.TxResponse, error)

res, err := node.BroadcastTxCommit(txBytes)
if err != nil {
if res := CheckTendermintError(err); res != nil {
return *res, err
}

return sdk.NewResponseFormatBroadcastTxCommit(res), err
}

Expand All @@ -67,6 +94,12 @@ func (ctx CLIContext) BroadcastTxSync(txBytes []byte) (sdk.TxResponse, error) {
}

res, err := node.BroadcastTxSync(txBytes)
if err != nil {
if res := CheckTendermintError(err); res != nil {
return *res, err
}
}

return sdk.NewResponseFormatBroadcastTx(res), err
}

Expand All @@ -79,5 +112,11 @@ func (ctx CLIContext) BroadcastTxAsync(txBytes []byte) (sdk.TxResponse, error) {
}

res, err := node.BroadcastTxAsync(txBytes)
if err != nil {
if res := CheckTendermintError(err); res != nil {
return *res, err
}
}

return sdk.NewResponseFormatBroadcastTx(res), err
}
63 changes: 63 additions & 0 deletions client/context/broadcast_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package context

import (
"testing"

"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/mempool"
"github.com/tendermint/tendermint/rpc/client/mock"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
tmtypes "github.com/tendermint/tendermint/types"
)

type MockClient struct {
mock.Client
err error
}

func (c MockClient) BroadcastTxCommit(tx tmtypes.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
return nil, c.err
}

func (c MockClient) BroadcastTxAsync(tx tmtypes.Tx) (*ctypes.ResultBroadcastTx, error) {
return nil, c.err
}

func (c MockClient) BroadcastTxSync(tx tmtypes.Tx) (*ctypes.ResultBroadcastTx, error) {
return nil, c.err
}

func CreateContextWithErrorAndMode(err error, mode string) CLIContext {
return CLIContext{
Client: MockClient{err: err},
BroadcastMode: mode,
}
}

// Test the correct code is returned when
func TestBroadcastError(t *testing.T) {
errors := map[error]uint32{
mempool.ErrTxInCache: uint32(types.CodeTxInCache),
mempool.ErrTxTooLarge{}: uint32(types.CodeTxTooLarge),
mempool.ErrPreCheck{}: uint32(types.CodeFailedPreCheck),
mempool.ErrMempoolIsFull{}: uint32(types.CodeMempoolIsFull),
}

modes := []string{
flags.BroadcastAsync,
flags.BroadcastBlock,
flags.BroadcastSync,
}

for _, mode := range modes {
for err, code := range errors {
ctx := CreateContextWithErrorAndMode(err, mode)
resp, returnedErr := ctx.BroadcastTx([]byte{})
require.Error(t, returnedErr)
require.Equal(t, code, resp.Code)
}
}

}
4 changes: 4 additions & 0 deletions types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ const (
CodeTooManySignatures CodeType = 15
CodeGasOverflow CodeType = 16
CodeNoSignatures CodeType = 17
CodeTxInCache CodeType = 18
CodeMempoolIsFull CodeType = 19
CodeFailedPreCheck CodeType = 20
CodeTxTooLarge CodeType = 21

// CodespaceRoot is a codespace for error codes in this file only.
// Notice that 0 is an "unset" codespace, which can be overridden with
Expand Down

0 comments on commit a904f67

Please sign in to comment.