Error codespacing (#809)
* Initial codespacing layout (ref #766) * Add codespace to Router (ref #766) * Implement Codespacer and update modules * Default codespaces, testcases * Update error formatting, codespacer tests * Add RegisterOrPanic testcase * Update CHANGELOG
This commit is contained in:
parent
ffd428d199
commit
f8e44b5b00
|
@ -13,6 +13,7 @@ BREAKING CHANGES
|
|||
* Remove go-wire, use go-amino
|
||||
* [store] Add `SubspaceIterator` and `ReverseSubspaceIterator` to `KVStore` interface
|
||||
* [basecoin] NewBasecoinApp takes a `dbm.DB` and uses namespaced DBs for substores
|
||||
* All module keepers now require a codespace, see basecoin or democoin for usage
|
||||
|
||||
BUG FIXES
|
||||
|
||||
|
|
|
@ -342,7 +342,7 @@
|
|||
"types/priv_validator",
|
||||
"version"
|
||||
]
|
||||
revision = "d0beaba7e8a5652506a34b5fab299cc2dc274c02"
|
||||
revision = "a2930cd7233f04f5a651020669289296545e70dc"
|
||||
version = "v0.19.0"
|
||||
|
||||
[[projects]]
|
||||
|
@ -384,6 +384,7 @@
|
|||
name = "golang.org/x/net"
|
||||
packages = [
|
||||
"context",
|
||||
"http/httpguts",
|
||||
"http2",
|
||||
"http2/hpack",
|
||||
"idna",
|
||||
|
@ -391,13 +392,13 @@
|
|||
"lex/httplex",
|
||||
"trace"
|
||||
]
|
||||
revision = "61147c48b25b599e5b561d2e9c4f3e1ef489ca41"
|
||||
revision = "8d16fa6dc9a85c1cd3ed24ad08ff21cf94f10888"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sys"
|
||||
packages = ["unix"]
|
||||
revision = "3b87a42e500a6dc65dae1a55d0b641295971163e"
|
||||
revision = "b126b21c05a91c856b027c16779c12e3bf236954"
|
||||
|
||||
[[projects]]
|
||||
name = "golang.org/x/text"
|
||||
|
@ -424,7 +425,7 @@
|
|||
branch = "master"
|
||||
name = "google.golang.org/genproto"
|
||||
packages = ["googleapis/rpc/status"]
|
||||
revision = "51d0944304c3cbce4afe9e5247e21100037bff78"
|
||||
revision = "7fd901a49ba6a7f87732eb344f6e3c5b19d1b200"
|
||||
|
||||
[[projects]]
|
||||
name = "google.golang.org/grpc"
|
||||
|
|
|
@ -24,11 +24,12 @@ var dbHeaderKey = []byte("header")
|
|||
// The ABCI application
|
||||
type BaseApp struct {
|
||||
// initialized on creation
|
||||
Logger log.Logger
|
||||
name string // application name from abci.Info
|
||||
db dbm.DB // common DB backend
|
||||
cms sdk.CommitMultiStore // Main (uncached) state
|
||||
router Router // handle any kind of message
|
||||
Logger log.Logger
|
||||
name string // application name from abci.Info
|
||||
db dbm.DB // common DB backend
|
||||
cms sdk.CommitMultiStore // Main (uncached) state
|
||||
router Router // handle any kind of message
|
||||
codespacer *sdk.Codespacer // handle module codespacing
|
||||
|
||||
// must be set
|
||||
txDecoder sdk.TxDecoder // unmarshal []byte into sdk.Tx
|
||||
|
@ -56,13 +57,18 @@ var _ abci.Application = (*BaseApp)(nil)
|
|||
// Create and name new BaseApp
|
||||
// NOTE: The db is used to store the version number for now.
|
||||
func NewBaseApp(name string, logger log.Logger, db dbm.DB) *BaseApp {
|
||||
return &BaseApp{
|
||||
Logger: logger,
|
||||
name: name,
|
||||
db: db,
|
||||
cms: store.NewCommitMultiStore(db),
|
||||
router: NewRouter(),
|
||||
app := &BaseApp{
|
||||
Logger: logger,
|
||||
name: name,
|
||||
db: db,
|
||||
cms: store.NewCommitMultiStore(db),
|
||||
router: NewRouter(),
|
||||
codespacer: sdk.NewCodespacer(),
|
||||
}
|
||||
// Register the undefined & root codespaces, which should not be used by any modules
|
||||
app.codespacer.RegisterOrPanic(sdk.CodespaceUndefined)
|
||||
app.codespacer.RegisterOrPanic(sdk.CodespaceRoot)
|
||||
return app
|
||||
}
|
||||
|
||||
// BaseApp Name
|
||||
|
@ -70,6 +76,11 @@ func (app *BaseApp) Name() string {
|
|||
return app.name
|
||||
}
|
||||
|
||||
// Register the next available codespace through the baseapp's codespacer, starting from a default
|
||||
func (app *BaseApp) RegisterCodespace(codespace sdk.CodespaceType) sdk.CodespaceType {
|
||||
return app.codespacer.RegisterNext(codespace)
|
||||
}
|
||||
|
||||
// Mount a store to the provided key in the BaseApp multistore
|
||||
func (app *BaseApp) MountStoresIAVL(keys ...*sdk.KVStoreKey) {
|
||||
for _, key := range keys {
|
||||
|
@ -355,6 +366,7 @@ func (app *BaseApp) runTx(isCheckTx bool, txBytes []byte, tx sdk.Tx) (result sdk
|
|||
// Validate the Msg.
|
||||
err := msg.ValidateBasic()
|
||||
if err != nil {
|
||||
err = err.WithDefaultCodespace(sdk.CodespaceRoot)
|
||||
return err.Result()
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ func TestKeys(t *testing.T) {
|
|||
jsonStr = []byte(fmt.Sprintf(`{"name":"%s", "password":"%s", "seed": "%s"}`, newName, newPassword, newSeed))
|
||||
res, body = request(t, port, "POST", "/keys", jsonStr)
|
||||
|
||||
assert.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
addr := body
|
||||
assert.Len(t, addr, 40, "Returned address has wrong format", addr)
|
||||
|
||||
|
@ -311,7 +311,11 @@ func TestTxs(t *testing.T) {
|
|||
// strt TM and the LCD in process, listening on their respective sockets
|
||||
func startTMAndLCD() (*nm.Node, net.Listener, error) {
|
||||
|
||||
viper.Set(cli.HomeFlag, os.TempDir())
|
||||
dir, err := ioutil.TempDir("", "lcd_test")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
viper.Set(cli.HomeFlag, dir)
|
||||
kb, err := keys.GetKeyBase() // dbm.NewMemDB()) // :(
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
|
|
@ -65,8 +65,8 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp {
|
|||
|
||||
// Add handlers.
|
||||
coinKeeper := bank.NewCoinKeeper(app.accountMapper)
|
||||
ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore)
|
||||
stakeKeeper := simplestake.NewKeeper(app.capKeyStakingStore, coinKeeper)
|
||||
ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore, app.RegisterCodespace(ibc.DefaultCodespace))
|
||||
stakeKeeper := simplestake.NewKeeper(app.capKeyStakingStore, coinKeeper, app.RegisterCodespace(simplestake.DefaultCodespace))
|
||||
app.Router().
|
||||
AddRoute("bank", bank.NewHandler(coinKeeper)).
|
||||
AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)).
|
||||
|
@ -123,7 +123,7 @@ func (app *BasecoinApp) txDecoder(txBytes []byte) (sdk.Tx, sdk.Error) {
|
|||
// are registered by MakeTxCodec in bank.RegisterAmino.
|
||||
err := app.cdc.UnmarshalBinary(txBytes, &tx)
|
||||
if err != nil {
|
||||
return nil, sdk.ErrTxDecode("").TraceCause(err, "")
|
||||
return nil, sdk.ErrTxDecode("").Trace(err.Error())
|
||||
}
|
||||
return tx, nil
|
||||
}
|
||||
|
|
|
@ -166,7 +166,7 @@ func TestSortGenesis(t *testing.T) {
|
|||
|
||||
// Unsorted coins means invalid
|
||||
err := sendMsg5.ValidateBasic()
|
||||
require.Equal(t, sdk.CodeInvalidCoins, err.ABCICode(), err.ABCILog())
|
||||
require.Equal(t, sdk.CodeInvalidCoins, err.Code(), err.ABCILog())
|
||||
|
||||
// Sort coins, should be valid
|
||||
sendMsg5.Inputs[0].Coins.Sort()
|
||||
|
@ -243,7 +243,7 @@ func TestSendMsgWithAccounts(t *testing.T) {
|
|||
tx.Signatures[0].Sequence = 1
|
||||
res := bapp.Deliver(tx)
|
||||
|
||||
assert.Equal(t, sdk.CodeUnauthorized, res.Code, res.Log)
|
||||
assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), res.Code, res.Log)
|
||||
|
||||
// resigning the tx with the bumped sequence should work
|
||||
SignCheckDeliver(t, bapp, sendMsg1, []int64{1}, true, priv1)
|
||||
|
@ -437,18 +437,18 @@ func SignCheckDeliver(t *testing.T, bapp *BasecoinApp, msg sdk.Msg, seq []int64,
|
|||
// Run a Check
|
||||
res := bapp.Check(tx)
|
||||
if expPass {
|
||||
require.Equal(t, sdk.CodeOK, res.Code, res.Log)
|
||||
require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||
} else {
|
||||
require.NotEqual(t, sdk.CodeOK, res.Code, res.Log)
|
||||
require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||
}
|
||||
|
||||
// Simulate a Block
|
||||
bapp.BeginBlock(abci.RequestBeginBlock{})
|
||||
res = bapp.Deliver(tx)
|
||||
if expPass {
|
||||
require.Equal(t, sdk.CodeOK, res.Code, res.Log)
|
||||
require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||
} else {
|
||||
require.NotEqual(t, sdk.CodeOK, res.Code, res.Log)
|
||||
require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||
}
|
||||
bapp.EndBlock(abci.RequestEndBlock{})
|
||||
//bapp.Commit()
|
||||
|
|
|
@ -70,10 +70,10 @@ func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp {
|
|||
|
||||
// Add handlers.
|
||||
coinKeeper := bank.NewCoinKeeper(app.accountMapper)
|
||||
coolKeeper := cool.NewKeeper(app.capKeyMainStore, coinKeeper)
|
||||
powKeeper := pow.NewKeeper(app.capKeyPowStore, pow.NewPowConfig("pow", int64(1)), coinKeeper)
|
||||
ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore)
|
||||
stakeKeeper := simplestake.NewKeeper(app.capKeyStakingStore, coinKeeper)
|
||||
coolKeeper := cool.NewKeeper(app.capKeyMainStore, coinKeeper, app.RegisterCodespace(cool.DefaultCodespace))
|
||||
powKeeper := pow.NewKeeper(app.capKeyPowStore, pow.NewPowConfig("pow", int64(1)), coinKeeper, app.RegisterCodespace(pow.DefaultCodespace))
|
||||
ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore, app.RegisterCodespace(ibc.DefaultCodespace))
|
||||
stakeKeeper := simplestake.NewKeeper(app.capKeyStakingStore, coinKeeper, app.RegisterCodespace(simplestake.DefaultCodespace))
|
||||
app.Router().
|
||||
AddRoute("bank", bank.NewHandler(coinKeeper)).
|
||||
AddRoute("cool", cool.NewHandler(coolKeeper)).
|
||||
|
@ -136,7 +136,7 @@ func (app *DemocoinApp) txDecoder(txBytes []byte) (sdk.Tx, sdk.Error) {
|
|||
// are registered by MakeTxCodec in bank.RegisterWire.
|
||||
err := app.cdc.UnmarshalBinary(txBytes, &tx)
|
||||
if err != nil {
|
||||
return nil, sdk.ErrTxDecode("").TraceCause(err, "")
|
||||
return nil, sdk.ErrTxDecode("").Trace(err.Error())
|
||||
}
|
||||
return tx, nil
|
||||
}
|
||||
|
|
|
@ -202,12 +202,12 @@ func TestSendMsgWithAccounts(t *testing.T) {
|
|||
|
||||
// Run a Check
|
||||
res := bapp.Check(tx)
|
||||
assert.Equal(t, sdk.CodeOK, res.Code, res.Log)
|
||||
assert.Equal(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||
|
||||
// Simulate a Block
|
||||
bapp.BeginBlock(abci.RequestBeginBlock{})
|
||||
res = bapp.Deliver(tx)
|
||||
assert.Equal(t, sdk.CodeOK, res.Code, res.Log)
|
||||
assert.Equal(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||
|
||||
// Check balances
|
||||
ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{})
|
||||
|
@ -218,19 +218,19 @@ func TestSendMsgWithAccounts(t *testing.T) {
|
|||
|
||||
// Delivering again should cause replay error
|
||||
res = bapp.Deliver(tx)
|
||||
assert.Equal(t, sdk.CodeInvalidSequence, res.Code, res.Log)
|
||||
assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeInvalidSequence), sdk.ABCICodeType(res.Code), res.Log)
|
||||
|
||||
// bumping the txnonce number without resigning should be an auth error
|
||||
tx.Signatures[0].Sequence = 1
|
||||
res = bapp.Deliver(tx)
|
||||
assert.Equal(t, sdk.CodeUnauthorized, res.Code, res.Log)
|
||||
assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), sdk.ABCICodeType(res.Code), res.Log)
|
||||
|
||||
// resigning the tx with the bumped sequence should work
|
||||
sequences = []int64{1}
|
||||
sig = priv1.Sign(sdk.StdSignBytes(chainID, sequences, fee, tx.Msg))
|
||||
tx.Signatures[0].Signature = sig
|
||||
res = bapp.Deliver(tx)
|
||||
assert.Equal(t, sdk.CodeOK, res.Code, res.Log)
|
||||
assert.Equal(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||
}
|
||||
|
||||
func TestMineMsg(t *testing.T) {
|
||||
|
@ -403,18 +403,18 @@ func SignCheckDeliver(t *testing.T, bapp *DemocoinApp, msg sdk.Msg, seq int64, e
|
|||
// Run a Check
|
||||
res := bapp.Check(tx)
|
||||
if expPass {
|
||||
require.Equal(t, sdk.CodeOK, res.Code, res.Log)
|
||||
require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||
} else {
|
||||
require.NotEqual(t, sdk.CodeOK, res.Code, res.Log)
|
||||
require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||
}
|
||||
|
||||
// Simulate a Block
|
||||
bapp.BeginBlock(abci.RequestBeginBlock{})
|
||||
res = bapp.Deliver(tx)
|
||||
if expPass {
|
||||
require.Equal(t, sdk.CodeOK, res.Code, res.Log)
|
||||
require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||
} else {
|
||||
require.NotEqual(t, sdk.CodeOK, res.Code, res.Log)
|
||||
require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log)
|
||||
}
|
||||
bapp.EndBlock(abci.RequestEndBlock{})
|
||||
//bapp.Commit()
|
||||
|
|
|
@ -7,11 +7,13 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
DefaultCodespace sdk.CodespaceType = 6
|
||||
|
||||
// Cool module reserves error 400-499 lawl
|
||||
CodeIncorrectCoolAnswer sdk.CodeType = 400
|
||||
)
|
||||
|
||||
// ErrIncorrectCoolAnswer - Error returned upon an incorrect guess
|
||||
func ErrIncorrectCoolAnswer(answer string) sdk.Error {
|
||||
return sdk.NewError(CodeIncorrectCoolAnswer, fmt.Sprintf("Incorrect cool answer: %v", answer))
|
||||
func ErrIncorrectCoolAnswer(codespace sdk.CodespaceType, answer string) sdk.Error {
|
||||
return sdk.NewError(codespace, CodeIncorrectCoolAnswer, fmt.Sprintf("Incorrect cool answer: %v", answer))
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ func handleQuizMsg(ctx sdk.Context, k Keeper, msg QuizMsg) sdk.Result {
|
|||
correct := k.CheckTrend(ctx, msg.CoolAnswer)
|
||||
|
||||
if !correct {
|
||||
return ErrIncorrectCoolAnswer(msg.CoolAnswer).Result()
|
||||
return ErrIncorrectCoolAnswer(k.codespace, msg.CoolAnswer).Result()
|
||||
}
|
||||
|
||||
if ctx.IsCheckTx() {
|
||||
|
|
|
@ -10,11 +10,13 @@ type Keeper struct {
|
|||
ck bank.CoinKeeper
|
||||
|
||||
storeKey sdk.StoreKey // The (unexposed) key used to access the store from the Context.
|
||||
|
||||
codespace sdk.CodespaceType
|
||||
}
|
||||
|
||||
// NewKeeper - Returns the Keeper
|
||||
func NewKeeper(key sdk.StoreKey, bankKeeper bank.CoinKeeper) Keeper {
|
||||
return Keeper{bankKeeper, key}
|
||||
func NewKeeper(key sdk.StoreKey, bankKeeper bank.CoinKeeper, codespace sdk.CodespaceType) Keeper {
|
||||
return Keeper{bankKeeper, key, codespace}
|
||||
}
|
||||
|
||||
// Key to knowing the trend on the streets!
|
||||
|
|
|
@ -7,6 +7,8 @@ import (
|
|||
type CodeType = sdk.CodeType
|
||||
|
||||
const (
|
||||
DefaultCodespace sdk.CodespaceType = 5
|
||||
|
||||
CodeInvalidDifficulty CodeType = 201
|
||||
CodeNonexistentDifficulty CodeType = 202
|
||||
CodeNonexistentReward CodeType = 203
|
||||
|
@ -40,32 +42,32 @@ func codeToDefaultMsg(code CodeType) string {
|
|||
}
|
||||
}
|
||||
|
||||
func ErrInvalidDifficulty(msg string) sdk.Error {
|
||||
return newError(CodeInvalidDifficulty, msg)
|
||||
func ErrInvalidDifficulty(codespace sdk.CodespaceType, msg string) sdk.Error {
|
||||
return newError(codespace, CodeInvalidDifficulty, msg)
|
||||
}
|
||||
|
||||
func ErrNonexistentDifficulty() sdk.Error {
|
||||
return newError(CodeNonexistentDifficulty, "")
|
||||
func ErrNonexistentDifficulty(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeNonexistentDifficulty, "")
|
||||
}
|
||||
|
||||
func ErrNonexistentReward() sdk.Error {
|
||||
return newError(CodeNonexistentReward, "")
|
||||
func ErrNonexistentReward(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeNonexistentReward, "")
|
||||
}
|
||||
|
||||
func ErrNonexistentCount() sdk.Error {
|
||||
return newError(CodeNonexistentCount, "")
|
||||
func ErrNonexistentCount(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeNonexistentCount, "")
|
||||
}
|
||||
|
||||
func ErrInvalidProof(msg string) sdk.Error {
|
||||
return newError(CodeInvalidProof, msg)
|
||||
func ErrInvalidProof(codespace sdk.CodespaceType, msg string) sdk.Error {
|
||||
return newError(codespace, CodeInvalidProof, msg)
|
||||
}
|
||||
|
||||
func ErrNotBelowTarget(msg string) sdk.Error {
|
||||
return newError(CodeNotBelowTarget, msg)
|
||||
func ErrNotBelowTarget(codespace sdk.CodespaceType, msg string) sdk.Error {
|
||||
return newError(codespace, CodeNotBelowTarget, msg)
|
||||
}
|
||||
|
||||
func ErrInvalidCount(msg string) sdk.Error {
|
||||
return newError(CodeInvalidCount, msg)
|
||||
func ErrInvalidCount(codespace sdk.CodespaceType, msg string) sdk.Error {
|
||||
return newError(codespace, CodeInvalidCount, msg)
|
||||
}
|
||||
|
||||
func msgOrDefaultMsg(msg string, code CodeType) string {
|
||||
|
@ -76,7 +78,7 @@ func msgOrDefaultMsg(msg string, code CodeType) string {
|
|||
}
|
||||
}
|
||||
|
||||
func newError(code CodeType, msg string) sdk.Error {
|
||||
func newError(codespace sdk.CodespaceType, code CodeType, msg string) sdk.Error {
|
||||
msg = msgOrDefaultMsg(msg, code)
|
||||
return sdk.NewError(code, msg)
|
||||
return sdk.NewError(codespace, code, msg)
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ func TestPowHandler(t *testing.T) {
|
|||
ctx := sdk.NewContext(ms, abci.Header{}, false, nil)
|
||||
config := NewPowConfig("pow", int64(1))
|
||||
ck := bank.NewCoinKeeper(am)
|
||||
keeper := NewKeeper(capKey, config, ck)
|
||||
keeper := NewKeeper(capKey, config, ck, DefaultCodespace)
|
||||
|
||||
handler := keeper.Handler
|
||||
|
||||
|
|
|
@ -21,17 +21,18 @@ type PowGenesis struct {
|
|||
}
|
||||
|
||||
type Keeper struct {
|
||||
key sdk.StoreKey
|
||||
config PowConfig
|
||||
ck bank.CoinKeeper
|
||||
key sdk.StoreKey
|
||||
config PowConfig
|
||||
ck bank.CoinKeeper
|
||||
codespace sdk.CodespaceType
|
||||
}
|
||||
|
||||
func NewPowConfig(denomination string, reward int64) PowConfig {
|
||||
return PowConfig{denomination, reward}
|
||||
}
|
||||
|
||||
func NewKeeper(key sdk.StoreKey, config PowConfig, ck bank.CoinKeeper) Keeper {
|
||||
return Keeper{key, config, ck}
|
||||
func NewKeeper(key sdk.StoreKey, config PowConfig, ck bank.CoinKeeper, codespace sdk.CodespaceType) Keeper {
|
||||
return Keeper{key, config, ck, codespace}
|
||||
}
|
||||
|
||||
func (pk Keeper) InitGenesis(ctx sdk.Context, genesis PowGenesis) error {
|
||||
|
@ -78,24 +79,24 @@ func (pk Keeper) CheckValid(ctx sdk.Context, difficulty uint64, count uint64) (u
|
|||
|
||||
lastDifficulty, err := pk.GetLastDifficulty(ctx)
|
||||
if err != nil {
|
||||
return 0, 0, ErrNonexistentDifficulty()
|
||||
return 0, 0, ErrNonexistentDifficulty(pk.codespace)
|
||||
}
|
||||
|
||||
newDifficulty := lastDifficulty + 1
|
||||
|
||||
lastCount, err := pk.GetLastCount(ctx)
|
||||
if err != nil {
|
||||
return 0, 0, ErrNonexistentCount()
|
||||
return 0, 0, ErrNonexistentCount(pk.codespace)
|
||||
}
|
||||
|
||||
newCount := lastCount + 1
|
||||
|
||||
if count != newCount {
|
||||
return 0, 0, ErrInvalidCount(fmt.Sprintf("invalid count: was %d, should have been %d", count, newCount))
|
||||
return 0, 0, ErrInvalidCount(pk.codespace, fmt.Sprintf("invalid count: was %d, should have been %d", count, newCount))
|
||||
}
|
||||
|
||||
if difficulty != newDifficulty {
|
||||
return 0, 0, ErrInvalidDifficulty(fmt.Sprintf("invalid difficulty: was %d, should have been %d", difficulty, newDifficulty))
|
||||
return 0, 0, ErrInvalidDifficulty(pk.codespace, fmt.Sprintf("invalid difficulty: was %d, should have been %d", difficulty, newDifficulty))
|
||||
}
|
||||
|
||||
return newDifficulty, newCount, nil
|
||||
|
|
|
@ -35,7 +35,7 @@ func TestPowKeeperGetSet(t *testing.T) {
|
|||
ctx := sdk.NewContext(ms, abci.Header{}, false, nil)
|
||||
config := NewPowConfig("pow", int64(1))
|
||||
ck := bank.NewCoinKeeper(am)
|
||||
keeper := NewKeeper(capKey, config, ck)
|
||||
keeper := NewKeeper(capKey, config, ck, DefaultCodespace)
|
||||
|
||||
err := keeper.InitGenesis(ctx, PowGenesis{uint64(1), uint64(0)})
|
||||
assert.Nil(t, err)
|
||||
|
|
|
@ -52,7 +52,7 @@ func (msg MineMsg) ValidateBasic() sdk.Error {
|
|||
hex.Encode(hashHex, hash)
|
||||
hashHex = hashHex[:16]
|
||||
if !bytes.Equal(hashHex, msg.Proof) {
|
||||
return ErrInvalidProof(fmt.Sprintf("hashHex: %s, proof: %s", hashHex, msg.Proof))
|
||||
return ErrInvalidProof(DefaultCodespace, fmt.Sprintf("hashHex: %s, proof: %s", hashHex, msg.Proof))
|
||||
}
|
||||
|
||||
// check proof below difficulty
|
||||
|
@ -60,10 +60,10 @@ func (msg MineMsg) ValidateBasic() sdk.Error {
|
|||
target := math.MaxUint64 / msg.Difficulty
|
||||
hashUint, err := strconv.ParseUint(string(msg.Proof), 16, 64)
|
||||
if err != nil {
|
||||
return ErrInvalidProof(fmt.Sprintf("proof: %s", msg.Proof))
|
||||
return ErrInvalidProof(DefaultCodespace, fmt.Sprintf("proof: %s", msg.Proof))
|
||||
}
|
||||
if hashUint >= target {
|
||||
return ErrNotBelowTarget(fmt.Sprintf("hashuint: %d, target: %d", hashUint, target))
|
||||
return ErrNotBelowTarget(DefaultCodespace, fmt.Sprintf("hashuint: %d, target: %d", hashUint, target))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -128,34 +128,34 @@ func TestMultiStoreQuery(t *testing.T) {
|
|||
// Test bad path.
|
||||
query := abci.RequestQuery{Path: "/key", Data: k, Height: ver}
|
||||
qres := multi.Query(query)
|
||||
assert.Equal(t, uint32(sdk.CodeUnknownRequest), qres.Code)
|
||||
assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnknownRequest), sdk.ABCICodeType(qres.Code))
|
||||
|
||||
query.Path = "h897fy32890rf63296r92"
|
||||
qres = multi.Query(query)
|
||||
assert.Equal(t, uint32(sdk.CodeUnknownRequest), qres.Code)
|
||||
assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnknownRequest), sdk.ABCICodeType(qres.Code))
|
||||
|
||||
// Test invalid store name.
|
||||
query.Path = "/garbage/key"
|
||||
qres = multi.Query(query)
|
||||
assert.Equal(t, uint32(sdk.CodeUnknownRequest), qres.Code)
|
||||
assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnknownRequest), sdk.ABCICodeType(qres.Code))
|
||||
|
||||
// Test valid query with data.
|
||||
query.Path = "/store1/key"
|
||||
qres = multi.Query(query)
|
||||
assert.Equal(t, uint32(sdk.CodeOK), qres.Code)
|
||||
assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeOK), sdk.ABCICodeType(qres.Code))
|
||||
assert.Equal(t, v, qres.Value)
|
||||
|
||||
// Test valid but empty query.
|
||||
query.Path = "/store2/key"
|
||||
query.Prove = true
|
||||
qres = multi.Query(query)
|
||||
assert.Equal(t, uint32(sdk.CodeOK), qres.Code)
|
||||
assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeOK), sdk.ABCICodeType(qres.Code))
|
||||
assert.Nil(t, qres.Value)
|
||||
|
||||
// Test store2 data.
|
||||
query.Data = k2
|
||||
qres = multi.Query(query)
|
||||
assert.Equal(t, uint32(sdk.CodeOK), qres.Code)
|
||||
assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeOK), sdk.ABCICodeType(qres.Code))
|
||||
assert.Equal(t, v2, qres.Value)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package types
|
||||
|
||||
// Codespacer is a simple struct to track reserved codespaces
|
||||
type Codespacer struct {
|
||||
reserved map[CodespaceType]bool
|
||||
}
|
||||
|
||||
// NewCodespacer generates a new Codespacer with the starting codespace
|
||||
func NewCodespacer() *Codespacer {
|
||||
return &Codespacer{
|
||||
reserved: make(map[CodespaceType]bool),
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterNext reserves and returns the next available codespace, starting from a default, and panics if the maximum codespace is reached
|
||||
func (c *Codespacer) RegisterNext(codespace CodespaceType) CodespaceType {
|
||||
for {
|
||||
if !c.reserved[codespace] {
|
||||
c.reserved[codespace] = true
|
||||
return codespace
|
||||
}
|
||||
codespace++
|
||||
if codespace == MaximumCodespace {
|
||||
panic("Maximum codespace reached!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterOrPanic reserved a codespace or panics if it is unavailable
|
||||
func (c *Codespacer) RegisterOrPanic(codespace CodespaceType) {
|
||||
if c.reserved[codespace] {
|
||||
panic("Cannot register codespace, already reserved")
|
||||
}
|
||||
c.reserved[codespace] = true
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestRegisterNext(t *testing.T) {
|
||||
codespacer := NewCodespacer()
|
||||
// unregistered, allow
|
||||
code1 := codespacer.RegisterNext(CodespaceType(2))
|
||||
require.Equal(t, code1, CodespaceType(2))
|
||||
// registered, pick next
|
||||
code2 := codespacer.RegisterNext(CodespaceType(2))
|
||||
require.Equal(t, code2, CodespaceType(3))
|
||||
// pick next
|
||||
code3 := codespacer.RegisterNext(CodespaceType(2))
|
||||
require.Equal(t, code3, CodespaceType(4))
|
||||
// skip 1
|
||||
code4 := codespacer.RegisterNext(CodespaceType(6))
|
||||
require.Equal(t, code4, CodespaceType(6))
|
||||
code5 := codespacer.RegisterNext(CodespaceType(2))
|
||||
require.Equal(t, code5, CodespaceType(5))
|
||||
code6 := codespacer.RegisterNext(CodespaceType(2))
|
||||
require.Equal(t, code6, CodespaceType(7))
|
||||
// panic on maximum
|
||||
defer func() {
|
||||
r := recover()
|
||||
require.NotNil(t, r, "Did not panic on maximum codespace")
|
||||
}()
|
||||
codespacer.RegisterNext(MaximumCodespace - 1)
|
||||
codespacer.RegisterNext(MaximumCodespace - 1)
|
||||
}
|
||||
|
||||
func TestRegisterOrPanic(t *testing.T) {
|
||||
codespacer := NewCodespacer()
|
||||
// unregistered, allow
|
||||
code1 := codespacer.RegisterNext(CodespaceType(2))
|
||||
require.Equal(t, code1, CodespaceType(2))
|
||||
// panic on duplicate
|
||||
defer func() {
|
||||
r := recover()
|
||||
require.NotNil(t, r, "Did not panic on duplicate codespace")
|
||||
}()
|
||||
codespacer.RegisterOrPanic(CodespaceType(2))
|
||||
}
|
191
types/errors.go
191
types/errors.go
|
@ -2,25 +2,42 @@ package types
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
)
|
||||
|
||||
// ABCI Response Code
|
||||
type CodeType uint32
|
||||
// ABCICodeType - combined codetype / codespace
|
||||
type ABCICodeType uint32
|
||||
|
||||
// is everything okay?
|
||||
func (code CodeType) IsOK() bool {
|
||||
if code == CodeOK {
|
||||
// CodeType - code identifier within codespace
|
||||
type CodeType uint16
|
||||
|
||||
// CodespaceType - codespace identifier
|
||||
type CodespaceType uint16
|
||||
|
||||
// IsOK - is everything okay?
|
||||
func (code ABCICodeType) IsOK() bool {
|
||||
if code == ABCICodeOK {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ABCI Response Codes
|
||||
// Base SDK reserves 0 - 99.
|
||||
func ToABCICode(space CodespaceType, code CodeType) ABCICodeType {
|
||||
// TODO: Make Tendermint more aware of codespaces.
|
||||
if space == CodespaceRoot && code == CodeOK {
|
||||
return ABCICodeOK
|
||||
}
|
||||
return ABCICodeType((uint32(space) << 16) | uint32(code))
|
||||
}
|
||||
|
||||
const (
|
||||
// ABCI error codes
|
||||
ABCICodeOK ABCICodeType = 0
|
||||
|
||||
// Base error codes
|
||||
CodeOK CodeType = 0
|
||||
CodeInternal CodeType = 1
|
||||
CodeTxDecode CodeType = 2
|
||||
|
@ -34,7 +51,14 @@ const (
|
|||
CodeInsufficientCoins CodeType = 10
|
||||
CodeInvalidCoins CodeType = 11
|
||||
|
||||
CodeGenesisParse CodeType = 0xdead // TODO: remove ? // why remove?
|
||||
// CodespaceRoot is a codespace for error codes in this file only.
|
||||
// Notice that 0 is an "unset" codespace, which can be overridden with
|
||||
// Error.WithDefaultCodespace().
|
||||
CodespaceUndefined CodespaceType = 0
|
||||
CodespaceRoot CodespaceType = 1
|
||||
|
||||
// Maximum reservable codespace (2^16 - 1)
|
||||
MaximumCodespace CodespaceType = 65535
|
||||
)
|
||||
|
||||
// NOTE: Don't stringer this, we'll put better messages in later.
|
||||
|
@ -44,8 +68,6 @@ func CodeToDefaultMsg(code CodeType) string {
|
|||
return "Internal error"
|
||||
case CodeTxDecode:
|
||||
return "Tx parse error"
|
||||
case CodeGenesisParse:
|
||||
return "Genesis parse error"
|
||||
case CodeInvalidSequence:
|
||||
return "Invalid sequence"
|
||||
case CodeUnauthorized:
|
||||
|
@ -75,40 +97,37 @@ func CodeToDefaultMsg(code CodeType) string {
|
|||
|
||||
// nolint
|
||||
func ErrInternal(msg string) Error {
|
||||
return newError(CodeInternal, msg)
|
||||
return newErrorWithRootCodespace(CodeInternal, msg)
|
||||
}
|
||||
func ErrTxDecode(msg string) Error {
|
||||
return newError(CodeTxDecode, msg)
|
||||
}
|
||||
func ErrGenesisParse(msg string) Error {
|
||||
return newError(CodeGenesisParse, msg)
|
||||
return newErrorWithRootCodespace(CodeTxDecode, msg)
|
||||
}
|
||||
func ErrInvalidSequence(msg string) Error {
|
||||
return newError(CodeInvalidSequence, msg)
|
||||
return newErrorWithRootCodespace(CodeInvalidSequence, msg)
|
||||
}
|
||||
func ErrUnauthorized(msg string) Error {
|
||||
return newError(CodeUnauthorized, msg)
|
||||
return newErrorWithRootCodespace(CodeUnauthorized, msg)
|
||||
}
|
||||
func ErrInsufficientFunds(msg string) Error {
|
||||
return newError(CodeInsufficientFunds, msg)
|
||||
return newErrorWithRootCodespace(CodeInsufficientFunds, msg)
|
||||
}
|
||||
func ErrUnknownRequest(msg string) Error {
|
||||
return newError(CodeUnknownRequest, msg)
|
||||
return newErrorWithRootCodespace(CodeUnknownRequest, msg)
|
||||
}
|
||||
func ErrInvalidAddress(msg string) Error {
|
||||
return newError(CodeInvalidAddress, msg)
|
||||
return newErrorWithRootCodespace(CodeInvalidAddress, msg)
|
||||
}
|
||||
func ErrUnknownAddress(msg string) Error {
|
||||
return newError(CodeUnknownAddress, msg)
|
||||
return newErrorWithRootCodespace(CodeUnknownAddress, msg)
|
||||
}
|
||||
func ErrInvalidPubKey(msg string) Error {
|
||||
return newError(CodeInvalidPubKey, msg)
|
||||
return newErrorWithRootCodespace(CodeInvalidPubKey, msg)
|
||||
}
|
||||
func ErrInsufficientCoins(msg string) Error {
|
||||
return newError(CodeInsufficientCoins, msg)
|
||||
return newErrorWithRootCodespace(CodeInsufficientCoins, msg)
|
||||
}
|
||||
func ErrInvalidCoins(msg string) Error {
|
||||
return newError(CodeInvalidCoins, msg)
|
||||
return newErrorWithRootCodespace(CodeInvalidCoins, msg)
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
@ -117,104 +136,98 @@ func ErrInvalidCoins(msg string) Error {
|
|||
// sdk Error type
|
||||
type Error interface {
|
||||
Error() string
|
||||
ABCICode() CodeType
|
||||
Code() CodeType
|
||||
Codespace() CodespaceType
|
||||
ABCILog() string
|
||||
ABCICode() ABCICodeType
|
||||
WithDefaultCodespace(codespace CodespaceType) Error
|
||||
Trace(msg string) Error
|
||||
TraceCause(cause error, msg string) Error
|
||||
Cause() error
|
||||
T() interface{}
|
||||
Result() Result
|
||||
QueryResult() abci.ResponseQuery
|
||||
}
|
||||
|
||||
func NewError(code CodeType, msg string) Error {
|
||||
return newError(code, msg)
|
||||
// NewError - create an error
|
||||
func NewError(codespace CodespaceType, code CodeType, msg string) Error {
|
||||
return newError(codespace, code, msg)
|
||||
}
|
||||
|
||||
type traceItem struct {
|
||||
msg string
|
||||
filename string
|
||||
lineno int
|
||||
func newErrorWithRootCodespace(code CodeType, msg string) *sdkError {
|
||||
return newError(CodespaceRoot, code, msg)
|
||||
}
|
||||
|
||||
func (ti traceItem) String() string {
|
||||
return fmt.Sprintf("%v:%v %v", ti.filename, ti.lineno, ti.msg)
|
||||
}
|
||||
|
||||
type sdkError struct {
|
||||
code CodeType
|
||||
msg string
|
||||
cause error
|
||||
traces []traceItem
|
||||
}
|
||||
|
||||
func newError(code CodeType, msg string) *sdkError {
|
||||
// TODO capture stacktrace if ENV is set.
|
||||
func newError(codespace CodespaceType, code CodeType, msg string) *sdkError {
|
||||
if msg == "" {
|
||||
msg = CodeToDefaultMsg(code)
|
||||
}
|
||||
return &sdkError{
|
||||
code: code,
|
||||
msg: msg,
|
||||
cause: nil,
|
||||
traces: nil,
|
||||
codespace: codespace,
|
||||
code: code,
|
||||
err: cmn.NewErrorWithT(code, msg),
|
||||
}
|
||||
}
|
||||
|
||||
type sdkError struct {
|
||||
codespace CodespaceType
|
||||
code CodeType
|
||||
err cmn.Error
|
||||
}
|
||||
|
||||
// Implements ABCIError.
|
||||
func (err *sdkError) Error() string {
|
||||
return fmt.Sprintf("Error{%d:%s,%v,%v}", err.code, err.msg, err.cause, len(err.traces))
|
||||
return fmt.Sprintf("Error{%d:%d,%#v}", err.codespace, err.code, err.err)
|
||||
}
|
||||
|
||||
// Implements ABCIError.
|
||||
func (err *sdkError) ABCICode() CodeType {
|
||||
func (err *sdkError) ABCICode() ABCICodeType {
|
||||
return ToABCICode(err.codespace, err.code)
|
||||
}
|
||||
|
||||
// Implements Error.
|
||||
func (err *sdkError) Codespace() CodespaceType {
|
||||
return err.codespace
|
||||
}
|
||||
|
||||
// Implements Error.
|
||||
func (err *sdkError) Code() CodeType {
|
||||
return err.code
|
||||
}
|
||||
|
||||
// Implements ABCIError.
|
||||
func (err *sdkError) ABCILog() string {
|
||||
traceLog := ""
|
||||
for _, ti := range err.traces {
|
||||
traceLog += ti.String() + "\n"
|
||||
}
|
||||
return fmt.Sprintf("msg: %v\ntrace:\n%v",
|
||||
err.msg,
|
||||
traceLog,
|
||||
)
|
||||
return fmt.Sprintf(`=== ABCI Log ===
|
||||
Codespace: %v
|
||||
Code: %v
|
||||
ABCICode: %v
|
||||
Error: %#v
|
||||
=== /ABCI Log ===
|
||||
`, err.codespace, err.code, err.ABCICode(), err.err)
|
||||
}
|
||||
|
||||
// Add tracing information with msg.
|
||||
func (err *sdkError) Trace(msg string) Error {
|
||||
return err.doTrace(msg, 2)
|
||||
}
|
||||
|
||||
// Add tracing information with cause and msg.
|
||||
func (err *sdkError) TraceCause(cause error, msg string) Error {
|
||||
err.cause = cause
|
||||
return err.doTrace(msg, 2)
|
||||
}
|
||||
|
||||
func (err *sdkError) doTrace(msg string, n int) Error {
|
||||
_, fn, line, ok := runtime.Caller(n)
|
||||
if !ok {
|
||||
if fn == "" {
|
||||
fn = "<unknown>"
|
||||
}
|
||||
if line <= 0 {
|
||||
line = -1
|
||||
}
|
||||
return &sdkError{
|
||||
codespace: err.codespace,
|
||||
code: err.code,
|
||||
err: err.err.Trace(msg),
|
||||
}
|
||||
// Include file & line number & msg.
|
||||
// Do not include the whole stack trace.
|
||||
err.traces = append(err.traces, traceItem{
|
||||
filename: fn,
|
||||
lineno: line,
|
||||
msg: msg,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (err *sdkError) Cause() error {
|
||||
return err.cause
|
||||
// Implements Error.
|
||||
func (err *sdkError) WithDefaultCodespace(cs CodespaceType) Error {
|
||||
codespace := err.codespace
|
||||
if codespace == CodespaceUndefined {
|
||||
codespace = cs
|
||||
}
|
||||
return &sdkError{
|
||||
codespace: codespace,
|
||||
code: err.code,
|
||||
err: err.err,
|
||||
}
|
||||
}
|
||||
|
||||
func (err *sdkError) T() interface{} {
|
||||
return err.err.T()
|
||||
}
|
||||
|
||||
func (err *sdkError) Result() Result {
|
||||
|
|
|
@ -16,7 +16,6 @@ var codeTypes = []CodeType{
|
|||
CodeUnknownRequest,
|
||||
CodeUnknownAddress,
|
||||
CodeInvalidPubKey,
|
||||
CodeGenesisParse,
|
||||
}
|
||||
|
||||
type errFn func(msg string) Error
|
||||
|
@ -30,14 +29,12 @@ var errFns = []errFn{
|
|||
ErrUnknownRequest,
|
||||
ErrUnknownAddress,
|
||||
ErrInvalidPubKey,
|
||||
ErrGenesisParse,
|
||||
}
|
||||
|
||||
func TestCodeType(t *testing.T) {
|
||||
assert.True(t, CodeOK.IsOK())
|
||||
assert.True(t, ABCICodeOK.IsOK())
|
||||
|
||||
for _, c := range codeTypes {
|
||||
assert.False(t, c.IsOK())
|
||||
msg := CodeToDefaultMsg(c)
|
||||
assert.False(t, strings.HasPrefix(msg, "Unknown code"))
|
||||
}
|
||||
|
@ -47,7 +44,7 @@ func TestErrFn(t *testing.T) {
|
|||
for i, errFn := range errFns {
|
||||
err := errFn("")
|
||||
codeType := codeTypes[i]
|
||||
assert.Equal(t, err.ABCICode(), codeType)
|
||||
assert.Equal(t, err.Result().Code, codeType)
|
||||
assert.Equal(t, err.Code(), codeType)
|
||||
assert.Equal(t, err.Result().Code, ToABCICode(CodespaceRoot, codeType))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,23 +97,23 @@ func NewRatFromDecimal(decimalStr string) (f Rat, err Error) {
|
|||
switch len(str) {
|
||||
case 1:
|
||||
if len(str[0]) == 0 {
|
||||
return f, NewError(CodeUnknownRequest, "not a decimal string")
|
||||
return f, ErrUnknownRequest("not a decimal string")
|
||||
}
|
||||
numStr = str[0]
|
||||
case 2:
|
||||
if len(str[0]) == 0 || len(str[1]) == 0 {
|
||||
return f, NewError(CodeUnknownRequest, "not a decimal string")
|
||||
return f, ErrUnknownRequest("not a decimal string")
|
||||
}
|
||||
numStr = str[0] + str[1]
|
||||
len := int64(len(str[1]))
|
||||
denom = new(big.Int).Exp(big.NewInt(10), big.NewInt(len), nil).Int64()
|
||||
default:
|
||||
return f, NewError(CodeUnknownRequest, "not a decimal string")
|
||||
return f, ErrUnknownRequest("not a decimal string")
|
||||
}
|
||||
|
||||
num, errConv := strconv.Atoi(numStr)
|
||||
if errConv != nil {
|
||||
return f, NewError(CodeUnknownRequest, errConv.Error())
|
||||
return f, ErrUnknownRequest(errConv.Error())
|
||||
}
|
||||
|
||||
if neg {
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
type Result struct {
|
||||
|
||||
// Code is the response code, is stored back on the chain.
|
||||
Code CodeType
|
||||
Code ABCICodeType
|
||||
|
||||
// Data is any data returned from the app.
|
||||
Data []byte
|
||||
|
|
|
@ -40,7 +40,7 @@ func privAndAddr() (crypto.PrivKey, sdk.Address) {
|
|||
func checkValidTx(t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, tx sdk.Tx) {
|
||||
_, result, abort := anteHandler(ctx, tx)
|
||||
assert.False(t, abort)
|
||||
assert.Equal(t, sdk.CodeOK, result.Code)
|
||||
assert.Equal(t, sdk.ABCICodeOK, result.Code)
|
||||
assert.True(t, result.IsOK())
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ func checkValidTx(t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, tx
|
|||
func checkInvalidTx(t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, tx sdk.Tx, code sdk.CodeType) {
|
||||
_, result, abort := anteHandler(ctx, tx)
|
||||
assert.True(t, abort)
|
||||
assert.Equal(t, code, result.Code)
|
||||
assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, code), result.Code)
|
||||
}
|
||||
|
||||
func newTestTx(ctx sdk.Context, msg sdk.Msg, privs []crypto.PrivKey, seqs []int64, fee sdk.StdFee) sdk.Tx {
|
||||
|
|
|
@ -7,6 +7,8 @@ import (
|
|||
|
||||
// Coin errors reserve 100 ~ 199.
|
||||
const (
|
||||
DefaultCodespace sdk.CodespaceType = 2
|
||||
|
||||
CodeInvalidInput sdk.CodeType = 101
|
||||
CodeInvalidOutput sdk.CodeType = 102
|
||||
)
|
||||
|
@ -26,20 +28,20 @@ func codeToDefaultMsg(code sdk.CodeType) string {
|
|||
//----------------------------------------
|
||||
// Error constructors
|
||||
|
||||
func ErrInvalidInput(msg string) sdk.Error {
|
||||
return newError(CodeInvalidInput, msg)
|
||||
func ErrInvalidInput(codespace sdk.CodespaceType, msg string) sdk.Error {
|
||||
return newError(codespace, CodeInvalidInput, msg)
|
||||
}
|
||||
|
||||
func ErrNoInputs() sdk.Error {
|
||||
return newError(CodeInvalidInput, "")
|
||||
func ErrNoInputs(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidInput, "")
|
||||
}
|
||||
|
||||
func ErrInvalidOutput(msg string) sdk.Error {
|
||||
return newError(CodeInvalidOutput, msg)
|
||||
func ErrInvalidOutput(codespace sdk.CodespaceType, msg string) sdk.Error {
|
||||
return newError(codespace, CodeInvalidOutput, msg)
|
||||
}
|
||||
|
||||
func ErrNoOutputs() sdk.Error {
|
||||
return newError(CodeInvalidOutput, "")
|
||||
func ErrNoOutputs(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidOutput, "")
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
@ -51,7 +53,7 @@ func msgOrDefaultMsg(msg string, code sdk.CodeType) string {
|
|||
return codeToDefaultMsg(code)
|
||||
}
|
||||
|
||||
func newError(code sdk.CodeType, msg string) sdk.Error {
|
||||
func newError(codespace sdk.CodespaceType, code sdk.CodeType, msg string) sdk.Error {
|
||||
msg = msgOrDefaultMsg(msg, code)
|
||||
return sdk.NewError(code, msg)
|
||||
return sdk.NewError(codespace, code, msg)
|
||||
}
|
||||
|
|
|
@ -28,10 +28,10 @@ func (msg SendMsg) ValidateBasic() sdk.Error {
|
|||
// this just makes sure all the inputs and outputs are properly formatted,
|
||||
// not that they actually have the money inside
|
||||
if len(msg.Inputs) == 0 {
|
||||
return ErrNoInputs().Trace("")
|
||||
return ErrNoInputs(DefaultCodespace).Trace("")
|
||||
}
|
||||
if len(msg.Outputs) == 0 {
|
||||
return ErrNoOutputs().Trace("")
|
||||
return ErrNoOutputs(DefaultCodespace).Trace("")
|
||||
}
|
||||
// make sure all inputs and outputs are individually valid
|
||||
var totalIn, totalOut sdk.Coins
|
||||
|
@ -102,7 +102,7 @@ func (msg IssueMsg) Type() string { return "bank" } // TODO: "bank/issue"
|
|||
func (msg IssueMsg) ValidateBasic() sdk.Error {
|
||||
// XXX
|
||||
if len(msg.Outputs) == 0 {
|
||||
return ErrNoOutputs().Trace("")
|
||||
return ErrNoOutputs(DefaultCodespace).Trace("")
|
||||
}
|
||||
for _, out := range msg.Outputs {
|
||||
if err := out.ValidateBasic(); err != nil {
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
DefaultCodespace sdk.CodespaceType = 3
|
||||
|
||||
// IBC errors reserve 200 - 299.
|
||||
CodeInvalidSequence sdk.CodeType = 200
|
||||
CodeIdenticalChains sdk.CodeType = 201
|
||||
|
@ -22,20 +24,20 @@ func codeToDefaultMsg(code sdk.CodeType) string {
|
|||
}
|
||||
}
|
||||
|
||||
func ErrInvalidSequence() sdk.Error {
|
||||
return newError(CodeInvalidSequence, "")
|
||||
func ErrInvalidSequence(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidSequence, "")
|
||||
}
|
||||
|
||||
func ErrIdenticalChains() sdk.Error {
|
||||
return newError(CodeIdenticalChains, "")
|
||||
func ErrIdenticalChains(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeIdenticalChains, "")
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
// Helpers
|
||||
|
||||
func newError(code sdk.CodeType, msg string) sdk.Error {
|
||||
func newError(codespace sdk.CodespaceType, code sdk.CodeType, msg string) sdk.Error {
|
||||
msg = msgOrDefaultMsg(msg, code)
|
||||
return sdk.NewError(code, msg)
|
||||
return sdk.NewError(codespace, code, msg)
|
||||
}
|
||||
|
||||
func msgOrDefaultMsg(msg string, code sdk.CodeType) string {
|
||||
|
|
|
@ -44,7 +44,7 @@ func handleIBCReceiveMsg(ctx sdk.Context, ibcm IBCMapper, ck bank.CoinKeeper, ms
|
|||
|
||||
seq := ibcm.GetIngressSequence(ctx, packet.SrcChain)
|
||||
if msg.Sequence != seq {
|
||||
return ErrInvalidSequence().Result()
|
||||
return ErrInvalidSequence(ibcm.codespace).Result()
|
||||
}
|
||||
|
||||
_, err := ck.AddCoins(ctx, packet.DestAddr, packet.Coins)
|
||||
|
|
|
@ -73,7 +73,7 @@ func TestIBC(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
assert.Equal(t, mycoins, coins)
|
||||
|
||||
ibcm := NewIBCMapper(cdc, key)
|
||||
ibcm := NewIBCMapper(cdc, key, DefaultCodespace)
|
||||
h := NewHandler(ibcm, ck)
|
||||
packet := IBCPacket{
|
||||
SrcAddr: src,
|
||||
|
|
|
@ -8,17 +8,19 @@ import (
|
|||
)
|
||||
|
||||
type IBCMapper struct {
|
||||
key sdk.StoreKey
|
||||
cdc *wire.Codec
|
||||
key sdk.StoreKey
|
||||
cdc *wire.Codec
|
||||
codespace sdk.CodespaceType
|
||||
}
|
||||
|
||||
// XXX: The IBCMapper should not take a CoinKeeper. Rather have the CoinKeeper
|
||||
// take an IBCMapper.
|
||||
func NewIBCMapper(cdc *wire.Codec, key sdk.StoreKey) IBCMapper {
|
||||
func NewIBCMapper(cdc *wire.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) IBCMapper {
|
||||
// XXX: How are these codecs supposed to work?
|
||||
return IBCMapper{
|
||||
key: key,
|
||||
cdc: cdc,
|
||||
key: key,
|
||||
cdc: cdc,
|
||||
codespace: codespace,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ func NewIBCPacket(srcAddr sdk.Address, destAddr sdk.Address, coins sdk.Coins,
|
|||
|
||||
func (ibcp IBCPacket) ValidateBasic() sdk.Error {
|
||||
if ibcp.SrcChain == ibcp.DestChain {
|
||||
return ErrIdenticalChains().Trace("")
|
||||
return ErrIdenticalChains(DefaultCodespace).Trace("")
|
||||
}
|
||||
if !ibcp.Coins.IsValid() {
|
||||
return sdk.ErrInvalidCoins("")
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
DefaultCodespace sdk.CodespaceType = 4
|
||||
|
||||
// simplestake errors reserve 300 - 399.
|
||||
CodeEmptyValidator sdk.CodeType = 300
|
||||
CodeInvalidUnbond sdk.CodeType = 301
|
||||
|
@ -12,25 +14,25 @@ const (
|
|||
CodeIncorrectStakingToken sdk.CodeType = 303
|
||||
)
|
||||
|
||||
func ErrIncorrectStakingToken() sdk.Error {
|
||||
return newError(CodeIncorrectStakingToken, "")
|
||||
func ErrIncorrectStakingToken(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeIncorrectStakingToken, "")
|
||||
}
|
||||
|
||||
func ErrEmptyValidator() sdk.Error {
|
||||
return newError(CodeEmptyValidator, "")
|
||||
func ErrEmptyValidator(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeEmptyValidator, "")
|
||||
}
|
||||
|
||||
func ErrInvalidUnbond() sdk.Error {
|
||||
return newError(CodeInvalidUnbond, "")
|
||||
func ErrInvalidUnbond(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidUnbond, "")
|
||||
}
|
||||
|
||||
func ErrEmptyStake() sdk.Error {
|
||||
return newError(CodeEmptyStake, "")
|
||||
func ErrEmptyStake(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeEmptyStake, "")
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
// Helpers
|
||||
|
||||
func newError(code sdk.CodeType, msg string) sdk.Error {
|
||||
return sdk.NewError(code, msg)
|
||||
func newError(codespace sdk.CodespaceType, code sdk.CodeType, msg string) sdk.Error {
|
||||
return sdk.NewError(codespace, code, msg)
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ func handleBondMsg(ctx sdk.Context, k Keeper, msg BondMsg) sdk.Result {
|
|||
}
|
||||
|
||||
return sdk.Result{
|
||||
Code: sdk.CodeOK,
|
||||
Code: sdk.ABCICodeOK,
|
||||
ValidatorUpdates: abci.Validators{valSet},
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ func handleUnbondMsg(ctx sdk.Context, k Keeper, msg UnbondMsg) sdk.Result {
|
|||
}
|
||||
|
||||
return sdk.Result{
|
||||
Code: sdk.CodeOK,
|
||||
Code: sdk.ABCICodeOK,
|
||||
ValidatorUpdates: abci.Validators{valSet},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,17 +15,19 @@ const moduleName = "simplestake"
|
|||
type Keeper struct {
|
||||
ck bank.CoinKeeper
|
||||
|
||||
key sdk.StoreKey
|
||||
cdc *wire.Codec
|
||||
key sdk.StoreKey
|
||||
cdc *wire.Codec
|
||||
codespace sdk.CodespaceType
|
||||
}
|
||||
|
||||
func NewKeeper(key sdk.StoreKey, coinKeeper bank.CoinKeeper) Keeper {
|
||||
func NewKeeper(key sdk.StoreKey, coinKeeper bank.CoinKeeper, codespace sdk.CodespaceType) Keeper {
|
||||
cdc := wire.NewCodec()
|
||||
wire.RegisterCrypto(cdc)
|
||||
return Keeper{
|
||||
key: key,
|
||||
cdc: cdc,
|
||||
ck: coinKeeper,
|
||||
key: key,
|
||||
cdc: cdc,
|
||||
ck: coinKeeper,
|
||||
codespace: codespace,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +61,7 @@ func (k Keeper) deleteBondInfo(ctx sdk.Context, addr sdk.Address) {
|
|||
|
||||
func (k Keeper) Bond(ctx sdk.Context, addr sdk.Address, pubKey crypto.PubKey, stake sdk.Coin) (int64, sdk.Error) {
|
||||
if stake.Denom != stakingToken {
|
||||
return 0, ErrIncorrectStakingToken()
|
||||
return 0, ErrIncorrectStakingToken(k.codespace)
|
||||
}
|
||||
|
||||
_, err := k.ck.SubtractCoins(ctx, addr, []sdk.Coin{stake})
|
||||
|
@ -84,7 +86,7 @@ func (k Keeper) Bond(ctx sdk.Context, addr sdk.Address, pubKey crypto.PubKey, st
|
|||
func (k Keeper) Unbond(ctx sdk.Context, addr sdk.Address) (crypto.PubKey, int64, sdk.Error) {
|
||||
bi := k.getBondInfo(ctx, addr)
|
||||
if bi.isEmpty() {
|
||||
return nil, 0, ErrInvalidUnbond()
|
||||
return nil, 0, ErrInvalidUnbond(k.codespace)
|
||||
}
|
||||
k.deleteBondInfo(ctx, addr)
|
||||
|
||||
|
@ -102,7 +104,7 @@ func (k Keeper) Unbond(ctx sdk.Context, addr sdk.Address) (crypto.PubKey, int64,
|
|||
|
||||
func (k Keeper) bondWithoutCoins(ctx sdk.Context, addr sdk.Address, pubKey crypto.PubKey, stake sdk.Coin) (int64, sdk.Error) {
|
||||
if stake.Denom != stakingToken {
|
||||
return 0, ErrIncorrectStakingToken()
|
||||
return 0, ErrIncorrectStakingToken(k.codespace)
|
||||
}
|
||||
|
||||
bi := k.getBondInfo(ctx, addr)
|
||||
|
@ -122,7 +124,7 @@ func (k Keeper) bondWithoutCoins(ctx sdk.Context, addr sdk.Address, pubKey crypt
|
|||
func (k Keeper) unbondWithoutCoins(ctx sdk.Context, addr sdk.Address) (crypto.PubKey, int64, sdk.Error) {
|
||||
bi := k.getBondInfo(ctx, addr)
|
||||
if bi.isEmpty() {
|
||||
return nil, 0, ErrInvalidUnbond()
|
||||
return nil, 0, ErrInvalidUnbond(k.codespace)
|
||||
}
|
||||
k.deleteBondInfo(ctx, addr)
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ func TestKeeperGetSet(t *testing.T) {
|
|||
ms, _, capKey := setupMultiStore()
|
||||
|
||||
ctx := sdk.NewContext(ms, abci.Header{}, false, nil)
|
||||
stakeKeeper := NewKeeper(capKey, bank.NewCoinKeeper(nil))
|
||||
stakeKeeper := NewKeeper(capKey, bank.NewCoinKeeper(nil), DefaultCodespace)
|
||||
addr := sdk.Address([]byte("some-address"))
|
||||
|
||||
bi := stakeKeeper.getBondInfo(ctx, addr)
|
||||
|
@ -63,13 +63,13 @@ func TestBonding(t *testing.T) {
|
|||
|
||||
accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{})
|
||||
coinKeeper := bank.NewCoinKeeper(accountMapper)
|
||||
stakeKeeper := NewKeeper(capKey, coinKeeper)
|
||||
stakeKeeper := NewKeeper(capKey, coinKeeper, DefaultCodespace)
|
||||
addr := sdk.Address([]byte("some-address"))
|
||||
privKey := crypto.GenPrivKeyEd25519()
|
||||
pubKey := privKey.PubKey()
|
||||
|
||||
_, _, err := stakeKeeper.unbondWithoutCoins(ctx, addr)
|
||||
assert.Equal(t, err, ErrInvalidUnbond())
|
||||
assert.Equal(t, err, ErrInvalidUnbond(DefaultCodespace))
|
||||
|
||||
_, err = stakeKeeper.bondWithoutCoins(ctx, addr, pubKey, sdk.Coin{"steak", 10})
|
||||
assert.Nil(t, err)
|
||||
|
@ -82,5 +82,5 @@ func TestBonding(t *testing.T) {
|
|||
assert.Equal(t, pubKey, pk)
|
||||
|
||||
_, _, err = stakeKeeper.unbondWithoutCoins(ctx, addr)
|
||||
assert.Equal(t, err, ErrInvalidUnbond())
|
||||
assert.Equal(t, err, ErrInvalidUnbond(DefaultCodespace))
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ func (msg BondMsg) Type() string {
|
|||
|
||||
func (msg BondMsg) ValidateBasic() sdk.Error {
|
||||
if msg.Stake.IsZero() {
|
||||
return ErrEmptyStake()
|
||||
return ErrEmptyStake(DefaultCodespace)
|
||||
}
|
||||
|
||||
if msg.PubKey == nil {
|
||||
|
|
|
@ -10,6 +10,8 @@ import (
|
|||
type CodeType = sdk.CodeType
|
||||
|
||||
const (
|
||||
DefaultCodespace sdk.CodespaceType = 4
|
||||
|
||||
// Gaia errors reserve 200 ~ 299.
|
||||
CodeInvalidValidator CodeType = 201
|
||||
CodeInvalidCandidate CodeType = 202
|
||||
|
@ -45,62 +47,62 @@ func codeToDefaultMsg(code CodeType) string {
|
|||
//----------------------------------------
|
||||
// Error constructors
|
||||
|
||||
func ErrNotEnoughBondShares(shares string) sdk.Error {
|
||||
return newError(CodeInvalidBond, fmt.Sprintf("not enough shares only have %v", shares))
|
||||
func ErrNotEnoughBondShares(codespace sdk.CodespaceType, shares string) sdk.Error {
|
||||
return newError(codespace, CodeInvalidBond, fmt.Sprintf("not enough shares only have %v", shares))
|
||||
}
|
||||
func ErrCandidateEmpty() sdk.Error {
|
||||
return newError(CodeInvalidValidator, "Cannot bond to an empty candidate")
|
||||
func ErrCandidateEmpty(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Cannot bond to an empty candidate")
|
||||
}
|
||||
func ErrBadBondingDenom() sdk.Error {
|
||||
return newError(CodeInvalidBond, "Invalid coin denomination")
|
||||
func ErrBadBondingDenom(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidBond, "Invalid coin denomination")
|
||||
}
|
||||
func ErrBadBondingAmount() sdk.Error {
|
||||
return newError(CodeInvalidBond, "Amount must be > 0")
|
||||
func ErrBadBondingAmount(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidBond, "Amount must be > 0")
|
||||
}
|
||||
func ErrNoBondingAcct() sdk.Error {
|
||||
return newError(CodeInvalidValidator, "No bond account for this (address, validator) pair")
|
||||
func ErrNoBondingAcct(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "No bond account for this (address, validator) pair")
|
||||
}
|
||||
func ErrCommissionNegative() sdk.Error {
|
||||
return newError(CodeInvalidValidator, "Commission must be positive")
|
||||
func ErrCommissionNegative(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Commission must be positive")
|
||||
}
|
||||
func ErrCommissionHuge() sdk.Error {
|
||||
return newError(CodeInvalidValidator, "Commission cannot be more than 100%")
|
||||
func ErrCommissionHuge(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Commission cannot be more than 100%")
|
||||
}
|
||||
func ErrBadValidatorAddr() sdk.Error {
|
||||
return newError(CodeInvalidValidator, "Validator does not exist for that address")
|
||||
func ErrBadValidatorAddr(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Validator does not exist for that address")
|
||||
}
|
||||
func ErrBadCandidateAddr() sdk.Error {
|
||||
return newError(CodeInvalidValidator, "Candidate does not exist for that address")
|
||||
func ErrBadCandidateAddr(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Candidate does not exist for that address")
|
||||
}
|
||||
func ErrBadDelegatorAddr() sdk.Error {
|
||||
return newError(CodeInvalidValidator, "Delegator does not exist for that address")
|
||||
func ErrBadDelegatorAddr(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Delegator does not exist for that address")
|
||||
}
|
||||
func ErrCandidateExistsAddr() sdk.Error {
|
||||
return newError(CodeInvalidValidator, "Candidate already exist, cannot re-declare candidacy")
|
||||
func ErrCandidateExistsAddr(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Candidate already exist, cannot re-declare candidacy")
|
||||
}
|
||||
func ErrCandidateRevoked() sdk.Error {
|
||||
return newError(CodeInvalidValidator, "Candidacy for this address is currently revoked")
|
||||
func ErrCandidateRevoked(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Candidacy for this address is currently revoked")
|
||||
}
|
||||
func ErrMissingSignature() sdk.Error {
|
||||
return newError(CodeInvalidValidator, "Missing signature")
|
||||
func ErrMissingSignature(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Missing signature")
|
||||
}
|
||||
func ErrBondNotNominated() sdk.Error {
|
||||
return newError(CodeInvalidValidator, "Cannot bond to non-nominated account")
|
||||
func ErrBondNotNominated(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Cannot bond to non-nominated account")
|
||||
}
|
||||
func ErrNoCandidateForAddress() sdk.Error {
|
||||
return newError(CodeInvalidValidator, "Validator does not exist for that address")
|
||||
func ErrNoCandidateForAddress(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Validator does not exist for that address")
|
||||
}
|
||||
func ErrNoDelegatorForAddress() sdk.Error {
|
||||
return newError(CodeInvalidValidator, "Delegator does not contain validator bond")
|
||||
func ErrNoDelegatorForAddress(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Delegator does not contain validator bond")
|
||||
}
|
||||
func ErrInsufficientFunds() sdk.Error {
|
||||
return newError(CodeInvalidInput, "Insufficient bond shares")
|
||||
func ErrInsufficientFunds(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidInput, "Insufficient bond shares")
|
||||
}
|
||||
func ErrBadShares() sdk.Error {
|
||||
return newError(CodeInvalidInput, "bad shares provided as input, must be MAX or decimal")
|
||||
func ErrBadShares(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidInput, "bad shares provided as input, must be MAX or decimal")
|
||||
}
|
||||
func ErrBadRemoveValidator() sdk.Error {
|
||||
return newError(CodeInvalidValidator, "Error removing validator")
|
||||
func ErrBadRemoveValidator(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Error removing validator")
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
@ -114,7 +116,7 @@ func msgOrDefaultMsg(msg string, code CodeType) string {
|
|||
return codeToDefaultMsg(code)
|
||||
}
|
||||
|
||||
func newError(code CodeType, msg string) sdk.Error {
|
||||
func newError(codespace sdk.CodespaceType, code CodeType, msg string) sdk.Error {
|
||||
msg = msgOrDefaultMsg(msg, code)
|
||||
return sdk.NewError(code, msg)
|
||||
return sdk.NewError(codespace, code, msg)
|
||||
}
|
||||
|
|
|
@ -57,10 +57,10 @@ func handleMsgDeclareCandidacy(ctx sdk.Context, msg MsgDeclareCandidacy, k Keepe
|
|||
// check to see if the pubkey or sender has been registered before
|
||||
_, found := k.GetCandidate(ctx, msg.CandidateAddr)
|
||||
if found {
|
||||
return ErrCandidateExistsAddr().Result()
|
||||
return ErrCandidateExistsAddr(k.codespace).Result()
|
||||
}
|
||||
if msg.Bond.Denom != k.GetParams(ctx).BondDenom {
|
||||
return ErrBadBondingDenom().Result()
|
||||
return ErrBadBondingDenom(k.codespace).Result()
|
||||
}
|
||||
if ctx.IsCheckTx() {
|
||||
return sdk.Result{
|
||||
|
@ -85,7 +85,7 @@ func handleMsgEditCandidacy(ctx sdk.Context, msg MsgEditCandidacy, k Keeper) sdk
|
|||
// candidate must already be registered
|
||||
candidate, found := k.GetCandidate(ctx, msg.CandidateAddr)
|
||||
if !found {
|
||||
return ErrBadCandidateAddr().Result()
|
||||
return ErrBadCandidateAddr(k.codespace).Result()
|
||||
}
|
||||
if ctx.IsCheckTx() {
|
||||
return sdk.Result{
|
||||
|
@ -93,7 +93,7 @@ func handleMsgEditCandidacy(ctx sdk.Context, msg MsgEditCandidacy, k Keeper) sdk
|
|||
}
|
||||
}
|
||||
if candidate.Status == Unbonded { //candidate has been withdrawn
|
||||
return ErrBondNotNominated().Result()
|
||||
return ErrBondNotNominated(k.codespace).Result()
|
||||
}
|
||||
|
||||
// XXX move to types
|
||||
|
@ -111,13 +111,13 @@ func handleMsgDelegate(ctx sdk.Context, msg MsgDelegate, k Keeper) sdk.Result {
|
|||
|
||||
candidate, found := k.GetCandidate(ctx, msg.CandidateAddr)
|
||||
if !found {
|
||||
return ErrBadCandidateAddr().Result()
|
||||
return ErrBadCandidateAddr(k.codespace).Result()
|
||||
}
|
||||
if msg.Bond.Denom != k.GetParams(ctx).BondDenom {
|
||||
return ErrBadBondingDenom().Result()
|
||||
return ErrBadBondingDenom(k.codespace).Result()
|
||||
}
|
||||
if candidate.Status == Revoked {
|
||||
return ErrCandidateRevoked().Result()
|
||||
return ErrCandidateRevoked(k.codespace).Result()
|
||||
}
|
||||
if ctx.IsCheckTx() {
|
||||
return sdk.Result{
|
||||
|
@ -165,10 +165,10 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result {
|
|||
// check if bond has any shares in it unbond
|
||||
bond, found := k.getDelegatorBond(ctx, msg.DelegatorAddr, msg.CandidateAddr)
|
||||
if !found {
|
||||
return ErrNoDelegatorForAddress().Result()
|
||||
return ErrNoDelegatorForAddress(k.codespace).Result()
|
||||
}
|
||||
if !bond.Shares.GT(sdk.ZeroRat) { // bond shares < msg shares
|
||||
return ErrInsufficientFunds().Result()
|
||||
return ErrInsufficientFunds(k.codespace).Result()
|
||||
}
|
||||
|
||||
// test getting rational number from decimal provided
|
||||
|
@ -180,18 +180,18 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result {
|
|||
// test that there are enough shares to unbond
|
||||
if msg.Shares == "MAX" {
|
||||
if !bond.Shares.GT(sdk.ZeroRat) {
|
||||
return ErrNotEnoughBondShares(msg.Shares).Result()
|
||||
return ErrNotEnoughBondShares(k.codespace, msg.Shares).Result()
|
||||
}
|
||||
} else {
|
||||
if bond.Shares.LT(shares) {
|
||||
return ErrNotEnoughBondShares(msg.Shares).Result()
|
||||
return ErrNotEnoughBondShares(k.codespace, msg.Shares).Result()
|
||||
}
|
||||
}
|
||||
|
||||
// get candidate
|
||||
candidate, found := k.GetCandidate(ctx, msg.CandidateAddr)
|
||||
if !found {
|
||||
return ErrNoCandidateForAddress().Result()
|
||||
return ErrNoCandidateForAddress(k.codespace).Result()
|
||||
}
|
||||
|
||||
if ctx.IsCheckTx() {
|
||||
|
|
|
@ -19,13 +19,17 @@ type Keeper struct {
|
|||
// caches
|
||||
gs Pool
|
||||
params Params
|
||||
|
||||
// codespace
|
||||
codespace sdk.CodespaceType
|
||||
}
|
||||
|
||||
func NewKeeper(ctx sdk.Context, cdc *wire.Codec, key sdk.StoreKey, ck bank.CoinKeeper) Keeper {
|
||||
func NewKeeper(ctx sdk.Context, cdc *wire.Codec, key sdk.StoreKey, ck bank.CoinKeeper, codespace sdk.CodespaceType) Keeper {
|
||||
keeper := Keeper{
|
||||
storeKey: key,
|
||||
cdc: cdc,
|
||||
coinKeeper: ck,
|
||||
codespace: codespace,
|
||||
}
|
||||
return keeper
|
||||
}
|
||||
|
|
|
@ -60,18 +60,18 @@ func (msg MsgDeclareCandidacy) GetSignBytes() []byte {
|
|||
// quick validity check
|
||||
func (msg MsgDeclareCandidacy) ValidateBasic() sdk.Error {
|
||||
if msg.CandidateAddr == nil {
|
||||
return ErrCandidateEmpty()
|
||||
return ErrCandidateEmpty(DefaultCodespace)
|
||||
}
|
||||
if msg.Bond.Denom != StakingToken {
|
||||
return ErrBadBondingDenom()
|
||||
return ErrBadBondingDenom(DefaultCodespace)
|
||||
}
|
||||
if msg.Bond.Amount <= 0 {
|
||||
return ErrBadBondingAmount()
|
||||
return ErrBadBondingAmount(DefaultCodespace)
|
||||
// return sdk.ErrInvalidCoins(sdk.Coins{msg.Bond}.String())
|
||||
}
|
||||
empty := Description{}
|
||||
if msg.Description == empty {
|
||||
return newError(CodeInvalidInput, "description must be included")
|
||||
return newError(DefaultCodespace, CodeInvalidInput, "description must be included")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -111,11 +111,11 @@ func (msg MsgEditCandidacy) GetSignBytes() []byte {
|
|||
// quick validity check
|
||||
func (msg MsgEditCandidacy) ValidateBasic() sdk.Error {
|
||||
if msg.CandidateAddr == nil {
|
||||
return ErrCandidateEmpty()
|
||||
return ErrCandidateEmpty(DefaultCodespace)
|
||||
}
|
||||
empty := Description{}
|
||||
if msg.Description == empty {
|
||||
return newError(CodeInvalidInput, "Transaction must include some information to modify")
|
||||
return newError(DefaultCodespace, CodeInvalidInput, "Transaction must include some information to modify")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -157,16 +157,16 @@ func (msg MsgDelegate) GetSignBytes() []byte {
|
|||
// quick validity check
|
||||
func (msg MsgDelegate) ValidateBasic() sdk.Error {
|
||||
if msg.DelegatorAddr == nil {
|
||||
return ErrBadDelegatorAddr()
|
||||
return ErrBadDelegatorAddr(DefaultCodespace)
|
||||
}
|
||||
if msg.CandidateAddr == nil {
|
||||
return ErrBadCandidateAddr()
|
||||
return ErrBadCandidateAddr(DefaultCodespace)
|
||||
}
|
||||
if msg.Bond.Denom != StakingToken {
|
||||
return ErrBadBondingDenom()
|
||||
return ErrBadBondingDenom(DefaultCodespace)
|
||||
}
|
||||
if msg.Bond.Amount <= 0 {
|
||||
return ErrBadBondingAmount()
|
||||
return ErrBadBondingAmount(DefaultCodespace)
|
||||
// return sdk.ErrInvalidCoins(sdk.Coins{msg.Bond}.String())
|
||||
}
|
||||
return nil
|
||||
|
@ -209,18 +209,18 @@ func (msg MsgUnbond) GetSignBytes() []byte {
|
|||
// quick validity check
|
||||
func (msg MsgUnbond) ValidateBasic() sdk.Error {
|
||||
if msg.DelegatorAddr == nil {
|
||||
return ErrBadDelegatorAddr()
|
||||
return ErrBadDelegatorAddr(DefaultCodespace)
|
||||
}
|
||||
if msg.CandidateAddr == nil {
|
||||
return ErrBadCandidateAddr()
|
||||
return ErrBadCandidateAddr(DefaultCodespace)
|
||||
}
|
||||
if msg.Shares != "MAX" {
|
||||
rat, err := sdk.NewRatFromDecimal(msg.Shares)
|
||||
if err != nil {
|
||||
return ErrBadShares()
|
||||
return ErrBadShares(DefaultCodespace)
|
||||
}
|
||||
if rat.IsZero() || rat.LT(sdk.ZeroRat) {
|
||||
return ErrBadShares()
|
||||
return ErrBadShares(DefaultCodespace)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -132,7 +132,7 @@ func createTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context
|
|||
&auth.BaseAccount{}, // prototype
|
||||
).Seal()
|
||||
ck := bank.NewCoinKeeper(accountMapper)
|
||||
keeper := NewKeeper(ctx, cdc, keyStake, ck)
|
||||
keeper := NewKeeper(ctx, cdc, keyStake, ck, DefaultCodespace)
|
||||
keeper.setPool(ctx, initialPool())
|
||||
keeper.setParams(ctx, defaultParams())
|
||||
|
||||
|
|
Loading…
Reference in New Issue