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:
Christopher Goes
2018-04-17 19:16:21 -07:00
committed by Jae Kwon
parent ffd428d199
commit f8e44b5b00
41 changed files with 438 additions and 305 deletions
+3 -3
View File
@@ -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
}
+6 -6
View File
@@ -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()
+5 -5
View File
@@ -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
}
+9 -9
View File
@@ -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()
+4 -2
View File
@@ -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))
}
+1 -1
View File
@@ -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() {
+4 -2
View File
@@ -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!
+18 -16
View File
@@ -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)
}
+1 -1
View File
@@ -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
+10 -9
View File
@@ -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
+1 -1
View File
@@ -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)
+3 -3
View File
@@ -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