From 751662a9d756463efd1a591e664b9bb533fc3a9a Mon Sep 17 00:00:00 2001 From: mossid Date: Sat, 5 Jan 2019 09:19:30 +0100 Subject: [PATCH] invert dependency --- store/iavl/store.go | 7 +- store/iavl/store_test.go | 2 +- store/rootmulti/proof_test.go | 2 +- store/rootmulti/store.go | 2 +- store/rootmulti/store_test.go | 8 +- store/types/errors.go | 154 ++++++++++++++++++++++++++++++++++ store/types/gas_test.go | 2 +- 7 files changed, 165 insertions(+), 12 deletions(-) create mode 100644 store/types/errors.go diff --git a/store/iavl/store.go b/store/iavl/store.go index 28a9f8ab6a87..56a47b058edf 100644 --- a/store/iavl/store.go +++ b/store/iavl/store.go @@ -11,8 +11,7 @@ import ( cmn "github.com/tendermint/tendermint/libs/common" dbm "github.com/tendermint/tendermint/libs/db" - stypes "github.com/cosmos/cosmos-sdk/store/types" - "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/store/types" "github.com/cosmos/cosmos-sdk/store/cachekv" "github.com/cosmos/cosmos-sdk/store/tracekv" @@ -299,8 +298,8 @@ var _ types.Iterator = (*iavlIterator)(nil) func newIAVLIterator(tree *iavl.ImmutableTree, start, end []byte, ascending bool) *iavlIterator { iter := &iavlIterator{ tree: tree, - start: stypes.Cp(start), - end: stypes.Cp(end), + start: types.Cp(start), + end: types.Cp(end), ascending: ascending, iterCh: make(chan cmn.KVPair, 0), // Set capacity > 0? quitCh: make(chan struct{}), diff --git a/store/iavl/store_test.go b/store/iavl/store_test.go index f7d7da30794f..75593ac03ceb 100644 --- a/store/iavl/store_test.go +++ b/store/iavl/store_test.go @@ -11,7 +11,7 @@ import ( cmn "github.com/tendermint/tendermint/libs/common" dbm "github.com/tendermint/tendermint/libs/db" - "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/store/types" ) var ( diff --git a/store/rootmulti/proof_test.go b/store/rootmulti/proof_test.go index 51c974d45554..5498fba1ce0e 100644 --- a/store/rootmulti/proof_test.go +++ b/store/rootmulti/proof_test.go @@ -3,12 +3,12 @@ package rootmulti import ( "testing" - "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" dbm "github.com/tendermint/tendermint/libs/db" "github.com/cosmos/cosmos-sdk/store/iavl" + "github.com/cosmos/cosmos-sdk/store/types" ) func TestVerifyIAVLStoreQueryProof(t *testing.T) { diff --git a/store/rootmulti/store.go b/store/rootmulti/store.go index c087956da6bd..409718cdecaa 100644 --- a/store/rootmulti/store.go +++ b/store/rootmulti/store.go @@ -15,7 +15,7 @@ import ( "github.com/cosmos/cosmos-sdk/store/iavl" "github.com/cosmos/cosmos-sdk/store/tracekv" "github.com/cosmos/cosmos-sdk/store/transient" - "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/store/types" ) const ( diff --git a/store/rootmulti/store_test.go b/store/rootmulti/store_test.go index e042e0026f1b..692a18a20f49 100644 --- a/store/rootmulti/store_test.go +++ b/store/rootmulti/store_test.go @@ -8,7 +8,7 @@ import ( "github.com/tendermint/tendermint/crypto/merkle" dbm "github.com/tendermint/tendermint/libs/db" - "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/store/types" ) const useDebugDB = false @@ -157,18 +157,18 @@ func TestMultiStoreQuery(t *testing.T) { query := abci.RequestQuery{Path: "/key", Data: k, Height: ver} qres := multi.Query(query) require.EqualValues(t, types.CodeUnknownRequest, qres.Code) - require.EqualValues(t, types.CodespaceRoot, qres.Codespace) + require.EqualValues(t, types.CodespaceQuery, qres.Codespace) query.Path = "h897fy32890rf63296r92" qres = multi.Query(query) require.EqualValues(t, types.CodeUnknownRequest, qres.Code) - require.EqualValues(t, types.CodespaceRoot, qres.Codespace) + require.EqualValues(t, types.CodespaceQuery, qres.Codespace) // Test invalid store name. query.Path = "/garbage/key" qres = multi.Query(query) require.EqualValues(t, types.CodeUnknownRequest, qres.Code) - require.EqualValues(t, types.CodespaceRoot, qres.Codespace) + require.EqualValues(t, types.CodespaceQuery, qres.Codespace) // Test valid query with data. query.Path = "/store1/key" diff --git a/store/types/errors.go b/store/types/errors.go new file mode 100644 index 000000000000..c6471c7bdc4a --- /dev/null +++ b/store/types/errors.go @@ -0,0 +1,154 @@ +package types + +import ( + "fmt" + + cmn "github.com/tendermint/tendermint/libs/common" + + "github.com/cosmos/cosmos-sdk/codec" + + abci "github.com/tendermint/tendermint/abci/types" +) + +// CodeType - ABCI code identifier within codespace +type CodeType uint32 + +// CodespaceType - codespace identifier +type CodespaceType string + +// IsOK - is everything okay? +func (code CodeType) IsOK() bool { + if code == CodeOK { + return true + } + return false +} + +// SDK error codes +const ( + // Base error codes + CodeOK CodeType = 0 + CodeInternal CodeType = 1 + CodeTxDecode CodeType = 2 + CodeUnknownRequest CodeType = 6 + + // CodespaceQuery is a codespace for error codes in this file only. + CodespaceQuery CodespaceType = "query" +) + +func unknownCodeMsg(code CodeType) string { + return fmt.Sprintf("unknown code %d", code) +} + +// NOTE: Don't stringer this, we'll put better messages in later. +func CodeToDefaultMsg(code CodeType) string { + switch code { + case CodeInternal: + return "internal error" + case CodeTxDecode: + return "tx parse error" + case CodeUnknownRequest: + return "unknown request" + default: + return unknownCodeMsg(code) + } +} + +//-------------------------------------------------------------------------------- +// All errors are created via constructors so as to enable us to hijack them +// and inject stack traces if we really want to. + +// nolint +func ErrInternal(msg string) Error { + return newQueryError(CodeInternal, msg) +} +func ErrTxDecode(msg string) Error { + return newQueryError(CodeTxDecode, msg) +} +func ErrUnknownRequest(msg string) Error { + return newQueryError(CodeUnknownRequest, msg) +} + +//---------------------------------------- +// Error & queryError + +type cmnError = cmn.Error + +// sdk Error type +type Error interface { + // Implements cmn.Error + // Error() string + // Stacktrace() cmn.Error + // Trace(offset int, format string, args ...interface{}) cmn.Error + // Data() interface{} + cmnError + + Code() CodeType + ABCILog() string + QueryResult() abci.ResponseQuery +} + +func newQueryError(code CodeType, format string, args ...interface{}) *queryError { + if format == "" { + format = CodeToDefaultMsg(code) + } + return &queryError{ + code: code, + cmnError: cmn.NewError(format, args...), + } +} + +type queryError struct { + code CodeType + cmnError +} + +// Implements ABCIError. +func (err *queryError) Error() string { + return fmt.Sprintf(`ERROR: +Codespace: %s +Code: %d +Message: %#v +`, CodespaceQuery, err.code, err.cmnError.Error()) +} + +// Implements Error. +func (err *queryError) Code() CodeType { + return err.code +} + +// Implements ABCIError. +func (err *queryError) ABCILog() string { + cdc := codec.New() + errMsg := err.cmnError.Error() + jsonErr := humanReadableError{ + Codespace: CodespaceQuery, + Code: err.code, + Message: errMsg, + } + bz, er := cdc.MarshalJSON(jsonErr) + if er != nil { + panic(er) + } + stringifiedJSON := string(bz) + return stringifiedJSON +} + +// QueryResult allows us to return sdk.Error.QueryResult() in query responses +func (err *queryError) QueryResult() abci.ResponseQuery { + return abci.ResponseQuery{ + Code: uint32(err.Code()), + Codespace: string(CodespaceQuery), + Log: err.ABCILog(), + } +} + +//---------------------------------------- +// REST error utilities + +// parses the error into an object-like struct for exporting +type humanReadableError struct { + Codespace CodespaceType `json:"codespace"` + Code CodeType `json:"code"` + Message string `json:"message"` +} diff --git a/store/types/gas_test.go b/store/types/gas_test.go index 3b2866e458fd..81bb0c901747 100644 --- a/store/types/gas_test.go +++ b/store/types/gas_test.go @@ -45,7 +45,7 @@ func TestGasMeter(t *testing.T) { } } -func TestaddUint64Overflow(t *testing.T) { +func TestAddUint64Overflow(t *testing.T) { testCases := []struct { a, b uint64 result uint64