Merge pull request #1812: Add BaseApp.Seal
* Merge pull request #1812: Add BaseApp.Seal fix pow move setter functions apply requests * fix errors * fix test * fix test * changelog
This commit is contained in:
parent
179b8f9c49
commit
7b54e4b786
|
@ -42,6 +42,7 @@ FEATURES
|
||||||
* [store] Add transient store
|
* [store] Add transient store
|
||||||
* [gov] Add slashing for validators who do not vote on a proposal
|
* [gov] Add slashing for validators who do not vote on a proposal
|
||||||
* [cli] added `gov query-proposals` command to CLI. Can filter by `depositer`, `voter`, and `status`
|
* [cli] added `gov query-proposals` command to CLI. Can filter by `depositer`, `voter`, and `status`
|
||||||
|
* [core] added BaseApp.Seal - ability to seal baseapp parameters once they've been set
|
||||||
|
|
||||||
IMPROVEMENTS
|
IMPROVEMENTS
|
||||||
* [baseapp] Allow any alphanumeric character in route
|
* [baseapp] Allow any alphanumeric character in route
|
||||||
|
|
|
@ -66,6 +66,9 @@ type BaseApp struct {
|
||||||
checkState *state // for CheckTx
|
checkState *state // for CheckTx
|
||||||
deliverState *state // for DeliverTx
|
deliverState *state // for DeliverTx
|
||||||
signedValidators []abci.SigningValidator // absent validators from begin block
|
signedValidators []abci.SigningValidator // absent validators from begin block
|
||||||
|
|
||||||
|
// flag for sealing
|
||||||
|
sealed bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ abci.Application = (*BaseApp)(nil)
|
var _ abci.Application = (*BaseApp)(nil)
|
||||||
|
@ -132,27 +135,6 @@ func (app *BaseApp) MountStore(key sdk.StoreKey, typ sdk.StoreType) {
|
||||||
app.cms.MountStoreWithDB(key, typ, nil)
|
app.cms.MountStoreWithDB(key, typ, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint - Set functions
|
|
||||||
func (app *BaseApp) SetInitChainer(initChainer sdk.InitChainer) {
|
|
||||||
app.initChainer = initChainer
|
|
||||||
}
|
|
||||||
func (app *BaseApp) SetBeginBlocker(beginBlocker sdk.BeginBlocker) {
|
|
||||||
app.beginBlocker = beginBlocker
|
|
||||||
}
|
|
||||||
func (app *BaseApp) SetEndBlocker(endBlocker sdk.EndBlocker) {
|
|
||||||
app.endBlocker = endBlocker
|
|
||||||
}
|
|
||||||
func (app *BaseApp) SetAnteHandler(ah sdk.AnteHandler) {
|
|
||||||
app.anteHandler = ah
|
|
||||||
}
|
|
||||||
func (app *BaseApp) SetAddrPeerFilter(pf sdk.PeerFilter) {
|
|
||||||
app.addrPeerFilter = pf
|
|
||||||
}
|
|
||||||
func (app *BaseApp) SetPubKeyPeerFilter(pf sdk.PeerFilter) {
|
|
||||||
app.pubkeyPeerFilter = pf
|
|
||||||
}
|
|
||||||
func (app *BaseApp) Router() Router { return app.router }
|
|
||||||
|
|
||||||
// load latest application version
|
// load latest application version
|
||||||
func (app *BaseApp) LoadLatestVersion(mainKey sdk.StoreKey) error {
|
func (app *BaseApp) LoadLatestVersion(mainKey sdk.StoreKey) error {
|
||||||
err := app.cms.LoadLatestVersion()
|
err := app.cms.LoadLatestVersion()
|
||||||
|
@ -183,7 +165,6 @@ func (app *BaseApp) LastBlockHeight() int64 {
|
||||||
|
|
||||||
// initializes the remaining logic from app.cms
|
// initializes the remaining logic from app.cms
|
||||||
func (app *BaseApp) initFromStore(mainKey sdk.StoreKey) error {
|
func (app *BaseApp) initFromStore(mainKey sdk.StoreKey) error {
|
||||||
|
|
||||||
// main store should exist.
|
// main store should exist.
|
||||||
// TODO: we don't actually need the main store here
|
// TODO: we don't actually need the main store here
|
||||||
main := app.cms.GetKVStore(mainKey)
|
main := app.cms.GetKVStore(mainKey)
|
||||||
|
@ -192,6 +173,9 @@ func (app *BaseApp) initFromStore(mainKey sdk.StoreKey) error {
|
||||||
}
|
}
|
||||||
// Needed for `gaiad export`, which inits from store but never calls initchain
|
// Needed for `gaiad export`, which inits from store but never calls initchain
|
||||||
app.setCheckState(abci.Header{})
|
app.setCheckState(abci.Header{})
|
||||||
|
|
||||||
|
app.Seal()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,12 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/wire"
|
"github.com/cosmos/cosmos-sdk/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// make some cap keys
|
||||||
|
capKey1 = sdk.NewKVStoreKey("key1")
|
||||||
|
capKey2 = sdk.NewKVStoreKey("key2")
|
||||||
|
)
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------
|
||||||
// Helpers for setup. Most tests should be able to use setupBaseApp
|
// Helpers for setup. Most tests should be able to use setupBaseApp
|
||||||
|
|
||||||
|
@ -25,12 +31,12 @@ func defaultLogger() log.Logger {
|
||||||
return log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app")
|
return log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app")
|
||||||
}
|
}
|
||||||
|
|
||||||
func newBaseApp(name string) *BaseApp {
|
func newBaseApp(name string, options ...func(*BaseApp)) *BaseApp {
|
||||||
logger := defaultLogger()
|
logger := defaultLogger()
|
||||||
db := dbm.NewMemDB()
|
db := dbm.NewMemDB()
|
||||||
codec := wire.NewCodec()
|
codec := wire.NewCodec()
|
||||||
registerTestCodec(codec)
|
registerTestCodec(codec)
|
||||||
return NewBaseApp(name, logger, db, testTxDecoder(codec))
|
return NewBaseApp(name, logger, db, testTxDecoder(codec), options...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerTestCodec(cdc *wire.Codec) {
|
func registerTestCodec(cdc *wire.Codec) {
|
||||||
|
@ -45,14 +51,10 @@ func registerTestCodec(cdc *wire.Codec) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// simple one store baseapp
|
// simple one store baseapp
|
||||||
func setupBaseApp(t *testing.T) (*BaseApp, *sdk.KVStoreKey, *sdk.KVStoreKey) {
|
func setupBaseApp(t *testing.T, options ...func(*BaseApp)) *BaseApp {
|
||||||
app := newBaseApp(t.Name())
|
app := newBaseApp(t.Name(), options...)
|
||||||
require.Equal(t, t.Name(), app.Name())
|
require.Equal(t, t.Name(), app.Name())
|
||||||
|
|
||||||
// make some cap keys
|
|
||||||
capKey1 := sdk.NewKVStoreKey("key1")
|
|
||||||
capKey2 := sdk.NewKVStoreKey("key2")
|
|
||||||
|
|
||||||
// no stores are mounted
|
// no stores are mounted
|
||||||
require.Panics(t, func() { app.LoadLatestVersion(capKey1) })
|
require.Panics(t, func() { app.LoadLatestVersion(capKey1) })
|
||||||
|
|
||||||
|
@ -61,14 +63,14 @@ func setupBaseApp(t *testing.T) (*BaseApp, *sdk.KVStoreKey, *sdk.KVStoreKey) {
|
||||||
// stores are mounted
|
// stores are mounted
|
||||||
err := app.LoadLatestVersion(capKey1)
|
err := app.LoadLatestVersion(capKey1)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
return app, capKey1, capKey2
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------
|
||||||
// test mounting and loading stores
|
// test mounting and loading stores
|
||||||
|
|
||||||
func TestMountStores(t *testing.T) {
|
func TestMountStores(t *testing.T) {
|
||||||
app, capKey1, capKey2 := setupBaseApp(t)
|
app := setupBaseApp(t)
|
||||||
|
|
||||||
// check both stores
|
// check both stores
|
||||||
store1 := app.cms.GetCommitKVStore(capKey1)
|
store1 := app.cms.GetCommitKVStore(capKey1)
|
||||||
|
@ -216,8 +218,6 @@ func TestInitChainer(t *testing.T) {
|
||||||
capKey := sdk.NewKVStoreKey("main")
|
capKey := sdk.NewKVStoreKey("main")
|
||||||
capKey2 := sdk.NewKVStoreKey("key2")
|
capKey2 := sdk.NewKVStoreKey("key2")
|
||||||
app.MountStoresIAVL(capKey, capKey2)
|
app.MountStoresIAVL(capKey, capKey2)
|
||||||
err := app.LoadLatestVersion(capKey) // needed to make stores non-nil
|
|
||||||
require.Nil(t, err)
|
|
||||||
|
|
||||||
// set a value in the store on init chain
|
// set a value in the store on init chain
|
||||||
key, value := []byte("hello"), []byte("goodbye")
|
key, value := []byte("hello"), []byte("goodbye")
|
||||||
|
@ -239,6 +239,11 @@ func TestInitChainer(t *testing.T) {
|
||||||
|
|
||||||
// set initChainer and try again - should see the value
|
// set initChainer and try again - should see the value
|
||||||
app.SetInitChainer(initChainer)
|
app.SetInitChainer(initChainer)
|
||||||
|
|
||||||
|
// stores are mounted and private members are set - sealing baseapp
|
||||||
|
err := app.LoadLatestVersion(capKey) // needed to make stores non-nil
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
app.InitChain(abci.RequestInitChain{AppStateBytes: []byte("{}"), ChainId: "test-chain-id"}) // must have valid JSON genesis file, even if empty
|
app.InitChain(abci.RequestInitChain{AppStateBytes: []byte("{}"), ChainId: "test-chain-id"}) // must have valid JSON genesis file, even if empty
|
||||||
|
|
||||||
// assert that chainID is set correctly in InitChain
|
// assert that chainID is set correctly in InitChain
|
||||||
|
@ -254,10 +259,10 @@ func TestInitChainer(t *testing.T) {
|
||||||
|
|
||||||
// reload app
|
// reload app
|
||||||
app = NewBaseApp(name, logger, db, nil)
|
app = NewBaseApp(name, logger, db, nil)
|
||||||
|
app.SetInitChainer(initChainer)
|
||||||
app.MountStoresIAVL(capKey, capKey2)
|
app.MountStoresIAVL(capKey, capKey2)
|
||||||
err = app.LoadLatestVersion(capKey) // needed to make stores non-nil
|
err = app.LoadLatestVersion(capKey) // needed to make stores non-nil
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
app.SetInitChainer(initChainer)
|
|
||||||
|
|
||||||
// ensure we can still query after reloading
|
// ensure we can still query after reloading
|
||||||
res = app.Query(query)
|
res = app.Query(query)
|
||||||
|
@ -426,18 +431,20 @@ func incrementingCounter(t *testing.T, store sdk.KVStore, counterKey []byte, cou
|
||||||
// on the store within a block, and that the CheckTx state
|
// on the store within a block, and that the CheckTx state
|
||||||
// gets reset to the latest committed state during Commit
|
// gets reset to the latest committed state during Commit
|
||||||
func TestCheckTx(t *testing.T) {
|
func TestCheckTx(t *testing.T) {
|
||||||
app, capKey, _ := setupBaseApp(t)
|
|
||||||
|
|
||||||
// This ante handler reads the key and checks that the value matches the current counter.
|
// This ante handler reads the key and checks that the value matches the current counter.
|
||||||
// This ensures changes to the kvstore persist across successive CheckTx.
|
// This ensures changes to the kvstore persist across successive CheckTx.
|
||||||
counterKey := []byte("counter-key")
|
counterKey := []byte("counter-key")
|
||||||
app.SetAnteHandler(anteHandlerTxTest(t, capKey, counterKey))
|
|
||||||
|
anteOpt := func(bapp *BaseApp) { bapp.SetAnteHandler(anteHandlerTxTest(t, capKey1, counterKey)) }
|
||||||
|
routerOpt := func(bapp *BaseApp) {
|
||||||
|
// TODO: can remove this once CheckTx doesnt process msgs.
|
||||||
|
bapp.Router().AddRoute(typeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) sdk.Result { return sdk.Result{} })
|
||||||
|
}
|
||||||
|
|
||||||
|
app := setupBaseApp(t, anteOpt, routerOpt)
|
||||||
|
|
||||||
nTxs := int64(5)
|
nTxs := int64(5)
|
||||||
|
|
||||||
// TODO: can remove this once CheckTx doesnt process msgs.
|
|
||||||
app.Router().AddRoute(typeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) sdk.Result { return sdk.Result{} })
|
|
||||||
|
|
||||||
app.InitChain(abci.RequestInitChain{})
|
app.InitChain(abci.RequestInitChain{})
|
||||||
|
|
||||||
// Create same codec used in txDecoder
|
// Create same codec used in txDecoder
|
||||||
|
@ -452,7 +459,7 @@ func TestCheckTx(t *testing.T) {
|
||||||
assert.True(t, r.IsOK(), fmt.Sprintf("%v", r))
|
assert.True(t, r.IsOK(), fmt.Sprintf("%v", r))
|
||||||
}
|
}
|
||||||
|
|
||||||
checkStateStore := app.checkState.ctx.KVStore(capKey)
|
checkStateStore := app.checkState.ctx.KVStore(capKey1)
|
||||||
storedCounter := getIntFromStore(checkStateStore, counterKey)
|
storedCounter := getIntFromStore(checkStateStore, counterKey)
|
||||||
|
|
||||||
// Ensure AnteHandler ran
|
// Ensure AnteHandler ran
|
||||||
|
@ -463,7 +470,7 @@ func TestCheckTx(t *testing.T) {
|
||||||
app.EndBlock(abci.RequestEndBlock{})
|
app.EndBlock(abci.RequestEndBlock{})
|
||||||
app.Commit()
|
app.Commit()
|
||||||
|
|
||||||
checkStateStore = app.checkState.ctx.KVStore(capKey)
|
checkStateStore = app.checkState.ctx.KVStore(capKey1)
|
||||||
storedBytes := checkStateStore.Get(counterKey)
|
storedBytes := checkStateStore.Get(counterKey)
|
||||||
require.Nil(t, storedBytes)
|
require.Nil(t, storedBytes)
|
||||||
}
|
}
|
||||||
|
@ -471,15 +478,15 @@ func TestCheckTx(t *testing.T) {
|
||||||
// Test that successive DeliverTx can see each others' effects
|
// Test that successive DeliverTx can see each others' effects
|
||||||
// on the store, both within and across blocks.
|
// on the store, both within and across blocks.
|
||||||
func TestDeliverTx(t *testing.T) {
|
func TestDeliverTx(t *testing.T) {
|
||||||
app, capKey, _ := setupBaseApp(t)
|
|
||||||
|
|
||||||
// test increments in the ante
|
// test increments in the ante
|
||||||
anteKey := []byte("ante-key")
|
anteKey := []byte("ante-key")
|
||||||
app.SetAnteHandler(anteHandlerTxTest(t, capKey, anteKey))
|
anteOpt := func(bapp *BaseApp) { bapp.SetAnteHandler(anteHandlerTxTest(t, capKey1, anteKey)) }
|
||||||
|
|
||||||
// test increments in the handler
|
// test increments in the handler
|
||||||
deliverKey := []byte("deliver-key")
|
deliverKey := []byte("deliver-key")
|
||||||
app.Router().AddRoute(typeMsgCounter, handlerMsgCounter(t, capKey, deliverKey))
|
routerOpt := func(bapp *BaseApp) { bapp.Router().AddRoute(typeMsgCounter, handlerMsgCounter(t, capKey1, deliverKey)) }
|
||||||
|
|
||||||
|
app := setupBaseApp(t, anteOpt, routerOpt)
|
||||||
|
|
||||||
// Create same codec used in txDecoder
|
// Create same codec used in txDecoder
|
||||||
codec := wire.NewCodec()
|
codec := wire.NewCodec()
|
||||||
|
@ -510,17 +517,19 @@ func TestMultiMsgCheckTx(t *testing.T) {
|
||||||
|
|
||||||
// One call to DeliverTx should process all the messages, in order.
|
// One call to DeliverTx should process all the messages, in order.
|
||||||
func TestMultiMsgDeliverTx(t *testing.T) {
|
func TestMultiMsgDeliverTx(t *testing.T) {
|
||||||
app, capKey, _ := setupBaseApp(t)
|
|
||||||
|
|
||||||
// increment the tx counter
|
// increment the tx counter
|
||||||
anteKey := []byte("ante-key")
|
anteKey := []byte("ante-key")
|
||||||
app.SetAnteHandler(anteHandlerTxTest(t, capKey, anteKey))
|
anteOpt := func(bapp *BaseApp) { bapp.SetAnteHandler(anteHandlerTxTest(t, capKey1, anteKey)) }
|
||||||
|
|
||||||
// increment the msg counter
|
// increment the msg counter
|
||||||
deliverKey := []byte("deliver-key")
|
deliverKey := []byte("deliver-key")
|
||||||
deliverKey2 := []byte("deliver-key2")
|
deliverKey2 := []byte("deliver-key2")
|
||||||
app.Router().AddRoute(typeMsgCounter, handlerMsgCounter(t, capKey, deliverKey))
|
routerOpt := func(bapp *BaseApp) {
|
||||||
app.Router().AddRoute(typeMsgCounter2, handlerMsgCounter(t, capKey, deliverKey2))
|
bapp.Router().AddRoute(typeMsgCounter, handlerMsgCounter(t, capKey1, deliverKey))
|
||||||
|
bapp.Router().AddRoute(typeMsgCounter2, handlerMsgCounter(t, capKey1, deliverKey2))
|
||||||
|
}
|
||||||
|
|
||||||
|
app := setupBaseApp(t, anteOpt, routerOpt)
|
||||||
|
|
||||||
// Create same codec used in txDecoder
|
// Create same codec used in txDecoder
|
||||||
codec := wire.NewCodec()
|
codec := wire.NewCodec()
|
||||||
|
@ -536,7 +545,7 @@ func TestMultiMsgDeliverTx(t *testing.T) {
|
||||||
res := app.DeliverTx(txBytes)
|
res := app.DeliverTx(txBytes)
|
||||||
require.True(t, res.IsOK(), fmt.Sprintf("%v", res))
|
require.True(t, res.IsOK(), fmt.Sprintf("%v", res))
|
||||||
|
|
||||||
store := app.deliverState.ctx.KVStore(capKey)
|
store := app.deliverState.ctx.KVStore(capKey1)
|
||||||
|
|
||||||
// tx counter only incremented once
|
// tx counter only incremented once
|
||||||
txCounter := getIntFromStore(store, anteKey)
|
txCounter := getIntFromStore(store, anteKey)
|
||||||
|
@ -557,7 +566,7 @@ func TestMultiMsgDeliverTx(t *testing.T) {
|
||||||
res := app.DeliverTx(txBytes)
|
res := app.DeliverTx(txBytes)
|
||||||
require.True(t, res.IsOK(), fmt.Sprintf("%v", res))
|
require.True(t, res.IsOK(), fmt.Sprintf("%v", res))
|
||||||
|
|
||||||
store := app.deliverState.ctx.KVStore(capKey)
|
store := app.deliverState.ctx.KVStore(capKey1)
|
||||||
|
|
||||||
// tx counter only incremented once
|
// tx counter only incremented once
|
||||||
txCounter := getIntFromStore(store, anteKey)
|
txCounter := getIntFromStore(store, anteKey)
|
||||||
|
@ -583,18 +592,24 @@ func TestConcurrentCheckDeliver(t *testing.T) {
|
||||||
// Simulate() and Query("/app/simulate", txBytes) should give
|
// Simulate() and Query("/app/simulate", txBytes) should give
|
||||||
// the same results.
|
// the same results.
|
||||||
func TestSimulateTx(t *testing.T) {
|
func TestSimulateTx(t *testing.T) {
|
||||||
app, _, _ := setupBaseApp(t)
|
|
||||||
|
|
||||||
gasConsumed := int64(5)
|
gasConsumed := int64(5)
|
||||||
app.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) {
|
|
||||||
newCtx = ctx.WithGasMeter(sdk.NewGasMeter(gasConsumed))
|
|
||||||
return
|
|
||||||
})
|
|
||||||
|
|
||||||
app.Router().AddRoute(typeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
anteOpt := func(bapp *BaseApp) {
|
||||||
ctx.GasMeter().ConsumeGas(gasConsumed, "test")
|
bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) {
|
||||||
return sdk.Result{GasUsed: ctx.GasMeter().GasConsumed()}
|
newCtx = ctx.WithGasMeter(sdk.NewGasMeter(gasConsumed))
|
||||||
})
|
return
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
routerOpt := func(bapp *BaseApp) {
|
||||||
|
bapp.Router().AddRoute(typeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||||
|
ctx.GasMeter().ConsumeGas(gasConsumed, "test")
|
||||||
|
return sdk.Result{GasUsed: ctx.GasMeter().GasConsumed()}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
app := setupBaseApp(t, anteOpt, routerOpt)
|
||||||
|
|
||||||
app.InitChain(abci.RequestInitChain{})
|
app.InitChain(abci.RequestInitChain{})
|
||||||
|
|
||||||
// Create same codec used in txDecoder
|
// Create same codec used in txDecoder
|
||||||
|
@ -643,10 +658,14 @@ func TestSimulateTx(t *testing.T) {
|
||||||
// TODO: add more
|
// TODO: add more
|
||||||
|
|
||||||
func TestRunInvalidTransaction(t *testing.T) {
|
func TestRunInvalidTransaction(t *testing.T) {
|
||||||
app, _, _ := setupBaseApp(t)
|
anteOpt := func(bapp *BaseApp) {
|
||||||
app.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) { return })
|
bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) { return })
|
||||||
app.Router().AddRoute(typeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (res sdk.Result) { return })
|
}
|
||||||
|
routerOpt := func(bapp *BaseApp) {
|
||||||
|
bapp.Router().AddRoute(typeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (res sdk.Result) { return })
|
||||||
|
}
|
||||||
|
|
||||||
|
app := setupBaseApp(t, anteOpt, routerOpt)
|
||||||
app.BeginBlock(abci.RequestBeginBlock{})
|
app.BeginBlock(abci.RequestBeginBlock{})
|
||||||
|
|
||||||
// Transaction with no messages
|
// Transaction with no messages
|
||||||
|
@ -713,43 +732,49 @@ func TestRunInvalidTransaction(t *testing.T) {
|
||||||
|
|
||||||
// Test that transactions exceeding gas limits fail
|
// Test that transactions exceeding gas limits fail
|
||||||
func TestTxGasLimits(t *testing.T) {
|
func TestTxGasLimits(t *testing.T) {
|
||||||
app, _, _ := setupBaseApp(t)
|
|
||||||
|
|
||||||
gasGranted := int64(10)
|
gasGranted := int64(10)
|
||||||
app.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) {
|
anteOpt := func(bapp *BaseApp) {
|
||||||
newCtx = ctx.WithGasMeter(sdk.NewGasMeter(gasGranted))
|
bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) {
|
||||||
|
newCtx = ctx.WithGasMeter(sdk.NewGasMeter(gasGranted))
|
||||||
|
|
||||||
// NOTE/TODO/XXX:
|
// NOTE/TODO/XXX:
|
||||||
// AnteHandlers must have their own defer/recover in order
|
// AnteHandlers must have their own defer/recover in order
|
||||||
// for the BaseApp to know how much gas was used used!
|
// for the BaseApp to know how much gas was used used!
|
||||||
// This is because the GasMeter is created in the AnteHandler,
|
// This is because the GasMeter is created in the AnteHandler,
|
||||||
// but if it panics the context won't be set properly in runTx's recover ...
|
// but if it panics the context won't be set properly in runTx's recover ...
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
switch rType := r.(type) {
|
switch rType := r.(type) {
|
||||||
case sdk.ErrorOutOfGas:
|
case sdk.ErrorOutOfGas:
|
||||||
log := fmt.Sprintf("out of gas in location: %v", rType.Descriptor)
|
log := fmt.Sprintf("out of gas in location: %v", rType.Descriptor)
|
||||||
res = sdk.ErrOutOfGas(log).Result()
|
res = sdk.ErrOutOfGas(log).Result()
|
||||||
res.GasWanted = gasGranted
|
res.GasWanted = gasGranted
|
||||||
res.GasUsed = newCtx.GasMeter().GasConsumed()
|
res.GasUsed = newCtx.GasMeter().GasConsumed()
|
||||||
default:
|
default:
|
||||||
panic(r)
|
panic(r)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}()
|
||||||
}()
|
|
||||||
|
|
||||||
count := tx.(*txTest).Counter
|
count := tx.(*txTest).Counter
|
||||||
newCtx.GasMeter().ConsumeGas(count, "counter-ante")
|
newCtx.GasMeter().ConsumeGas(count, "counter-ante")
|
||||||
res = sdk.Result{
|
res = sdk.Result{
|
||||||
GasWanted: gasGranted,
|
GasWanted: gasGranted,
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
})
|
})
|
||||||
app.Router().AddRoute(typeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
|
||||||
count := msg.(msgCounter).Counter
|
}
|
||||||
ctx.GasMeter().ConsumeGas(count, "counter-handler")
|
|
||||||
return sdk.Result{}
|
routerOpt := func(bapp *BaseApp) {
|
||||||
})
|
bapp.Router().AddRoute(typeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||||
|
count := msg.(msgCounter).Counter
|
||||||
|
ctx.GasMeter().ConsumeGas(count, "counter-handler")
|
||||||
|
return sdk.Result{}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
app := setupBaseApp(t, anteOpt, routerOpt)
|
||||||
|
|
||||||
app.BeginBlock(abci.RequestBeginBlock{})
|
app.BeginBlock(abci.RequestBeginBlock{})
|
||||||
|
|
||||||
|
@ -798,20 +823,25 @@ func TestTxGasLimits(t *testing.T) {
|
||||||
|
|
||||||
// Test that we can only query from the latest committed state.
|
// Test that we can only query from the latest committed state.
|
||||||
func TestQuery(t *testing.T) {
|
func TestQuery(t *testing.T) {
|
||||||
app, capKey, _ := setupBaseApp(t)
|
|
||||||
|
|
||||||
key, value := []byte("hello"), []byte("goodbye")
|
key, value := []byte("hello"), []byte("goodbye")
|
||||||
app.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) {
|
anteOpt := func(bapp *BaseApp) {
|
||||||
store := ctx.KVStore(capKey)
|
bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) {
|
||||||
store.Set(key, value)
|
store := ctx.KVStore(capKey1)
|
||||||
return
|
store.Set(key, value)
|
||||||
})
|
return
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
routerOpt := func(bapp *BaseApp) {
|
||||||
|
bapp.Router().AddRoute(typeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||||
|
store := ctx.KVStore(capKey1)
|
||||||
|
store.Set(key, value)
|
||||||
|
return sdk.Result{}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
app := setupBaseApp(t, anteOpt, routerOpt)
|
||||||
|
|
||||||
app.Router().AddRoute(typeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
|
||||||
store := ctx.KVStore(capKey)
|
|
||||||
store.Set(key, value)
|
|
||||||
return sdk.Result{}
|
|
||||||
})
|
|
||||||
app.InitChain(abci.RequestInitChain{})
|
app.InitChain(abci.RequestInitChain{})
|
||||||
|
|
||||||
// NOTE: "/store/key1" tells us KVStore
|
// NOTE: "/store/key1" tells us KVStore
|
||||||
|
@ -848,17 +878,21 @@ func TestQuery(t *testing.T) {
|
||||||
|
|
||||||
// Test p2p filter queries
|
// Test p2p filter queries
|
||||||
func TestP2PQuery(t *testing.T) {
|
func TestP2PQuery(t *testing.T) {
|
||||||
app, _, _ := setupBaseApp(t)
|
addrPeerFilterOpt := func(bapp *BaseApp) {
|
||||||
|
bapp.SetAddrPeerFilter(func(addrport string) abci.ResponseQuery {
|
||||||
|
require.Equal(t, "1.1.1.1:8000", addrport)
|
||||||
|
return abci.ResponseQuery{Code: uint32(3)}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
app.SetAddrPeerFilter(func(addrport string) abci.ResponseQuery {
|
pubkeyPeerFilterOpt := func(bapp *BaseApp) {
|
||||||
require.Equal(t, "1.1.1.1:8000", addrport)
|
bapp.SetPubKeyPeerFilter(func(pubkey string) abci.ResponseQuery {
|
||||||
return abci.ResponseQuery{Code: uint32(3)}
|
require.Equal(t, "testpubkey", pubkey)
|
||||||
})
|
return abci.ResponseQuery{Code: uint32(4)}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
app.SetPubKeyPeerFilter(func(pubkey string) abci.ResponseQuery {
|
app := setupBaseApp(t, addrPeerFilterOpt, pubkeyPeerFilterOpt)
|
||||||
require.Equal(t, "testpubkey", pubkey)
|
|
||||||
return abci.ResponseQuery{Code: uint32(4)}
|
|
||||||
})
|
|
||||||
|
|
||||||
addrQuery := abci.RequestQuery{
|
addrQuery := abci.RequestQuery{
|
||||||
Path: "/p2p/filter/addr/1.1.1.1:8000",
|
Path: "/p2p/filter/addr/1.1.1.1:8000",
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
package baseapp
|
||||||
|
|
||||||
|
import (
|
||||||
|
dbm "github.com/tendermint/tendermint/libs/db"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/store"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// nolint - Setter functions
|
||||||
|
func (app *BaseApp) SetName(name string) {
|
||||||
|
if app.sealed {
|
||||||
|
panic("SetName() on sealed BaseApp")
|
||||||
|
}
|
||||||
|
app.name = name
|
||||||
|
}
|
||||||
|
func (app *BaseApp) SetDB(db dbm.DB) {
|
||||||
|
if app.sealed {
|
||||||
|
panic("SetDB() on sealed BaseApp")
|
||||||
|
}
|
||||||
|
app.db = db
|
||||||
|
}
|
||||||
|
func (app *BaseApp) SetCMS(cms store.CommitMultiStore) {
|
||||||
|
if app.sealed {
|
||||||
|
panic("SetEndBlocker() on sealed BaseApp")
|
||||||
|
}
|
||||||
|
app.cms = cms
|
||||||
|
}
|
||||||
|
func (app *BaseApp) SetTxDecoder(txDecoder sdk.TxDecoder) {
|
||||||
|
if app.sealed {
|
||||||
|
panic("SetTxDecoder() on sealed BaseApp")
|
||||||
|
}
|
||||||
|
app.txDecoder = txDecoder
|
||||||
|
}
|
||||||
|
func (app *BaseApp) SetInitChainer(initChainer sdk.InitChainer) {
|
||||||
|
if app.sealed {
|
||||||
|
panic("SetInitChainer() on sealed BaseApp")
|
||||||
|
}
|
||||||
|
app.initChainer = initChainer
|
||||||
|
}
|
||||||
|
func (app *BaseApp) SetBeginBlocker(beginBlocker sdk.BeginBlocker) {
|
||||||
|
if app.sealed {
|
||||||
|
panic("SetBeginBlocker() on sealed BaseApp")
|
||||||
|
}
|
||||||
|
app.beginBlocker = beginBlocker
|
||||||
|
}
|
||||||
|
func (app *BaseApp) SetEndBlocker(endBlocker sdk.EndBlocker) {
|
||||||
|
if app.sealed {
|
||||||
|
panic("SetEndBlocker() on sealed BaseApp")
|
||||||
|
}
|
||||||
|
app.endBlocker = endBlocker
|
||||||
|
}
|
||||||
|
func (app *BaseApp) SetAnteHandler(ah sdk.AnteHandler) {
|
||||||
|
if app.sealed {
|
||||||
|
panic("SetAnteHandler() on sealed BaseApp")
|
||||||
|
}
|
||||||
|
app.anteHandler = ah
|
||||||
|
}
|
||||||
|
func (app *BaseApp) SetAddrPeerFilter(pf sdk.PeerFilter) {
|
||||||
|
if app.sealed {
|
||||||
|
panic("SetAddrPeerFilter() on sealed BaseApp")
|
||||||
|
}
|
||||||
|
app.addrPeerFilter = pf
|
||||||
|
}
|
||||||
|
func (app *BaseApp) SetPubKeyPeerFilter(pf sdk.PeerFilter) {
|
||||||
|
if app.sealed {
|
||||||
|
panic("SetPubKeyPeerFilter() on sealed BaseApp")
|
||||||
|
}
|
||||||
|
app.pubkeyPeerFilter = pf
|
||||||
|
}
|
||||||
|
func (app *BaseApp) Router() Router {
|
||||||
|
if app.sealed {
|
||||||
|
panic("Router() on sealed BaseApp")
|
||||||
|
}
|
||||||
|
return app.router
|
||||||
|
}
|
||||||
|
func (app *BaseApp) Seal() { app.sealed = true }
|
||||||
|
func (app *BaseApp) IsSealed() bool { return app.sealed }
|
||||||
|
func (app *BaseApp) enforceSeal() {
|
||||||
|
if !app.sealed {
|
||||||
|
panic("enforceSeal() on BaseApp but not sealed")
|
||||||
|
}
|
||||||
|
}
|
|
@ -196,6 +196,8 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, baseAppOptions ...func(*bam.BaseAp
|
||||||
cmn.Exit(err.Error())
|
cmn.Exit(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.Seal()
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,8 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB, baseAppOptions ...func(*bam.Ba
|
||||||
cmn.Exit(err.Error())
|
cmn.Exit(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.Seal()
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,9 @@ func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cmn.Exit(err.Error())
|
cmn.Exit(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.Seal()
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,9 @@ func getMockApp(t *testing.T) *mock.App {
|
||||||
mapp.SetInitChainer(getInitChainer(mapp, keeper))
|
mapp.SetInitChainer(getInitChainer(mapp, keeper))
|
||||||
|
|
||||||
require.NoError(t, mapp.CompleteSetup([]*sdk.KVStoreKey{keyPOW}))
|
require.NoError(t, mapp.CompleteSetup([]*sdk.KVStoreKey{keyPOW}))
|
||||||
|
|
||||||
|
mapp.Seal()
|
||||||
|
|
||||||
return mapp
|
return mapp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,12 +36,13 @@ func getMockApp(t *testing.T, numGenAccs int) (*mock.App, Keeper, stake.Keeper,
|
||||||
keeper := NewKeeper(mapp.Cdc, keyGov, pk.Setter(), ck, sk, DefaultCodespace)
|
keeper := NewKeeper(mapp.Cdc, keyGov, pk.Setter(), ck, sk, DefaultCodespace)
|
||||||
mapp.Router().AddRoute("gov", NewHandler(keeper))
|
mapp.Router().AddRoute("gov", NewHandler(keeper))
|
||||||
|
|
||||||
require.NoError(t, mapp.CompleteSetup([]*sdk.KVStoreKey{keyStake, keyGov, keyGlobalParams}))
|
|
||||||
|
|
||||||
mapp.SetEndBlocker(getEndBlocker(keeper))
|
mapp.SetEndBlocker(getEndBlocker(keeper))
|
||||||
mapp.SetInitChainer(getInitChainer(mapp, keeper, sk))
|
mapp.SetInitChainer(getInitChainer(mapp, keeper, sk))
|
||||||
|
|
||||||
|
require.NoError(t, mapp.CompleteSetup([]*sdk.KVStoreKey{keyStake, keyGov, keyGlobalParams}))
|
||||||
|
|
||||||
genAccs, addrs, pubKeys, privKeys := mock.CreateGenAccounts(numGenAccs, sdk.Coins{sdk.NewInt64Coin("steak", 42)})
|
genAccs, addrs, pubKeys, privKeys := mock.CreateGenAccounts(numGenAccs, sdk.Coins{sdk.NewInt64Coin("steak", 42)})
|
||||||
|
|
||||||
mock.SetGenesis(mapp, genAccs)
|
mock.SetGenesis(mapp, genAccs)
|
||||||
|
|
||||||
return mapp, keeper, sk, addrs, pubKeys, privKeys
|
return mapp, keeper, sk, addrs, pubKeys, privKeys
|
||||||
|
|
|
@ -67,6 +67,8 @@ func NewApp() *App {
|
||||||
app.SetInitChainer(app.InitChainer)
|
app.SetInitChainer(app.InitChainer)
|
||||||
app.SetAnteHandler(auth.NewAnteHandler(app.AccountMapper, app.FeeCollectionKeeper))
|
app.SetAnteHandler(auth.NewAnteHandler(app.AccountMapper, app.FeeCollectionKeeper))
|
||||||
|
|
||||||
|
// Not sealing for custom extension
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue