2018-01-20 20:08:00 -08:00
package baseapp
2017-12-20 17:34:51 -08:00
import (
"encoding/json"
"fmt"
2018-02-16 17:15:38 -08:00
"os"
2017-12-20 17:34:51 -08:00
"testing"
"github.com/stretchr/testify/assert"
2018-05-11 11:02:05 -07:00
"github.com/stretchr/testify/require"
2017-12-20 17:34:51 -08:00
2018-06-28 17:54:47 -07:00
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto"
2018-07-02 13:34:06 -07:00
cmn "github.com/tendermint/tendermint/libs/common"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
2018-07-02 21:33:53 -07:00
tmtypes "github.com/tendermint/tendermint/types"
2018-01-15 17:38:56 -08:00
sdk "github.com/cosmos/cosmos-sdk/types"
2018-05-11 11:02:05 -07:00
"github.com/cosmos/cosmos-sdk/wire"
2018-05-23 22:09:01 -07:00
"github.com/cosmos/cosmos-sdk/x/auth"
2018-06-27 15:33:56 -07:00
"github.com/cosmos/cosmos-sdk/x/bank"
2017-12-20 17:34:51 -08:00
)
2018-02-16 17:15:38 -08:00
func defaultLogger ( ) log . Logger {
return log . NewTMLogger ( log . NewSyncWriter ( os . Stdout ) ) . With ( "module" , "sdk/app" )
}
func newBaseApp ( name string ) * BaseApp {
logger := defaultLogger ( )
db := dbm . NewMemDB ( )
2018-05-11 11:02:05 -07:00
codec := wire . NewCodec ( )
2018-06-21 15:05:25 -07:00
auth . RegisterBaseAccount ( codec )
2018-05-15 17:31:52 -07:00
return NewBaseApp ( name , codec , logger , db )
2018-02-16 17:15:38 -08:00
}
2018-02-16 16:52:07 -08:00
func TestMountStores ( t * testing . T ) {
2018-02-16 17:58:51 -08:00
name := t . Name ( )
app := newBaseApp ( name )
2018-06-29 18:10:15 -07:00
require . Equal ( t , name , app . Name ( ) )
2018-02-16 16:52:07 -08:00
// make some cap keys
capKey1 := sdk . NewKVStoreKey ( "key1" )
capKey2 := sdk . NewKVStoreKey ( "key2" )
// no stores are mounted
2018-06-29 18:10:15 -07:00
require . Panics ( t , func ( ) { app . LoadLatestVersion ( capKey1 ) } )
2018-02-16 16:52:07 -08:00
2018-04-13 03:44:20 -07:00
app . MountStoresIAVL ( capKey1 , capKey2 )
2018-02-16 16:52:07 -08:00
2018-02-27 19:23:56 -08:00
// stores are mounted
2018-02-16 16:52:07 -08:00
err := app . LoadLatestVersion ( capKey1 )
2018-06-29 18:10:15 -07:00
require . Nil ( t , err )
2018-02-27 19:23:56 -08:00
// check both stores
store1 := app . cms . GetCommitKVStore ( capKey1 )
2018-06-29 18:10:15 -07:00
require . NotNil ( t , store1 )
2018-02-27 19:23:56 -08:00
store2 := app . cms . GetCommitKVStore ( capKey2 )
2018-06-29 18:10:15 -07:00
require . NotNil ( t , store2 )
2018-02-16 16:52:07 -08:00
}
2018-02-26 02:59:48 -08:00
2018-02-19 10:02:04 -08:00
// Test that we can make commits and then reload old versions.
// Test that LoadLatestVersion actually does.
2018-02-16 16:52:07 -08:00
func TestLoadVersion ( t * testing . T ) {
2018-02-27 19:23:56 -08:00
logger := defaultLogger ( )
db := dbm . NewMemDB ( )
name := t . Name ( )
2018-05-15 17:31:52 -07:00
app := NewBaseApp ( name , nil , logger , db )
2018-02-27 19:23:56 -08:00
// make a cap key and mount the store
capKey := sdk . NewKVStoreKey ( "main" )
app . MountStoresIAVL ( capKey )
err := app . LoadLatestVersion ( capKey ) // needed to make stores non-nil
2018-06-29 18:10:15 -07:00
require . Nil ( t , err )
2018-02-27 19:23:56 -08:00
emptyCommitID := sdk . CommitID { }
lastHeight := app . LastBlockHeight ( )
lastID := app . LastCommitID ( )
2018-06-29 18:10:15 -07:00
require . Equal ( t , int64 ( 0 ) , lastHeight )
require . Equal ( t , emptyCommitID , lastID )
2018-02-27 19:23:56 -08:00
// execute some blocks
header := abci . Header { Height : 1 }
app . BeginBlock ( abci . RequestBeginBlock { Header : header } )
res := app . Commit ( )
2018-06-04 21:55:02 -07:00
commitID1 := sdk . CommitID { 1 , res . Data }
header = abci . Header { Height : 2 }
app . BeginBlock ( abci . RequestBeginBlock { Header : header } )
res = app . Commit ( )
commitID2 := sdk . CommitID { 2 , res . Data }
2018-02-27 19:23:56 -08:00
2018-06-04 21:55:02 -07:00
// reload with LoadLatestVersion
2018-05-15 17:31:52 -07:00
app = NewBaseApp ( name , nil , logger , db )
2018-02-27 19:23:56 -08:00
app . MountStoresIAVL ( capKey )
2018-06-04 21:55:02 -07:00
err = app . LoadLatestVersion ( capKey )
2018-06-29 18:10:15 -07:00
require . Nil ( t , err )
2018-06-04 21:55:02 -07:00
testLoadVersionHelper ( t , app , int64 ( 2 ) , commitID2 )
// reload with LoadVersion, see if you can commit the same block and get
// the same result
app = NewBaseApp ( name , nil , logger , db )
app . MountStoresIAVL ( capKey )
err = app . LoadVersion ( 1 , capKey )
2018-06-29 18:10:15 -07:00
require . Nil ( t , err )
2018-06-04 21:55:02 -07:00
testLoadVersionHelper ( t , app , int64 ( 1 ) , commitID1 )
app . BeginBlock ( abci . RequestBeginBlock { Header : header } )
app . Commit ( )
testLoadVersionHelper ( t , app , int64 ( 2 ) , commitID2 )
}
2018-02-27 19:23:56 -08:00
2018-06-04 21:55:02 -07:00
func testLoadVersionHelper ( t * testing . T , app * BaseApp , expectedHeight int64 , expectedID sdk . CommitID ) {
lastHeight := app . LastBlockHeight ( )
lastID := app . LastCommitID ( )
2018-06-29 18:10:15 -07:00
require . Equal ( t , expectedHeight , lastHeight )
require . Equal ( t , expectedID , lastID )
2018-02-17 16:13:22 -08:00
}
2018-02-27 19:23:56 -08:00
// Test that the app hash is static
// TODO: https://github.com/cosmos/cosmos-sdk/issues/520
/ * func TestStaticAppHash ( t * testing . T ) {
app := newBaseApp ( t . Name ( ) )
// make a cap key and mount the store
capKey := sdk . NewKVStoreKey ( "main" )
app . MountStoresIAVL ( capKey )
err := app . LoadLatestVersion ( capKey ) // needed to make stores non-nil
2018-06-29 18:10:15 -07:00
require . Nil ( t , err )
2018-02-27 19:23:56 -08:00
// execute some blocks
header := abci . Header { Height : 1 }
app . BeginBlock ( abci . RequestBeginBlock { Header : header } )
res := app . Commit ( )
commitID1 := sdk . CommitID { 1 , res . Data }
header = abci . Header { Height : 2 }
app . BeginBlock ( abci . RequestBeginBlock { Header : header } )
res = app . Commit ( )
commitID2 := sdk . CommitID { 2 , res . Data }
2018-06-29 18:10:15 -07:00
require . Equal ( t , commitID1 . Hash , commitID2 . Hash )
2018-02-27 19:23:56 -08:00
}
* /
2018-02-19 10:02:04 -08:00
// Test that txs can be unmarshalled and read and that
// correct error codes are returned when not
2018-02-17 16:13:22 -08:00
func TestTxDecoder ( t * testing . T ) {
// TODO
}
2018-02-19 10:02:04 -08:00
// Test that Info returns the latest committed state.
2018-02-17 16:13:22 -08:00
func TestInfo ( t * testing . T ) {
2018-02-19 10:02:04 -08:00
app := newBaseApp ( t . Name ( ) )
// ----- test an empty response -------
reqInfo := abci . RequestInfo { }
res := app . Info ( reqInfo )
// should be empty
assert . Equal ( t , "" , res . Version )
2018-02-26 02:59:48 -08:00
assert . Equal ( t , t . Name ( ) , res . GetData ( ) )
2018-02-19 10:02:04 -08:00
assert . Equal ( t , int64 ( 0 ) , res . LastBlockHeight )
2018-06-29 18:10:15 -07:00
require . Equal ( t , [ ] uint8 ( nil ) , res . LastBlockAppHash )
2018-02-19 10:02:04 -08:00
// ----- test a proper response -------
2018-02-17 16:13:22 -08:00
// TODO
2018-02-19 10:02:04 -08:00
2018-02-16 16:52:07 -08:00
}
2018-02-16 17:58:51 -08:00
func TestInitChainer ( t * testing . T ) {
2018-02-28 23:00:44 -08:00
name := t . Name ( )
2018-03-29 11:44:56 -07:00
db := dbm . NewMemDB ( )
logger := defaultLogger ( )
2018-05-15 17:31:52 -07:00
app := NewBaseApp ( name , nil , logger , db )
2018-02-28 23:02:29 -08:00
// make cap keys and mount the stores
// NOTE/TODO: mounting multiple stores is broken
// see https://github.com/cosmos/cosmos-sdk/issues/532
2018-02-16 17:58:51 -08:00
capKey := sdk . NewKVStoreKey ( "main" )
2018-03-29 11:44:56 -07:00
capKey2 := sdk . NewKVStoreKey ( "key2" )
2018-04-13 03:44:20 -07:00
app . MountStoresIAVL ( capKey , capKey2 )
2018-02-16 17:58:51 -08:00
err := app . LoadLatestVersion ( capKey ) // needed to make stores non-nil
2018-06-29 18:10:15 -07:00
require . Nil ( t , err )
2018-02-16 17:58:51 -08:00
key , value := [ ] byte ( "hello" ) , [ ] byte ( "goodbye" )
// initChainer sets a value in the store
2018-02-17 15:10:55 -08:00
var initChainer sdk . InitChainer = func ( ctx sdk . Context , req abci . RequestInitChain ) abci . ResponseInitChain {
2018-02-16 17:58:51 -08:00
store := ctx . KVStore ( capKey )
store . Set ( key , value )
2018-02-17 15:10:55 -08:00
return abci . ResponseInitChain { }
2018-02-16 17:58:51 -08:00
}
query := abci . RequestQuery {
2018-05-10 11:20:34 -07:00
Path : "/store/main/key" ,
2018-02-16 17:58:51 -08:00
Data : key ,
}
// initChainer is nil - nothing happens
app . InitChain ( abci . RequestInitChain { } )
res := app . Query ( query )
2018-06-29 18:10:15 -07:00
require . Equal ( t , 0 , len ( res . Value ) )
2018-02-16 17:58:51 -08:00
// set initChainer and try again - should see the value
app . SetInitChainer ( initChainer )
2018-06-27 15:45:10 -07:00
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
chainID := app . deliverState . ctx . ChainID ( )
2018-06-29 18:10:15 -07:00
require . Equal ( t , "test-chain-id" , chainID , "ChainID in deliverState not set correctly in InitChain" )
2018-06-27 15:45:10 -07:00
chainID = app . checkState . ctx . ChainID ( )
2018-06-29 18:10:15 -07:00
require . Equal ( t , "test-chain-id" , chainID , "ChainID in checkState not set correctly in InitChain" )
2018-06-27 15:45:10 -07:00
2018-02-27 20:07:54 -08:00
app . Commit ( )
2018-02-16 17:58:51 -08:00
res = app . Query ( query )
2018-06-29 18:10:15 -07:00
require . Equal ( t , value , res . Value )
2018-02-28 23:00:44 -08:00
// reload app
2018-05-15 17:31:52 -07:00
app = NewBaseApp ( name , nil , logger , db )
2018-04-13 03:44:20 -07:00
app . MountStoresIAVL ( capKey , capKey2 )
2018-02-28 23:00:44 -08:00
err = app . LoadLatestVersion ( capKey ) // needed to make stores non-nil
2018-06-29 18:10:15 -07:00
require . Nil ( t , err )
2018-02-28 23:00:44 -08:00
app . SetInitChainer ( initChainer )
// ensure we can still query after reloading
res = app . Query ( query )
2018-06-29 18:10:15 -07:00
require . Equal ( t , value , res . Value )
2018-02-28 23:00:44 -08:00
// commit and ensure we can still query
app . BeginBlock ( abci . RequestBeginBlock { } )
app . Commit ( )
res = app . Query ( query )
2018-06-29 18:10:15 -07:00
require . Equal ( t , value , res . Value )
2018-02-16 16:52:07 -08:00
}
2018-06-04 21:55:02 -07:00
func getStateCheckingHandler ( t * testing . T , capKey * sdk . KVStoreKey , txPerHeight int , checkHeader bool ) func ( ctx sdk . Context , msg sdk . Msg ) sdk . Result {
counter := 0
return func ( ctx sdk . Context , msg sdk . Msg ) sdk . Result {
store := ctx . KVStore ( capKey )
// Checking state gets updated between checkTx's / DeliverTx's
// on the store within a block.
if counter > 0 {
// check previous value in store
counterBytes := [ ] byte { byte ( counter - 1 ) }
prevBytes := store . Get ( counterBytes )
2018-06-29 18:10:15 -07:00
require . Equal ( t , counterBytes , prevBytes )
2018-06-04 21:55:02 -07:00
}
// set the current counter in the store
counterBytes := [ ] byte { byte ( counter ) }
store . Set ( counterBytes , counterBytes )
// check that we can see the current header
// wrapped in an if, so it can be reused between CheckTx and DeliverTx tests.
if checkHeader {
thisHeader := ctx . BlockHeader ( )
height := int64 ( ( counter / txPerHeight ) + 1 )
2018-06-29 18:10:15 -07:00
require . Equal ( t , height , thisHeader . Height )
2018-06-04 21:55:02 -07:00
}
counter ++
return sdk . Result { }
}
}
// A mock transaction that has a validation which can fail.
type testTx struct {
positiveNum int64
}
const msgType2 = "testTx"
func ( tx testTx ) Type ( ) string { return msgType2 }
2018-06-20 12:27:36 -07:00
func ( tx testTx ) GetMemo ( ) string { return "" }
2018-06-21 15:05:25 -07:00
func ( tx testTx ) GetMsgs ( ) [ ] sdk . Msg { return [ ] sdk . Msg { tx } }
2018-06-04 21:55:02 -07:00
func ( tx testTx ) GetSignBytes ( ) [ ] byte { return nil }
func ( tx testTx ) GetSigners ( ) [ ] sdk . Address { return nil }
func ( tx testTx ) GetSignatures ( ) [ ] auth . StdSignature { return nil }
func ( tx testTx ) ValidateBasic ( ) sdk . Error {
if tx . positiveNum >= 0 {
return nil
}
return sdk . ErrTxDecode ( "positiveNum should be a non-negative integer." )
}
2018-02-19 10:02:04 -08:00
// Test that successive CheckTx can see each others' effects
2018-02-17 16:13:22 -08:00
// on the store within a block, and that the CheckTx state
// gets reset to the latest Committed state during Commit
func TestCheckTx ( t * testing . T ) {
2018-06-04 21:55:02 -07:00
// Initialize an app for testing
app := newBaseApp ( t . Name ( ) )
// make a cap key and mount the store
capKey := sdk . NewKVStoreKey ( "main" )
app . MountStoresIAVL ( capKey )
err := app . LoadLatestVersion ( capKey ) // needed to make stores non-nil
2018-06-29 18:10:15 -07:00
require . Nil ( t , err )
2018-06-04 21:55:02 -07:00
app . SetAnteHandler ( func ( ctx sdk . Context , tx sdk . Tx ) ( newCtx sdk . Context , res sdk . Result , abort bool ) { return } )
txPerHeight := 3
app . Router ( ) . AddRoute ( msgType , getStateCheckingHandler ( t , capKey , txPerHeight , false ) ) .
AddRoute ( msgType2 , func ( ctx sdk . Context , msg sdk . Msg ) ( res sdk . Result ) { return } )
tx := testUpdatePowerTx { } // doesn't matter
for i := 0 ; i < txPerHeight ; i ++ {
app . Check ( tx )
}
// If it gets to this point, then successive CheckTx's can see the effects of
// other CheckTx's on the block. The following checks that if another block
// is committed, the CheckTx State will reset.
app . BeginBlock ( abci . RequestBeginBlock { } )
tx2 := testTx { }
for i := 0 ; i < txPerHeight ; i ++ {
app . Deliver ( tx2 )
}
app . EndBlock ( abci . RequestEndBlock { } )
app . Commit ( )
checkStateStore := app . checkState . ctx . KVStore ( capKey )
for i := 0 ; i < txPerHeight ; i ++ {
storedValue := checkStateStore . Get ( [ ] byte { byte ( i ) } )
2018-06-29 18:10:15 -07:00
require . Nil ( t , storedValue )
2018-06-04 21:55:02 -07:00
}
2018-02-17 16:13:22 -08:00
}
2018-02-19 10:02:04 -08:00
// Test that successive DeliverTx can see each others' effects
2018-02-17 16:13:22 -08:00
// on the store, both within and across blocks.
func TestDeliverTx ( t * testing . T ) {
app := newBaseApp ( t . Name ( ) )
// make a cap key and mount the store
capKey := sdk . NewKVStoreKey ( "main" )
app . MountStoresIAVL ( capKey )
err := app . LoadLatestVersion ( capKey ) // needed to make stores non-nil
2018-06-29 18:10:15 -07:00
require . Nil ( t , err )
2018-02-17 16:13:22 -08:00
txPerHeight := 2
app . SetAnteHandler ( func ( ctx sdk . Context , tx sdk . Tx ) ( newCtx sdk . Context , res sdk . Result , abort bool ) { return } )
2018-06-04 21:55:02 -07:00
app . Router ( ) . AddRoute ( msgType , getStateCheckingHandler ( t , capKey , txPerHeight , true ) )
2018-02-17 16:13:22 -08:00
tx := testUpdatePowerTx { } // doesn't matter
header := abci . Header { AppHash : [ ] byte ( "apphash" ) }
nBlocks := 3
for blockN := 0 ; blockN < nBlocks ; blockN ++ {
// block1
header . Height = int64 ( blockN + 1 )
app . BeginBlock ( abci . RequestBeginBlock { Header : header } )
for i := 0 ; i < txPerHeight ; i ++ {
app . Deliver ( tx )
}
app . EndBlock ( abci . RequestEndBlock { } )
app . Commit ( )
}
}
2018-05-11 11:02:05 -07:00
func TestSimulateTx ( t * testing . T ) {
app := newBaseApp ( t . Name ( ) )
// make a cap key and mount the store
capKey := sdk . NewKVStoreKey ( "main" )
app . MountStoresIAVL ( capKey )
err := app . LoadLatestVersion ( capKey ) // needed to make stores non-nil
2018-06-29 18:10:15 -07:00
require . Nil ( t , err )
2018-05-11 11:02:05 -07:00
counter := 0
app . SetAnteHandler ( func ( ctx sdk . Context , tx sdk . Tx ) ( newCtx sdk . Context , res sdk . Result , abort bool ) { return } )
app . Router ( ) . AddRoute ( msgType , func ( ctx sdk . Context , msg sdk . Msg ) sdk . Result {
ctx . GasMeter ( ) . ConsumeGas ( 10 , "test" )
store := ctx . KVStore ( capKey )
// ensure store is never written
require . Nil ( t , store . Get ( [ ] byte ( "key" ) ) )
store . Set ( [ ] byte ( "key" ) , [ ] byte ( "value" ) )
// check we can see the current header
thisHeader := ctx . BlockHeader ( )
height := int64 ( counter )
2018-06-29 18:10:15 -07:00
require . Equal ( t , height , thisHeader . Height )
2018-05-11 11:02:05 -07:00
counter ++
return sdk . Result { }
} )
tx := testUpdatePowerTx { } // doesn't matter
header := abci . Header { AppHash : [ ] byte ( "apphash" ) }
app . SetTxDecoder ( func ( txBytes [ ] byte ) ( sdk . Tx , sdk . Error ) {
var ttx testUpdatePowerTx
fromJSON ( txBytes , & ttx )
return ttx , nil
} )
2018-06-27 15:45:10 -07:00
app . InitChain ( abci . RequestInitChain { } )
2018-05-11 11:02:05 -07:00
nBlocks := 3
for blockN := 0 ; blockN < nBlocks ; blockN ++ {
// block1
header . Height = int64 ( blockN + 1 )
app . BeginBlock ( abci . RequestBeginBlock { Header : header } )
result := app . Simulate ( tx )
2018-06-27 15:45:10 -07:00
require . Equal ( t , result . Code , sdk . ABCICodeOK , result . Log )
2018-05-15 17:06:17 -07:00
require . Equal ( t , int64 ( 80 ) , result . GasUsed )
2018-05-11 11:02:05 -07:00
counter --
2018-06-28 17:54:47 -07:00
encoded , err := app . cdc . MarshalJSON ( tx )
2018-05-11 11:02:05 -07:00
require . Nil ( t , err )
query := abci . RequestQuery {
Path : "/app/simulate" ,
Data : encoded ,
}
queryResult := app . Query ( query )
require . Equal ( t , queryResult . Code , uint32 ( sdk . ABCICodeOK ) )
var res sdk . Result
2018-05-11 13:06:53 -07:00
app . cdc . MustUnmarshalBinary ( queryResult . Value , & res )
2018-06-27 15:45:10 -07:00
require . Equal ( t , sdk . ABCICodeOK , res . Code , res . Log )
require . Equal ( t , int64 ( 160 ) , res . GasUsed , res . Log )
2018-05-11 11:02:05 -07:00
app . EndBlock ( abci . RequestEndBlock { } )
app . Commit ( )
}
}
2018-06-04 21:55:02 -07:00
func TestRunInvalidTransaction ( t * testing . T ) {
// Initialize an app for testing
app := newBaseApp ( t . Name ( ) )
// make a cap key and mount the store
capKey := sdk . NewKVStoreKey ( "main" )
app . MountStoresIAVL ( capKey )
err := app . LoadLatestVersion ( capKey ) // needed to make stores non-nil
2018-06-29 18:10:15 -07:00
require . Nil ( t , err )
2018-06-04 21:55:02 -07:00
app . SetAnteHandler ( func ( ctx sdk . Context , tx sdk . Tx ) ( newCtx sdk . Context , res sdk . Result , abort bool ) { return } )
app . Router ( ) . AddRoute ( msgType2 , func ( ctx sdk . Context , msg sdk . Msg ) ( res sdk . Result ) { return } )
app . BeginBlock ( abci . RequestBeginBlock { } )
// Transaction where validate fails
invalidTx := testTx { - 1 }
err1 := app . Deliver ( invalidTx )
2018-06-29 18:10:15 -07:00
require . Equal ( t , sdk . ToABCICode ( sdk . CodespaceRoot , sdk . CodeTxDecode ) , err1 . Code )
2018-06-04 21:55:02 -07:00
// Transaction with no known route
unknownRouteTx := testUpdatePowerTx { }
err2 := app . Deliver ( unknownRouteTx )
2018-06-29 18:10:15 -07:00
require . Equal ( t , sdk . ToABCICode ( sdk . CodespaceRoot , sdk . CodeUnknownRequest ) , err2 . Code )
2018-06-04 21:55:02 -07:00
}
2018-05-08 08:54:00 -07:00
// Test that transactions exceeding gas limits fail
func TestTxGasLimits ( t * testing . T ) {
logger := defaultLogger ( )
db := dbm . NewMemDB ( )
2018-05-15 17:31:52 -07:00
app := NewBaseApp ( t . Name ( ) , nil , logger , db )
2018-05-08 08:54:00 -07:00
// make a cap key and mount the store
capKey := sdk . NewKVStoreKey ( "main" )
app . MountStoresIAVL ( capKey )
err := app . LoadLatestVersion ( capKey ) // needed to make stores non-nil
2018-06-29 18:10:15 -07:00
require . Nil ( t , err )
2018-05-08 08:54:00 -07:00
2018-05-15 17:31:52 -07:00
app . SetAnteHandler ( func ( ctx sdk . Context , tx sdk . Tx ) ( newCtx sdk . Context , res sdk . Result , abort bool ) {
newCtx = ctx . WithGasMeter ( sdk . NewGasMeter ( 0 ) )
return
} )
2018-05-08 08:54:00 -07:00
app . Router ( ) . AddRoute ( msgType , func ( ctx sdk . Context , msg sdk . Msg ) sdk . Result {
ctx . GasMeter ( ) . ConsumeGas ( 10 , "counter" )
return sdk . Result { }
} )
tx := testUpdatePowerTx { } // doesn't matter
header := abci . Header { AppHash : [ ] byte ( "apphash" ) }
app . BeginBlock ( abci . RequestBeginBlock { Header : header } )
res := app . Deliver ( tx )
2018-06-29 18:10:15 -07:00
require . Equal ( t , res . Code , sdk . ToABCICode ( sdk . CodespaceRoot , sdk . CodeOutOfGas ) , "Expected transaction to run out of gas" )
2018-05-08 08:54:00 -07:00
app . EndBlock ( abci . RequestEndBlock { } )
app . Commit ( )
}
2018-02-17 16:13:22 -08:00
// Test that we can only query from the latest committed state.
func TestQuery ( t * testing . T ) {
app := newBaseApp ( t . Name ( ) )
// make a cap key and mount the store
capKey := sdk . NewKVStoreKey ( "main" )
app . MountStoresIAVL ( capKey )
err := app . LoadLatestVersion ( capKey ) // needed to make stores non-nil
2018-06-29 18:10:15 -07:00
require . Nil ( t , err )
2018-02-17 16:13:22 -08:00
key , value := [ ] byte ( "hello" ) , [ ] byte ( "goodbye" )
app . SetAnteHandler ( func ( ctx sdk . Context , tx sdk . Tx ) ( newCtx sdk . Context , res sdk . Result , abort bool ) { return } )
app . Router ( ) . AddRoute ( msgType , func ( ctx sdk . Context , msg sdk . Msg ) sdk . Result {
store := ctx . KVStore ( capKey )
store . Set ( key , value )
return sdk . Result { }
2018-04-02 08:30:30 -07:00
} )
2018-02-17 16:13:22 -08:00
query := abci . RequestQuery {
2018-05-10 11:20:34 -07:00
Path : "/store/main/key" ,
2018-02-17 16:13:22 -08:00
Data : key ,
}
// query is empty before we do anything
res := app . Query ( query )
2018-06-29 18:10:15 -07:00
require . Equal ( t , 0 , len ( res . Value ) )
2018-02-17 16:13:22 -08:00
tx := testUpdatePowerTx { } // doesn't matter
// query is still empty after a CheckTx
app . Check ( tx )
res = app . Query ( query )
2018-06-29 18:10:15 -07:00
require . Equal ( t , 0 , len ( res . Value ) )
2018-02-17 16:13:22 -08:00
// query is still empty after a DeliverTx before we commit
app . BeginBlock ( abci . RequestBeginBlock { } )
app . Deliver ( tx )
res = app . Query ( query )
2018-06-29 18:10:15 -07:00
require . Equal ( t , 0 , len ( res . Value ) )
2018-02-17 16:13:22 -08:00
// query returns correct value after Commit
app . Commit ( )
res = app . Query ( query )
2018-06-29 18:10:15 -07:00
require . Equal ( t , value , res . Value )
2018-02-17 16:13:22 -08:00
}
2018-05-15 07:00:17 -07:00
// Test p2p filter queries
func TestP2PQuery ( t * testing . T ) {
app := newBaseApp ( t . Name ( ) )
// make a cap key and mount the store
capKey := sdk . NewKVStoreKey ( "main" )
app . MountStoresIAVL ( capKey )
err := app . LoadLatestVersion ( capKey ) // needed to make stores non-nil
2018-06-29 18:10:15 -07:00
require . Nil ( t , err )
2018-05-15 07:00:17 -07:00
app . SetAddrPeerFilter ( func ( addrport string ) abci . ResponseQuery {
require . Equal ( t , "1.1.1.1:8000" , addrport )
return abci . ResponseQuery { Code : uint32 ( 3 ) }
} )
app . SetPubKeyPeerFilter ( func ( pubkey string ) abci . ResponseQuery {
require . Equal ( t , "testpubkey" , pubkey )
return abci . ResponseQuery { Code : uint32 ( 4 ) }
} )
addrQuery := abci . RequestQuery {
Path : "/p2p/filter/addr/1.1.1.1:8000" ,
}
res := app . Query ( addrQuery )
require . Equal ( t , uint32 ( 3 ) , res . Code )
pubkeyQuery := abci . RequestQuery {
Path : "/p2p/filter/pubkey/testpubkey" ,
}
res = app . Query ( pubkeyQuery )
require . Equal ( t , uint32 ( 4 ) , res . Code )
}
2018-02-16 16:52:07 -08:00
//----------------------
2018-02-17 16:13:22 -08:00
// TODO: clean this up
2018-02-16 16:52:07 -08:00
2018-01-06 12:53:31 -08:00
// A mock transaction to update a validator's voting power.
2018-01-26 04:19:33 -08:00
type testUpdatePowerTx struct {
2018-01-06 12:53:31 -08:00
Addr [ ] byte
NewPower int64
}
2017-12-20 17:34:51 -08:00
2018-01-26 06:22:56 -08:00
const msgType = "testUpdatePowerTx"
2018-01-15 17:38:56 -08:00
2018-05-23 22:09:01 -07:00
func ( tx testUpdatePowerTx ) Type ( ) string { return msgType }
2018-06-20 12:27:36 -07:00
func ( tx testUpdatePowerTx ) GetMemo ( ) string { return "" }
2018-06-21 15:05:25 -07:00
func ( tx testUpdatePowerTx ) GetMsgs ( ) [ ] sdk . Msg { return [ ] sdk . Msg { tx } }
2018-05-23 22:09:01 -07:00
func ( tx testUpdatePowerTx ) GetSignBytes ( ) [ ] byte { return nil }
func ( tx testUpdatePowerTx ) ValidateBasic ( ) sdk . Error { return nil }
func ( tx testUpdatePowerTx ) GetSigners ( ) [ ] sdk . Address { return nil }
func ( tx testUpdatePowerTx ) GetSignatures ( ) [ ] auth . StdSignature { return nil }
2018-01-06 12:53:31 -08:00
2018-02-17 16:13:22 -08:00
func TestValidatorChange ( t * testing . T ) {
2017-12-20 17:34:51 -08:00
// Create app.
2018-02-16 17:15:38 -08:00
app := newBaseApp ( t . Name ( ) )
2018-02-27 19:23:56 -08:00
capKey := sdk . NewKVStoreKey ( "key" )
app . MountStoresIAVL ( capKey )
2018-01-26 04:19:33 -08:00
app . SetTxDecoder ( func ( txBytes [ ] byte ) ( sdk . Tx , sdk . Error ) {
var ttx testUpdatePowerTx
2018-01-06 12:53:31 -08:00
fromJSON ( txBytes , & ttx )
return ttx , nil
} )
2018-01-15 17:38:56 -08:00
2018-02-14 17:09:00 -08:00
app . SetAnteHandler ( func ( ctx sdk . Context , tx sdk . Tx ) ( newCtx sdk . Context , res sdk . Result , abort bool ) { return } )
2018-01-26 06:22:56 -08:00
app . Router ( ) . AddRoute ( msgType , func ( ctx sdk . Context , msg sdk . Msg ) sdk . Result {
2018-01-06 12:53:31 -08:00
// TODO
2018-01-15 17:38:56 -08:00
return sdk . Result { }
2018-04-02 08:30:30 -07:00
} )
2017-12-20 17:34:51 -08:00
// Load latest state, which should be empty.
2018-02-27 19:23:56 -08:00
err := app . LoadLatestVersion ( capKey )
2018-06-29 18:10:15 -07:00
require . Nil ( t , err )
require . Equal ( t , app . LastBlockHeight ( ) , int64 ( 0 ) )
2017-12-20 17:34:51 -08:00
// Create the validators
var numVals = 3
2017-12-26 17:04:48 -08:00
var valSet = make ( [ ] abci . Validator , numVals )
2017-12-20 17:34:51 -08:00
for i := 0 ; i < numVals ; i ++ {
valSet [ i ] = makeVal ( secret ( i ) )
}
// Initialize the chain
app . InitChain ( abci . RequestInitChain {
2017-12-26 17:04:48 -08:00
Validators : valSet ,
2017-12-20 17:34:51 -08:00
} )
// Simulate the start of a block.
app . BeginBlock ( abci . RequestBeginBlock { } )
// Add 1 to each validator's voting power.
for i , val := range valSet {
2018-01-26 04:19:33 -08:00
tx := testUpdatePowerTx {
2017-12-20 17:34:51 -08:00
Addr : makePubKey ( secret ( i ) ) . Address ( ) ,
NewPower : val . Power + 1 ,
}
txBytes := toJSON ( tx )
res := app . DeliverTx ( txBytes )
2018-06-29 18:10:15 -07:00
require . True ( t , res . IsOK ( ) , "%#v\nABCI log: %s" , res , res . Log )
2017-12-20 17:34:51 -08:00
}
// Simulate the end of a block.
// Get the summary of validator updates.
2017-12-26 17:04:48 -08:00
res := app . EndBlock ( abci . RequestEndBlock { } )
2017-12-20 17:34:51 -08:00
valUpdates := res . ValidatorUpdates
// Assert that validator updates are correct.
for _ , val := range valSet {
2018-06-04 16:42:01 -07:00
pubkey , err := tmtypes . PB2TM . PubKey ( val . PubKey )
2017-12-26 17:04:48 -08:00
// Sanity
2018-06-29 18:10:15 -07:00
require . Nil ( t , err )
2017-12-20 17:34:51 -08:00
// Find matching update and splice it out.
2018-06-04 16:42:01 -07:00
for j := 0 ; j < len ( valUpdates ) ; j ++ {
2017-12-26 17:04:48 -08:00
valUpdate := valUpdates [ j ]
2017-12-20 17:34:51 -08:00
2018-06-04 16:42:01 -07:00
updatePubkey , err := tmtypes . PB2TM . PubKey ( valUpdate . PubKey )
2018-06-29 18:10:15 -07:00
require . Nil ( t , err )
2018-06-04 16:42:01 -07:00
2017-12-20 17:34:51 -08:00
// Matched.
2018-06-04 16:42:01 -07:00
if updatePubkey . Equals ( pubkey ) {
2018-06-29 18:10:15 -07:00
require . Equal ( t , valUpdate . Power , val . Power + 1 )
2017-12-20 17:34:51 -08:00
if j < len ( valUpdates ) - 1 {
// Splice it out.
valUpdates = append ( valUpdates [ : j ] , valUpdates [ j + 1 : ] ... )
}
break
}
// Not matched.
}
}
2018-06-29 18:10:15 -07:00
require . Equal ( t , len ( valUpdates ) , 0 , "Some validator updates were unexpected" )
2017-12-20 17:34:51 -08:00
}
//----------------------------------------
2018-06-21 15:05:25 -07:00
// Use burn and send msg types to test multiple msgs in one tx
type testBurnMsg struct {
Addr sdk . Address
Amount sdk . Coins
}
const msgType3 = "burn"
func ( msg testBurnMsg ) Type ( ) string { return msgType3 }
func ( msg testBurnMsg ) GetSignBytes ( ) [ ] byte {
bz , _ := json . Marshal ( msg )
return bz
}
func ( msg testBurnMsg ) ValidateBasic ( ) sdk . Error {
if msg . Addr == nil {
return sdk . ErrInvalidAddress ( "Cannot use nil as Address" )
}
return nil
}
func ( msg testBurnMsg ) GetSigners ( ) [ ] sdk . Address {
return [ ] sdk . Address { msg . Addr }
}
type testSendMsg struct {
Sender sdk . Address
Receiver sdk . Address
Amount sdk . Coins
}
const msgType4 = "send"
func ( msg testSendMsg ) Type ( ) string { return msgType4 }
func ( msg testSendMsg ) GetSignBytes ( ) [ ] byte {
bz , _ := json . Marshal ( msg )
return bz
}
func ( msg testSendMsg ) ValidateBasic ( ) sdk . Error {
if msg . Sender == nil || msg . Receiver == nil {
return sdk . ErrInvalidAddress ( "Cannot use nil as Address" )
}
return nil
}
func ( msg testSendMsg ) GetSigners ( ) [ ] sdk . Address {
return [ ] sdk . Address { msg . Sender }
}
// Simple Handlers for burn and send
func newHandleBurn ( keeper bank . Keeper ) sdk . Handler {
return func ( ctx sdk . Context , msg sdk . Msg ) sdk . Result {
burnMsg := msg . ( testBurnMsg )
_ , _ , err := keeper . SubtractCoins ( ctx , burnMsg . Addr , burnMsg . Amount )
if err != nil {
return err . Result ( )
}
return sdk . Result { }
}
}
func newHandleSpend ( keeper bank . Keeper ) sdk . Handler {
return func ( ctx sdk . Context , msg sdk . Msg ) sdk . Result {
spendMsg := msg . ( testSendMsg )
_ , _ , err := keeper . SubtractCoins ( ctx , spendMsg . Sender , spendMsg . Amount )
if err != nil {
return err . Result ( )
}
_ , _ , err = keeper . AddCoins ( ctx , spendMsg . Receiver , spendMsg . Amount )
if err != nil {
return err . Result ( )
}
return sdk . Result { }
}
}
// generate a signed transaction
func GenTx ( chainID string , msgs [ ] sdk . Msg , accnums [ ] int64 , seq [ ] int64 , priv ... crypto . PrivKey ) auth . StdTx {
// make the transaction free
fee := auth . StdFee {
sdk . Coins { { "foocoin" , sdk . NewInt ( 0 ) } } ,
100000 ,
}
sigs := make ( [ ] auth . StdSignature , len ( priv ) )
for i , p := range priv {
2018-06-28 17:54:47 -07:00
sig , err := p . Sign ( auth . StdSignBytes ( chainID , accnums [ i ] , seq [ i ] , fee , msgs , "" ) )
// TODO: replace with proper error handling:
if err != nil {
panic ( err )
}
2018-06-21 15:05:25 -07:00
sigs [ i ] = auth . StdSignature {
PubKey : p . PubKey ( ) ,
2018-06-28 17:54:47 -07:00
Signature : sig ,
2018-06-21 15:05:25 -07:00
AccountNumber : accnums [ i ] ,
Sequence : seq [ i ] ,
}
}
return auth . NewStdTx ( msgs , fee , sigs , "" )
}
// spin up simple app for testing
type testApp struct {
* BaseApp
accountMapper auth . AccountMapper
accountKeeper bank . Keeper
}
func newTestApp ( name string ) testApp {
return testApp {
BaseApp : newBaseApp ( name ) ,
}
}
func MakeCodec ( ) * wire . Codec {
cdc := wire . NewCodec ( )
cdc . RegisterInterface ( ( * sdk . Msg ) ( nil ) , nil )
crypto . RegisterAmino ( cdc )
cdc . RegisterInterface ( ( * auth . Account ) ( nil ) , nil )
cdc . RegisterConcrete ( & auth . BaseAccount { } , "cosmos-sdk/BaseAccount" , nil )
return cdc
}
// tests multiple msgs of same type from same address in single tx
func TestMultipleBurn ( t * testing . T ) {
// Create app.
app := newTestApp ( t . Name ( ) )
capKey := sdk . NewKVStoreKey ( "key" )
app . MountStoresIAVL ( capKey )
app . SetTxDecoder ( func ( txBytes [ ] byte ) ( sdk . Tx , sdk . Error ) {
var tx auth . StdTx
fromJSON ( txBytes , & tx )
return tx , nil
} )
err := app . LoadLatestVersion ( capKey )
if err != nil {
panic ( err )
}
app . accountMapper = auth . NewAccountMapper ( app . cdc , capKey , & auth . BaseAccount { } )
app . accountKeeper = bank . NewKeeper ( app . accountMapper )
app . SetAnteHandler ( auth . NewAnteHandler ( app . accountMapper , auth . FeeCollectionKeeper { } ) )
app . Router ( ) .
AddRoute ( "burn" , newHandleBurn ( app . accountKeeper ) ) .
AddRoute ( "send" , newHandleSpend ( app . accountKeeper ) )
app . InitChain ( abci . RequestInitChain { } )
app . BeginBlock ( abci . RequestBeginBlock { } )
// Set chain-id
app . deliverState . ctx = app . deliverState . ctx . WithChainID ( t . Name ( ) )
priv := makePrivKey ( "my secret" )
addr := priv . PubKey ( ) . Address ( )
app . accountKeeper . AddCoins ( app . deliverState . ctx , addr , sdk . Coins { { "foocoin" , sdk . NewInt ( 100 ) } } )
2018-06-29 18:10:15 -07:00
require . Equal ( t , sdk . Coins { { "foocoin" , sdk . NewInt ( 100 ) } } , app . accountKeeper . GetCoins ( app . deliverState . ctx , addr ) , "Balance did not update" )
2018-06-21 15:05:25 -07:00
msg := testBurnMsg { addr , sdk . Coins { { "foocoin" , sdk . NewInt ( 50 ) } } }
tx := GenTx ( t . Name ( ) , [ ] sdk . Msg { msg , msg } , [ ] int64 { 0 } , [ ] int64 { 0 } , priv )
res := app . Deliver ( tx )
2018-06-29 18:10:15 -07:00
require . Equal ( t , true , res . IsOK ( ) , res . Log )
require . Equal ( t , sdk . Coins ( nil ) , app . accountKeeper . GetCoins ( app . deliverState . ctx , addr ) , "Double burn did not work" )
2018-06-21 15:05:25 -07:00
}
// tests multiples msgs of same type from different addresses in single tx
func TestBurnMultipleOwners ( t * testing . T ) {
// Create app.
app := newTestApp ( t . Name ( ) )
capKey := sdk . NewKVStoreKey ( "key" )
app . MountStoresIAVL ( capKey )
app . SetTxDecoder ( func ( txBytes [ ] byte ) ( sdk . Tx , sdk . Error ) {
var tx auth . StdTx
fromJSON ( txBytes , & tx )
return tx , nil
} )
err := app . LoadLatestVersion ( capKey )
if err != nil {
panic ( err )
}
app . accountMapper = auth . NewAccountMapper ( app . cdc , capKey , & auth . BaseAccount { } )
app . accountKeeper = bank . NewKeeper ( app . accountMapper )
app . SetAnteHandler ( auth . NewAnteHandler ( app . accountMapper , auth . FeeCollectionKeeper { } ) )
app . Router ( ) .
AddRoute ( "burn" , newHandleBurn ( app . accountKeeper ) ) .
AddRoute ( "send" , newHandleSpend ( app . accountKeeper ) )
app . InitChain ( abci . RequestInitChain { } )
app . BeginBlock ( abci . RequestBeginBlock { } )
// Set chain-id
app . deliverState . ctx = app . deliverState . ctx . WithChainID ( t . Name ( ) )
priv1 := makePrivKey ( "my secret 1" )
addr1 := priv1 . PubKey ( ) . Address ( )
priv2 := makePrivKey ( "my secret 2" )
addr2 := priv2 . PubKey ( ) . Address ( )
// fund accounts
app . accountKeeper . AddCoins ( app . deliverState . ctx , addr1 , sdk . Coins { { "foocoin" , sdk . NewInt ( 100 ) } } )
app . accountKeeper . AddCoins ( app . deliverState . ctx , addr2 , sdk . Coins { { "foocoin" , sdk . NewInt ( 100 ) } } )
2018-06-29 18:10:15 -07:00
require . Equal ( t , sdk . Coins { { "foocoin" , sdk . NewInt ( 100 ) } } , app . accountKeeper . GetCoins ( app . deliverState . ctx , addr1 ) , "Balance1 did not update" )
require . Equal ( t , sdk . Coins { { "foocoin" , sdk . NewInt ( 100 ) } } , app . accountKeeper . GetCoins ( app . deliverState . ctx , addr2 ) , "Balance2 did not update" )
2018-06-21 15:05:25 -07:00
msg1 := testBurnMsg { addr1 , sdk . Coins { { "foocoin" , sdk . NewInt ( 100 ) } } }
msg2 := testBurnMsg { addr2 , sdk . Coins { { "foocoin" , sdk . NewInt ( 100 ) } } }
// test wrong signers: Address 1 signs both messages
tx := GenTx ( t . Name ( ) , [ ] sdk . Msg { msg1 , msg2 } , [ ] int64 { 0 , 0 } , [ ] int64 { 0 , 0 } , priv1 , priv1 )
res := app . Deliver ( tx )
2018-06-29 18:10:15 -07:00
require . Equal ( t , sdk . ABCICodeType ( 0x10003 ) , res . Code , "Wrong signatures passed" )
2018-06-21 15:05:25 -07:00
2018-06-29 18:10:15 -07:00
require . Equal ( t , sdk . Coins { { "foocoin" , sdk . NewInt ( 100 ) } } , app . accountKeeper . GetCoins ( app . deliverState . ctx , addr1 ) , "Balance1 changed after invalid sig" )
require . Equal ( t , sdk . Coins { { "foocoin" , sdk . NewInt ( 100 ) } } , app . accountKeeper . GetCoins ( app . deliverState . ctx , addr2 ) , "Balance2 changed after invalid sig" )
2018-06-21 15:05:25 -07:00
// test valid tx
tx = GenTx ( t . Name ( ) , [ ] sdk . Msg { msg1 , msg2 } , [ ] int64 { 0 , 1 } , [ ] int64 { 1 , 0 } , priv1 , priv2 )
res = app . Deliver ( tx )
2018-06-29 18:10:15 -07:00
require . Equal ( t , true , res . IsOK ( ) , res . Log )
2018-06-21 15:05:25 -07:00
2018-06-29 18:10:15 -07:00
require . Equal ( t , sdk . Coins ( nil ) , app . accountKeeper . GetCoins ( app . deliverState . ctx , addr1 ) , "Balance1 did not change after valid tx" )
require . Equal ( t , sdk . Coins ( nil ) , app . accountKeeper . GetCoins ( app . deliverState . ctx , addr2 ) , "Balance2 did not change after valid tx" )
2018-06-21 15:05:25 -07:00
}
// tests different msg types in single tx with different addresses
func TestSendBurn ( t * testing . T ) {
// Create app.
app := newTestApp ( t . Name ( ) )
capKey := sdk . NewKVStoreKey ( "key" )
app . MountStoresIAVL ( capKey )
app . SetTxDecoder ( func ( txBytes [ ] byte ) ( sdk . Tx , sdk . Error ) {
var tx auth . StdTx
fromJSON ( txBytes , & tx )
return tx , nil
} )
err := app . LoadLatestVersion ( capKey )
if err != nil {
panic ( err )
}
app . accountMapper = auth . NewAccountMapper ( app . cdc , capKey , & auth . BaseAccount { } )
app . accountKeeper = bank . NewKeeper ( app . accountMapper )
app . SetAnteHandler ( auth . NewAnteHandler ( app . accountMapper , auth . FeeCollectionKeeper { } ) )
app . Router ( ) .
AddRoute ( "burn" , newHandleBurn ( app . accountKeeper ) ) .
AddRoute ( "send" , newHandleSpend ( app . accountKeeper ) )
app . InitChain ( abci . RequestInitChain { } )
app . BeginBlock ( abci . RequestBeginBlock { } )
// Set chain-id
app . deliverState . ctx = app . deliverState . ctx . WithChainID ( t . Name ( ) )
priv1 := makePrivKey ( "my secret 1" )
addr1 := priv1 . PubKey ( ) . Address ( )
priv2 := makePrivKey ( "my secret 2" )
addr2 := priv2 . PubKey ( ) . Address ( )
// fund accounts
app . accountKeeper . AddCoins ( app . deliverState . ctx , addr1 , sdk . Coins { { "foocoin" , sdk . NewInt ( 100 ) } } )
acc := app . accountMapper . NewAccountWithAddress ( app . deliverState . ctx , addr2 )
app . accountMapper . SetAccount ( app . deliverState . ctx , acc )
2018-06-29 18:10:15 -07:00
require . Equal ( t , sdk . Coins { { "foocoin" , sdk . NewInt ( 100 ) } } , app . accountKeeper . GetCoins ( app . deliverState . ctx , addr1 ) , "Balance1 did not update" )
2018-06-21 15:05:25 -07:00
sendMsg := testSendMsg { addr1 , addr2 , sdk . Coins { { "foocoin" , sdk . NewInt ( 50 ) } } }
msg1 := testBurnMsg { addr1 , sdk . Coins { { "foocoin" , sdk . NewInt ( 50 ) } } }
msg2 := testBurnMsg { addr2 , sdk . Coins { { "foocoin" , sdk . NewInt ( 50 ) } } }
// send then burn
tx := GenTx ( t . Name ( ) , [ ] sdk . Msg { sendMsg , msg2 , msg1 } , [ ] int64 { 0 , 1 } , [ ] int64 { 0 , 0 } , priv1 , priv2 )
res := app . Deliver ( tx )
2018-06-29 18:10:15 -07:00
require . Equal ( t , true , res . IsOK ( ) , res . Log )
2018-06-21 15:05:25 -07:00
2018-06-29 18:10:15 -07:00
require . Equal ( t , sdk . Coins ( nil ) , app . accountKeeper . GetCoins ( app . deliverState . ctx , addr1 ) , "Balance1 did not change after valid tx" )
require . Equal ( t , sdk . Coins ( nil ) , app . accountKeeper . GetCoins ( app . deliverState . ctx , addr2 ) , "Balance2 did not change after valid tx" )
2018-06-21 15:05:25 -07:00
// Check that state is only updated if all msgs in tx pass.
app . accountKeeper . AddCoins ( app . deliverState . ctx , addr1 , sdk . Coins { { "foocoin" , sdk . NewInt ( 50 ) } } )
// burn then send
tx = GenTx ( t . Name ( ) , [ ] sdk . Msg { msg1 , sendMsg } , [ ] int64 { 0 } , [ ] int64 { 1 } , priv1 )
res = app . Deliver ( tx )
// Double check that state is correct after Commit.
app . EndBlock ( abci . RequestEndBlock { } )
app . Commit ( )
app . BeginBlock ( abci . RequestBeginBlock { } )
app . deliverState . ctx = app . deliverState . ctx . WithChainID ( t . Name ( ) )
2018-06-29 18:10:15 -07:00
require . Equal ( t , sdk . ABCICodeType ( 0x1000a ) , res . Code , "Allowed tx to pass with insufficient funds" )
2018-06-21 15:05:25 -07:00
2018-06-29 18:10:15 -07:00
require . Equal ( t , sdk . Coins { { "foocoin" , sdk . NewInt ( 50 ) } } , app . accountKeeper . GetCoins ( app . deliverState . ctx , addr1 ) , "Allowed valid msg to pass in invalid tx" )
require . Equal ( t , sdk . Coins ( nil ) , app . accountKeeper . GetCoins ( app . deliverState . ctx , addr2 ) , "Balance2 changed after invalid tx" )
2018-06-21 15:05:25 -07:00
}
//----------------------------------------
2017-12-20 17:34:51 -08:00
func randPower ( ) int64 {
return cmn . RandInt64 ( )
}
2017-12-26 17:04:48 -08:00
func makeVal ( secret string ) abci . Validator {
return abci . Validator {
2018-06-04 16:42:01 -07:00
PubKey : tmtypes . TM2PB . PubKey ( makePubKey ( secret ) ) ,
2017-12-20 17:34:51 -08:00
Power : randPower ( ) ,
}
}
func makePubKey ( secret string ) crypto . PubKey {
return makePrivKey ( secret ) . PubKey ( )
}
func makePrivKey ( secret string ) crypto . PrivKey {
2017-12-26 17:04:48 -08:00
privKey := crypto . GenPrivKeyEd25519FromSecret ( [ ] byte ( secret ) )
2018-04-06 17:25:08 -07:00
return privKey
2017-12-20 17:34:51 -08:00
}
2017-12-26 17:04:48 -08:00
func secret ( index int ) string {
return fmt . Sprintf ( "secret%d" , index )
2017-12-20 17:34:51 -08:00
}
2017-12-26 17:04:48 -08:00
func copyVal ( val abci . Validator ) abci . Validator {
// val2 := *val
// return &val2
return val
2017-12-20 17:34:51 -08:00
}
func toJSON ( o interface { } ) [ ] byte {
2018-06-28 17:54:47 -07:00
bz , err := wire . Cdc . MarshalJSON ( o )
2017-12-20 17:34:51 -08:00
if err != nil {
panic ( err )
}
2017-12-26 17:04:48 -08:00
return bz
2017-12-20 17:34:51 -08:00
}
2017-12-26 17:04:48 -08:00
func fromJSON ( bz [ ] byte , ptr interface { } ) {
2018-06-28 17:54:47 -07:00
err := wire . Cdc . UnmarshalJSON ( bz , ptr )
2017-12-20 17:34:51 -08:00
if err != nil {
panic ( err )
}
}