diff --git a/actpool/actpool.go b/actpool/actpool.go index 1310359ddb..2eda0bd5df 100644 --- a/actpool/actpool.go +++ b/actpool/actpool.go @@ -212,7 +212,8 @@ func (ap *actPool) Add(act action.SealedEnvelope) error { // Reject action if the gas price is lower than the threshold if act.GasPrice().Cmp(ap.cfg.MinGasPrice()) < 0 { actpoolMtc.WithLabelValues("gasPriceLower").Inc() - return errors.Errorf( + return errors.Wrapf( + action.ErrGasPrice, "reject the action %x whose gas price %s is lower than minimal gas price threshold", hash, act.GasPrice(), diff --git a/api/api.go b/api/api.go index 29bc5fad3f..5c8f77ae9f 100644 --- a/api/api.go +++ b/api/api.go @@ -25,6 +25,7 @@ import ( "github.com/iotexproject/iotex-proto/golang/iotextypes" "github.com/pkg/errors" "go.uber.org/zap" + "google.golang.org/genproto/googleapis/rpc/errdetails" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/reflection" @@ -327,7 +328,35 @@ func (api *Server) SendAction(ctx context.Context, in *iotexapi.SendActionReques // Add to local actpool if err = api.ap.Add(selp); err != nil { log.L().Debug(err.Error()) - return nil, status.Error(codes.Internal, err.Error()) + var desc string + switch errors.Cause(err) { + case action.ErrBalance: + desc = "Invalid balance" + case action.ErrInsufficientBalanceForGas: + desc = "Insufficient balance for gas" + case action.ErrNonce: + desc = "Invalid nonce" + case action.ErrAddress: + desc = "Blacklisted address" + case action.ErrActPool: + desc = "Invalid actpool" + case action.ErrGasPrice: + desc = "Invalid gas price" + default: + desc = "Unknown" + } + st := status.New(codes.Internal, err.Error()) + v := &errdetails.BadRequest_FieldViolation{ + Field: "Action rejected", + Description: desc, + } + br := &errdetails.BadRequest{} + br.FieldViolations = append(br.FieldViolations, v) + st, err := st.WithDetails(br) + if err != nil { + log.S().Panicf("Unexpected error attaching metadata: %v", err) + } + return nil, st.Err() } // If there is no error putting into local actpool, // Broadcast it to the network diff --git a/go.mod b/go.mod index e97fa0f807..70d08cdc66 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/gogo/protobuf v1.2.1 github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef github.com/golang/mock v1.3.1 - github.com/golang/protobuf v1.3.1 + github.com/golang/protobuf v1.3.2 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/iotexproject/go-fsm v1.0.0 github.com/iotexproject/go-p2p v0.2.10 @@ -45,6 +45,7 @@ require ( golang.org/x/sync v0.0.0-20190423024810-112230192c58 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 // indirect + google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6 google.golang.org/grpc v1.21.0 gopkg.in/urfave/cli.v1 v1.20.0 // indirect gopkg.in/yaml.v2 v2.2.2 diff --git a/go.sum b/go.sum index 40faf3f7d4..97cbbe0e78 100644 --- a/go.sum +++ b/go.sum @@ -102,6 +102,8 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -561,6 +563,8 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101 h1:wuGevabY6r+ivPNagjUXGGxF+GqgMd+dBhjsxW4q9u4= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6 h1:UXl+Zk3jqqcbEVV7ace5lrt4YdA4tXiz3f/KbmD29Vo= +google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=