2018-01-29 14:09:14 -08:00
|
|
|
package types_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
2019-06-18 15:11:31 -07:00
|
|
|
"time"
|
2018-01-29 14:09:14 -08:00
|
|
|
|
2018-05-01 05:00:23 -07:00
|
|
|
"github.com/stretchr/testify/require"
|
2018-04-10 08:04:27 -07:00
|
|
|
|
2018-07-02 13:34:06 -07:00
|
|
|
"github.com/tendermint/tendermint/libs/log"
|
2019-08-02 06:20:39 -07:00
|
|
|
dbm "github.com/tendermint/tm-db"
|
2018-04-10 08:04:27 -07:00
|
|
|
|
2018-12-10 06:27:25 -08:00
|
|
|
abci "github.com/tendermint/tendermint/abci/types"
|
|
|
|
|
2019-06-18 15:11:31 -07:00
|
|
|
"github.com/tendermint/tendermint/crypto/secp256k1"
|
|
|
|
|
2018-04-10 08:04:27 -07:00
|
|
|
"github.com/cosmos/cosmos-sdk/store"
|
2018-01-29 14:09:14 -08:00
|
|
|
"github.com/cosmos/cosmos-sdk/types"
|
|
|
|
)
|
|
|
|
|
2018-05-01 05:00:23 -07:00
|
|
|
type MockLogger struct {
|
|
|
|
logs *[]string
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewMockLogger() MockLogger {
|
|
|
|
logs := make([]string, 0)
|
|
|
|
return MockLogger{
|
|
|
|
&logs,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l MockLogger) Debug(msg string, kvs ...interface{}) {
|
|
|
|
*l.logs = append(*l.logs, msg)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l MockLogger) Info(msg string, kvs ...interface{}) {
|
|
|
|
*l.logs = append(*l.logs, msg)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l MockLogger) Error(msg string, kvs ...interface{}) {
|
|
|
|
*l.logs = append(*l.logs, msg)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l MockLogger) With(kvs ...interface{}) log.Logger {
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2018-04-10 08:04:27 -07:00
|
|
|
func defaultContext(key types.StoreKey) types.Context {
|
|
|
|
db := dbm.NewMemDB()
|
|
|
|
cms := store.NewCommitMultiStore(db)
|
|
|
|
cms.MountStoreWithDB(key, types.StoreTypeIAVL, db)
|
|
|
|
cms.LoadLatestVersion()
|
2018-06-21 18:03:05 -07:00
|
|
|
ctx := types.NewContext(cms, abci.Header{}, false, log.NewNopLogger())
|
2018-04-10 08:04:27 -07:00
|
|
|
return ctx
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCacheContext(t *testing.T) {
|
|
|
|
key := types.NewKVStoreKey(t.Name())
|
|
|
|
k1 := []byte("hello")
|
|
|
|
v1 := []byte("world")
|
|
|
|
k2 := []byte("key")
|
|
|
|
v2 := []byte("value")
|
|
|
|
|
|
|
|
ctx := defaultContext(key)
|
|
|
|
store := ctx.KVStore(key)
|
|
|
|
store.Set(k1, v1)
|
2018-06-29 18:10:15 -07:00
|
|
|
require.Equal(t, v1, store.Get(k1))
|
|
|
|
require.Nil(t, store.Get(k2))
|
2018-04-10 08:04:27 -07:00
|
|
|
|
|
|
|
cctx, write := ctx.CacheContext()
|
|
|
|
cstore := cctx.KVStore(key)
|
2018-06-29 18:10:15 -07:00
|
|
|
require.Equal(t, v1, cstore.Get(k1))
|
|
|
|
require.Nil(t, cstore.Get(k2))
|
2018-04-10 08:04:27 -07:00
|
|
|
|
|
|
|
cstore.Set(k2, v2)
|
2018-06-29 18:10:15 -07:00
|
|
|
require.Equal(t, v2, cstore.Get(k2))
|
|
|
|
require.Nil(t, store.Get(k2))
|
2018-04-10 08:04:27 -07:00
|
|
|
|
|
|
|
write()
|
|
|
|
|
2018-06-29 18:10:15 -07:00
|
|
|
require.Equal(t, v2, store.Get(k2))
|
2018-04-10 08:04:27 -07:00
|
|
|
}
|
2018-04-25 04:30:58 -07:00
|
|
|
|
|
|
|
func TestLogContext(t *testing.T) {
|
|
|
|
key := types.NewKVStoreKey(t.Name())
|
|
|
|
ctx := defaultContext(key)
|
2018-05-01 05:00:23 -07:00
|
|
|
logger := NewMockLogger()
|
|
|
|
ctx = ctx.WithLogger(logger)
|
2018-04-25 04:30:58 -07:00
|
|
|
ctx.Logger().Debug("debug")
|
|
|
|
ctx.Logger().Info("info")
|
|
|
|
ctx.Logger().Error("error")
|
2018-05-01 05:00:23 -07:00
|
|
|
require.Equal(t, *logger.logs, []string{"debug", "info", "error"})
|
2018-04-25 04:30:58 -07:00
|
|
|
}
|
2018-08-06 12:00:49 -07:00
|
|
|
|
|
|
|
type dummy int64
|
|
|
|
|
|
|
|
func (d dummy) Clone() interface{} {
|
|
|
|
return d
|
|
|
|
}
|
|
|
|
|
|
|
|
// Testing saving/loading sdk type values to/from the context
|
|
|
|
func TestContextWithCustom(t *testing.T) {
|
|
|
|
var ctx types.Context
|
|
|
|
require.True(t, ctx.IsZero())
|
|
|
|
|
|
|
|
header := abci.Header{}
|
|
|
|
height := int64(1)
|
|
|
|
chainid := "chainid"
|
|
|
|
ischeck := true
|
|
|
|
txbytes := []byte("txbytes")
|
|
|
|
logger := NewMockLogger()
|
2018-10-03 08:48:23 -07:00
|
|
|
voteinfos := []abci.VoteInfo{{}}
|
2018-08-06 12:00:49 -07:00
|
|
|
meter := types.NewGasMeter(10000)
|
2019-02-15 07:33:23 -08:00
|
|
|
minGasPrices := types.DecCoins{types.NewInt64DecCoin("feetoken", 1)}
|
2018-08-06 12:00:49 -07:00
|
|
|
|
2018-10-14 17:37:06 -07:00
|
|
|
ctx = types.NewContext(nil, header, ischeck, logger)
|
|
|
|
require.Equal(t, header, ctx.BlockHeader())
|
|
|
|
|
|
|
|
ctx = ctx.
|
2018-08-06 12:00:49 -07:00
|
|
|
WithBlockHeight(height).
|
|
|
|
WithChainID(chainid).
|
|
|
|
WithTxBytes(txbytes).
|
2018-10-03 08:48:23 -07:00
|
|
|
WithVoteInfos(voteinfos).
|
2018-09-19 08:25:52 -07:00
|
|
|
WithGasMeter(meter).
|
2019-01-18 08:45:20 -08:00
|
|
|
WithMinGasPrices(minGasPrices)
|
2018-08-06 12:00:49 -07:00
|
|
|
require.Equal(t, height, ctx.BlockHeight())
|
|
|
|
require.Equal(t, chainid, ctx.ChainID())
|
2018-09-19 08:25:52 -07:00
|
|
|
require.Equal(t, ischeck, ctx.IsCheckTx())
|
2018-08-06 12:00:49 -07:00
|
|
|
require.Equal(t, txbytes, ctx.TxBytes())
|
|
|
|
require.Equal(t, logger, ctx.Logger())
|
2018-10-03 08:48:23 -07:00
|
|
|
require.Equal(t, voteinfos, ctx.VoteInfos())
|
2018-08-06 12:00:49 -07:00
|
|
|
require.Equal(t, meter, ctx.GasMeter())
|
2019-01-18 08:45:20 -08:00
|
|
|
require.Equal(t, minGasPrices, ctx.MinGasPrices())
|
2018-08-06 12:00:49 -07:00
|
|
|
}
|
2019-06-18 15:11:31 -07:00
|
|
|
|
|
|
|
// Testing saving/loading of header fields to/from the context
|
|
|
|
func TestContextHeader(t *testing.T) {
|
|
|
|
var ctx types.Context
|
|
|
|
|
|
|
|
height := int64(5)
|
|
|
|
time := time.Now()
|
|
|
|
addr := secp256k1.GenPrivKey().PubKey().Address()
|
|
|
|
proposer := types.ConsAddress(addr)
|
|
|
|
|
|
|
|
ctx = types.NewContext(nil, abci.Header{}, false, nil)
|
|
|
|
|
|
|
|
ctx = ctx.
|
|
|
|
WithBlockHeight(height).
|
|
|
|
WithBlockTime(time).
|
|
|
|
WithProposer(proposer)
|
|
|
|
require.Equal(t, height, ctx.BlockHeight())
|
|
|
|
require.Equal(t, height, ctx.BlockHeader().Height)
|
2019-07-16 06:40:42 -07:00
|
|
|
require.Equal(t, time.UTC(), ctx.BlockHeader().Time)
|
2019-06-18 15:11:31 -07:00
|
|
|
require.Equal(t, proposer.Bytes(), ctx.BlockHeader().ProposerAddress)
|
|
|
|
}
|
2019-07-16 06:40:42 -07:00
|
|
|
|
|
|
|
func TestContextHeaderClone(t *testing.T) {
|
|
|
|
cases := map[string]struct {
|
|
|
|
h abci.Header
|
|
|
|
}{
|
|
|
|
"empty": {
|
|
|
|
h: abci.Header{},
|
|
|
|
},
|
|
|
|
"height": {
|
|
|
|
h: abci.Header{
|
|
|
|
Height: 77,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"time": {
|
|
|
|
h: abci.Header{
|
|
|
|
Time: time.Unix(12345677, 12345),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"zero time": {
|
|
|
|
h: abci.Header{
|
|
|
|
Time: time.Unix(0, 0),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"many items": {
|
|
|
|
h: abci.Header{
|
|
|
|
Height: 823,
|
|
|
|
Time: time.Unix(9999999999, 0),
|
|
|
|
ChainID: "silly-demo",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"many items with hash": {
|
|
|
|
h: abci.Header{
|
|
|
|
Height: 823,
|
|
|
|
Time: time.Unix(9999999999, 0),
|
|
|
|
ChainID: "silly-demo",
|
|
|
|
AppHash: []byte{5, 34, 11, 3, 23},
|
|
|
|
ConsensusHash: []byte{11, 3, 23, 87, 3, 1},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for name, tc := range cases {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
ctx := types.NewContext(nil, tc.h, false, nil)
|
|
|
|
require.Equal(t, tc.h.Height, ctx.BlockHeight())
|
|
|
|
require.Equal(t, tc.h.Time.UTC(), ctx.BlockTime())
|
|
|
|
|
|
|
|
// update only changes one field
|
|
|
|
var newHeight int64 = 17
|
|
|
|
ctx = ctx.WithBlockHeight(newHeight)
|
|
|
|
require.Equal(t, newHeight, ctx.BlockHeight())
|
|
|
|
require.Equal(t, tc.h.Time.UTC(), ctx.BlockTime())
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|