Move db interfaces to top level
This commit is contained in:
parent
2a3c072cc5
commit
555db84977
|
@ -0,0 +1,46 @@
|
|||
package sdk
|
||||
|
||||
import (
|
||||
"github.com/tendermint/go-wire/data"
|
||||
)
|
||||
|
||||
// KVStore is a simple interface to get/set data
|
||||
type KVStore interface {
|
||||
Set(key, value []byte)
|
||||
Get(key []byte) (value []byte)
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
// Model grabs together key and value to allow easier return values
|
||||
type Model struct {
|
||||
Key data.Bytes
|
||||
Value data.Bytes
|
||||
}
|
||||
|
||||
// SimpleDB allows us to do some basic range queries on a db
|
||||
type SimpleDB interface {
|
||||
KVStore
|
||||
|
||||
Has(key []byte) (has bool)
|
||||
Remove(key []byte) (value []byte) // returns old value if there was one
|
||||
|
||||
// Start is inclusive, End is exclusive...
|
||||
// Thus List ([]byte{12, 13}, []byte{12, 14}) will return anything with
|
||||
// the prefix []byte{12, 13}
|
||||
List(start, end []byte, limit int) []Model
|
||||
First(start, end []byte) Model
|
||||
Last(start, end []byte) Model
|
||||
|
||||
// Checkpoint returns the same state, but where writes
|
||||
// are buffered and don't affect the parent
|
||||
Checkpoint() SimpleDB
|
||||
|
||||
// Commit will take all changes from the checkpoint and write
|
||||
// them to the parent.
|
||||
// Returns an error if this is not a child of this one
|
||||
Commit(SimpleDB) error
|
||||
|
||||
// Discard will remove reference to this
|
||||
Discard()
|
||||
}
|
|
@ -1,9 +1,5 @@
|
|||
package sdk
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/state"
|
||||
)
|
||||
|
||||
// Decorator is anything that wraps another handler
|
||||
// to enhance functionality.
|
||||
//
|
||||
|
@ -15,12 +11,12 @@ type Decorator interface {
|
|||
}
|
||||
|
||||
type DecorateChecker interface {
|
||||
CheckTx(ctx Context, store state.SimpleDB,
|
||||
CheckTx(ctx Context, store SimpleDB,
|
||||
tx interface{}, next Checker) (CheckResult, error)
|
||||
}
|
||||
|
||||
type DecorateDeliverer interface {
|
||||
DeliverTx(ctx Context, store state.SimpleDB, tx interface{},
|
||||
DeliverTx(ctx Context, store SimpleDB, tx interface{},
|
||||
next Deliverer) (DeliverResult, error)
|
||||
}
|
||||
|
||||
|
@ -74,14 +70,14 @@ type decorator struct {
|
|||
var _ Handler = &decorator{}
|
||||
|
||||
// CheckTx fulfils Handler interface
|
||||
func (m *decorator) CheckTx(ctx Context, store state.SimpleDB,
|
||||
func (m *decorator) CheckTx(ctx Context, store SimpleDB,
|
||||
tx interface{}) (CheckResult, error) {
|
||||
|
||||
return m.decorator.CheckTx(ctx, store, tx, m.next)
|
||||
}
|
||||
|
||||
// DeliverTx fulfils Handler interface
|
||||
func (m *decorator) DeliverTx(ctx Context, store state.SimpleDB,
|
||||
func (m *decorator) DeliverTx(ctx Context, store SimpleDB,
|
||||
tx interface{}) (res DeliverResult, err error) {
|
||||
|
||||
return m.decorator.DeliverTx(ctx, store, tx, m.next)
|
||||
|
|
24
handler.go
24
handler.go
|
@ -3,8 +3,6 @@ package sdk
|
|||
import (
|
||||
abci "github.com/tendermint/abci/types"
|
||||
"github.com/tendermint/tmlibs/log"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/state"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -25,25 +23,25 @@ type Handler interface {
|
|||
|
||||
// Checker verifies there are valid fees and estimates work
|
||||
type Checker interface {
|
||||
CheckTx(ctx Context, store state.SimpleDB, tx interface{}) (CheckResult, error)
|
||||
CheckTx(ctx Context, store SimpleDB, tx interface{}) (CheckResult, error)
|
||||
}
|
||||
|
||||
// CheckerFunc (like http.HandlerFunc) is a shortcut for making wrappers
|
||||
type CheckerFunc func(Context, state.SimpleDB, interface{}) (CheckResult, error)
|
||||
type CheckerFunc func(Context, SimpleDB, interface{}) (CheckResult, error)
|
||||
|
||||
func (c CheckerFunc) CheckTx(ctx Context, store state.SimpleDB, tx interface{}) (CheckResult, error) {
|
||||
func (c CheckerFunc) CheckTx(ctx Context, store SimpleDB, tx interface{}) (CheckResult, error) {
|
||||
return c(ctx, store, tx)
|
||||
}
|
||||
|
||||
// Deliverer performs the tx once it makes it in the block
|
||||
type Deliverer interface {
|
||||
DeliverTx(ctx Context, store state.SimpleDB, tx interface{}) (DeliverResult, error)
|
||||
DeliverTx(ctx Context, store SimpleDB, tx interface{}) (DeliverResult, error)
|
||||
}
|
||||
|
||||
// DelivererFunc (like http.HandlerFunc) is a shortcut for making wrappers
|
||||
type DelivererFunc func(Context, state.SimpleDB, interface{}) (DeliverResult, error)
|
||||
type DelivererFunc func(Context, SimpleDB, interface{}) (DeliverResult, error)
|
||||
|
||||
func (c DelivererFunc) DeliverTx(ctx Context, store state.SimpleDB, tx interface{}) (DeliverResult, error) {
|
||||
func (c DelivererFunc) DeliverTx(ctx Context, store SimpleDB, tx interface{}) (DeliverResult, error) {
|
||||
return c(ctx, store, tx)
|
||||
}
|
||||
|
||||
|
@ -53,20 +51,20 @@ func (c DelivererFunc) DeliverTx(ctx Context, store state.SimpleDB, tx interface
|
|||
// Ticker can be executed every block.
|
||||
// Called from BeginBlock
|
||||
type Ticker interface {
|
||||
Tick(Context, state.SimpleDB) ([]*abci.Validator, error)
|
||||
Tick(Context, SimpleDB) ([]*abci.Validator, error)
|
||||
}
|
||||
|
||||
// TickerFunc allows a function to implement the interface
|
||||
type TickerFunc func(Context, state.SimpleDB) ([]*abci.Validator, error)
|
||||
type TickerFunc func(Context, SimpleDB) ([]*abci.Validator, error)
|
||||
|
||||
func (t TickerFunc) Tick(ctx Context, store state.SimpleDB) ([]*abci.Validator, error) {
|
||||
func (t TickerFunc) Tick(ctx Context, store SimpleDB) ([]*abci.Validator, error) {
|
||||
return t(ctx, store)
|
||||
}
|
||||
|
||||
// InitValidator sets the initial validator set.
|
||||
// Called from InitChain
|
||||
type InitValidator interface {
|
||||
InitValidators(logger log.Logger, store state.SimpleDB,
|
||||
InitValidators(logger log.Logger, store SimpleDB,
|
||||
vals []*abci.Validator)
|
||||
}
|
||||
|
||||
|
@ -74,7 +72,7 @@ type InitValidator interface {
|
|||
//
|
||||
// TODO: Think if this belongs here, in genesis, or somewhere else
|
||||
type InitStater interface {
|
||||
InitState(logger log.Logger, store state.SimpleDB,
|
||||
InitState(logger log.Logger, store SimpleDB,
|
||||
module, key, value string) (string, error)
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package state
|
|||
import (
|
||||
"math/rand"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk"
|
||||
"github.com/tendermint/iavl"
|
||||
)
|
||||
|
||||
|
@ -19,7 +20,7 @@ func (b *Bonsai) String() string {
|
|||
return "Bonsai{" + b.Tree.String() + "}"
|
||||
}
|
||||
|
||||
var _ SimpleDB = &Bonsai{}
|
||||
var _ sdk.SimpleDB = &Bonsai{}
|
||||
|
||||
// NewBonsai wraps a merkle tree and tags it to track children
|
||||
func NewBonsai(tree *iavl.VersionedTree) *Bonsai {
|
||||
|
@ -58,10 +59,10 @@ func (b *Bonsai) GetVersionedWithProof(key []byte, version uint64) ([]byte, iavl
|
|||
return b.Tree.GetVersionedWithProof(key, version)
|
||||
}
|
||||
|
||||
func (b *Bonsai) List(start, end []byte, limit int) []Model {
|
||||
res := []Model{}
|
||||
func (b *Bonsai) List(start, end []byte, limit int) []sdk.Model {
|
||||
res := []sdk.Model{}
|
||||
stopAtCount := func(key []byte, value []byte) (stop bool) {
|
||||
m := Model{key, value}
|
||||
m := sdk.Model{key, value}
|
||||
res = append(res, m)
|
||||
return limit > 0 && len(res) >= limit
|
||||
}
|
||||
|
@ -69,31 +70,31 @@ func (b *Bonsai) List(start, end []byte, limit int) []Model {
|
|||
return res
|
||||
}
|
||||
|
||||
func (b *Bonsai) First(start, end []byte) Model {
|
||||
var m Model
|
||||
func (b *Bonsai) First(start, end []byte) sdk.Model {
|
||||
var m sdk.Model
|
||||
stopAtFirst := func(key []byte, value []byte) (stop bool) {
|
||||
m = Model{key, value}
|
||||
m = sdk.Model{key, value}
|
||||
return true
|
||||
}
|
||||
b.Tree.IterateRange(start, end, true, stopAtFirst)
|
||||
return m
|
||||
}
|
||||
|
||||
func (b *Bonsai) Last(start, end []byte) Model {
|
||||
var m Model
|
||||
func (b *Bonsai) Last(start, end []byte) sdk.Model {
|
||||
var m sdk.Model
|
||||
stopAtFirst := func(key []byte, value []byte) (stop bool) {
|
||||
m = Model{key, value}
|
||||
m = sdk.Model{key, value}
|
||||
return true
|
||||
}
|
||||
b.Tree.IterateRange(start, end, false, stopAtFirst)
|
||||
return m
|
||||
}
|
||||
|
||||
func (b *Bonsai) Checkpoint() SimpleDB {
|
||||
func (b *Bonsai) Checkpoint() sdk.SimpleDB {
|
||||
return NewMemKVCache(b)
|
||||
}
|
||||
|
||||
func (b *Bonsai) Commit(sub SimpleDB) error {
|
||||
func (b *Bonsai) Commit(sub sdk.SimpleDB) error {
|
||||
cache, ok := sub.(*MemKVCache)
|
||||
if !ok {
|
||||
return ErrNotASubTransaction()
|
||||
|
@ -115,7 +116,7 @@ func (b *Bonsai) Commit(sub SimpleDB) error {
|
|||
//
|
||||
// FIXME: use this code when iavltree is improved
|
||||
|
||||
// func (b *Bonsai) Checkpoint() SimpleDB {
|
||||
// func (b *Bonsai) Checkpoint() sdk.SimpleDB {
|
||||
// return &Bonsai{
|
||||
// id: b.id,
|
||||
// Tree: b.Tree.Copy(),
|
||||
|
@ -125,7 +126,7 @@ func (b *Bonsai) Commit(sub SimpleDB) error {
|
|||
// // Commit will take all changes from the checkpoint and write
|
||||
// // them to the parent.
|
||||
// // Returns an error if this is not a child of this one
|
||||
// func (b *Bonsai) Commit(sub SimpleDB) error {
|
||||
// func (b *Bonsai) Commit(sub sdk.SimpleDB) error {
|
||||
// bb, ok := sub.(*Bonsai)
|
||||
// if !ok || (b.id != bb.id) {
|
||||
// return ErrNotASubTransaction()
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package state
|
||||
|
||||
import sdk "github.com/cosmos/cosmos-sdk"
|
||||
|
||||
// ChainState maintains general information for the chain
|
||||
type ChainState struct {
|
||||
chainID string
|
||||
|
@ -13,13 +15,13 @@ func NewChainState() *ChainState {
|
|||
var baseChainIDKey = []byte("base/chain_id")
|
||||
|
||||
// SetChainID stores the chain id in the store
|
||||
func (s *ChainState) SetChainID(store KVStore, chainID string) {
|
||||
func (s *ChainState) SetChainID(store sdk.KVStore, chainID string) {
|
||||
s.chainID = chainID
|
||||
store.Set(baseChainIDKey, []byte(chainID))
|
||||
}
|
||||
|
||||
// GetChainID gets the chain id from the cache or the store
|
||||
func (s *ChainState) GetChainID(store KVStore) string {
|
||||
func (s *ChainState) GetChainID(store sdk.KVStore) string {
|
||||
if s.chainID != "" {
|
||||
return s.chainID
|
||||
}
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
package state
|
||||
|
||||
import sdk "github.com/cosmos/cosmos-sdk"
|
||||
|
||||
// MemKVCache is designed to wrap MemKVStore as a cache
|
||||
type MemKVCache struct {
|
||||
store SimpleDB
|
||||
store sdk.SimpleDB
|
||||
cache *MemKVStore
|
||||
}
|
||||
|
||||
var _ SimpleDB = (*MemKVCache)(nil)
|
||||
var _ sdk.SimpleDB = (*MemKVCache)(nil)
|
||||
|
||||
// NewMemKVCache wraps a cache around MemKVStore
|
||||
//
|
||||
// You probably don't want to use directly, but rather
|
||||
// via MemKVCache.Checkpoint()
|
||||
func NewMemKVCache(store SimpleDB) *MemKVCache {
|
||||
func NewMemKVCache(store sdk.SimpleDB) *MemKVCache {
|
||||
if store == nil {
|
||||
panic("wtf")
|
||||
}
|
||||
|
@ -53,7 +55,7 @@ func (c *MemKVCache) Remove(key []byte) (value []byte) {
|
|||
}
|
||||
|
||||
// List is also inefficiently implemented...
|
||||
func (c *MemKVCache) List(start, end []byte, limit int) []Model {
|
||||
func (c *MemKVCache) List(start, end []byte, limit int) []sdk.Model {
|
||||
orig := c.store.List(start, end, 0)
|
||||
cached := c.cache.List(start, end, 0)
|
||||
keys := c.combineLists(orig, cached)
|
||||
|
@ -69,7 +71,7 @@ func (c *MemKVCache) List(start, end []byte, limit int) []Model {
|
|||
return keys
|
||||
}
|
||||
|
||||
func (c *MemKVCache) combineLists(orig, cache []Model) []Model {
|
||||
func (c *MemKVCache) combineLists(orig, cache []sdk.Model) []sdk.Model {
|
||||
store := NewMemKVStore()
|
||||
for _, m := range orig {
|
||||
store.Set(m.Key, m.Value)
|
||||
|
@ -86,33 +88,33 @@ func (c *MemKVCache) combineLists(orig, cache []Model) []Model {
|
|||
}
|
||||
|
||||
// First is done with List, but could be much more efficient
|
||||
func (c *MemKVCache) First(start, end []byte) Model {
|
||||
func (c *MemKVCache) First(start, end []byte) sdk.Model {
|
||||
data := c.List(start, end, 0)
|
||||
if len(data) == 0 {
|
||||
return Model{}
|
||||
return sdk.Model{}
|
||||
}
|
||||
return data[0]
|
||||
}
|
||||
|
||||
// Last is done with List, but could be much more efficient
|
||||
func (c *MemKVCache) Last(start, end []byte) Model {
|
||||
func (c *MemKVCache) Last(start, end []byte) sdk.Model {
|
||||
data := c.List(start, end, 0)
|
||||
if len(data) == 0 {
|
||||
return Model{}
|
||||
return sdk.Model{}
|
||||
}
|
||||
return data[len(data)-1]
|
||||
}
|
||||
|
||||
// Checkpoint returns the same state, but where writes
|
||||
// are buffered and don't affect the parent
|
||||
func (c *MemKVCache) Checkpoint() SimpleDB {
|
||||
func (c *MemKVCache) Checkpoint() sdk.SimpleDB {
|
||||
return NewMemKVCache(c)
|
||||
}
|
||||
|
||||
// Commit will take all changes from the checkpoint and write
|
||||
// them to the parent.
|
||||
// Returns an error if this is not a child of this one
|
||||
func (c *MemKVCache) Commit(sub SimpleDB) error {
|
||||
func (c *MemKVCache) Commit(sub sdk.SimpleDB) error {
|
||||
cache, ok := sub.(*MemKVCache)
|
||||
if !ok {
|
||||
return ErrNotASubTransaction()
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
@ -11,47 +12,47 @@ func TestCache(t *testing.T) {
|
|||
assert := assert.New(t)
|
||||
|
||||
cases := []struct {
|
||||
init []Model
|
||||
toGet []Model
|
||||
init []sdk.Model
|
||||
toGet []sdk.Model
|
||||
toList []listQuery
|
||||
|
||||
setCache []Model
|
||||
removeCache []Model
|
||||
getCache []Model
|
||||
setCache []sdk.Model
|
||||
removeCache []sdk.Model
|
||||
getCache []sdk.Model
|
||||
listCache []listQuery
|
||||
}{
|
||||
// simple add
|
||||
{
|
||||
init: []Model{m("a", "1"), m("c", "2")},
|
||||
toGet: []Model{m("a", "1"), m("c", "2"), m("d", "")},
|
||||
init: []sdk.Model{m("a", "1"), m("c", "2")},
|
||||
toGet: []sdk.Model{m("a", "1"), m("c", "2"), m("d", "")},
|
||||
toList: []listQuery{{
|
||||
"a", "e", 0,
|
||||
[]Model{m("a", "1"), m("c", "2")},
|
||||
[]sdk.Model{m("a", "1"), m("c", "2")},
|
||||
m("c", "2"),
|
||||
}},
|
||||
setCache: []Model{m("d", "3")},
|
||||
removeCache: []Model{m("a", "1")},
|
||||
getCache: []Model{m("a", ""), m("c", "2"), m("d", "3")},
|
||||
setCache: []sdk.Model{m("d", "3")},
|
||||
removeCache: []sdk.Model{m("a", "1")},
|
||||
getCache: []sdk.Model{m("a", ""), m("c", "2"), m("d", "3")},
|
||||
listCache: []listQuery{{
|
||||
"a", "e", 0,
|
||||
[]Model{m("c", "2"), m("d", "3")},
|
||||
[]sdk.Model{m("c", "2"), m("d", "3")},
|
||||
m("d", "3"),
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
checkGet := func(db SimpleDB, m Model, msg string) {
|
||||
checkGet := func(db sdk.SimpleDB, m sdk.Model, msg string) {
|
||||
val := db.Get(m.Key)
|
||||
assert.EqualValues(m.Value, val, msg)
|
||||
has := db.Has(m.Key)
|
||||
assert.Equal(len(m.Value) != 0, has, msg)
|
||||
}
|
||||
|
||||
checkList := func(db SimpleDB, lq listQuery, msg string) {
|
||||
checkList := func(db sdk.SimpleDB, lq listQuery, msg string) {
|
||||
start, end := []byte(lq.start), []byte(lq.end)
|
||||
list := db.List(start, end, lq.limit)
|
||||
if assert.EqualValues(lq.expected, list, msg) {
|
||||
var first Model
|
||||
var first sdk.Model
|
||||
if len(lq.expected) > 0 {
|
||||
first = lq.expected[0]
|
||||
}
|
||||
|
|
|
@ -3,60 +3,19 @@ package state
|
|||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/tendermint/go-wire/data"
|
||||
sdk "github.com/cosmos/cosmos-sdk"
|
||||
)
|
||||
|
||||
// KVStore is a simple interface to get/set data
|
||||
type KVStore interface {
|
||||
Set(key, value []byte)
|
||||
Get(key []byte) (value []byte)
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
// Model grabs together key and value to allow easier return values
|
||||
type Model struct {
|
||||
Key data.Bytes
|
||||
Value data.Bytes
|
||||
}
|
||||
|
||||
// SimpleDB allows us to do some basic range queries on a db
|
||||
type SimpleDB interface {
|
||||
KVStore
|
||||
|
||||
Has(key []byte) (has bool)
|
||||
Remove(key []byte) (value []byte) // returns old value if there was one
|
||||
|
||||
// Start is inclusive, End is exclusive...
|
||||
// Thus List ([]byte{12, 13}, []byte{12, 14}) will return anything with
|
||||
// the prefix []byte{12, 13}
|
||||
List(start, end []byte, limit int) []Model
|
||||
First(start, end []byte) Model
|
||||
Last(start, end []byte) Model
|
||||
|
||||
// Checkpoint returns the same state, but where writes
|
||||
// are buffered and don't affect the parent
|
||||
Checkpoint() SimpleDB
|
||||
|
||||
// Commit will take all changes from the checkpoint and write
|
||||
// them to the parent.
|
||||
// Returns an error if this is not a child of this one
|
||||
Commit(SimpleDB) error
|
||||
|
||||
// Discard will remove reference to this
|
||||
Discard()
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
// MemKVStore is a simple implementation of SimpleDB.
|
||||
// MemKVStore is a simple implementation of sdk.SimpleDB.
|
||||
// It is only intended for quick testing, not to be used
|
||||
// in production or with large data stores.
|
||||
type MemKVStore struct {
|
||||
m map[string][]byte
|
||||
}
|
||||
|
||||
var _ SimpleDB = NewMemKVStore()
|
||||
var _ sdk.SimpleDB = NewMemKVStore()
|
||||
|
||||
// NewMemKVStore initializes a MemKVStore
|
||||
func NewMemKVStore() *MemKVStore {
|
||||
|
@ -84,7 +43,7 @@ func (m *MemKVStore) Remove(key []byte) (value []byte) {
|
|||
return val
|
||||
}
|
||||
|
||||
func (m *MemKVStore) List(start, end []byte, limit int) []Model {
|
||||
func (m *MemKVStore) List(start, end []byte, limit int) []sdk.Model {
|
||||
keys := m.keysInRange(start, end)
|
||||
if limit > 0 && len(keys) > 0 {
|
||||
if limit > len(keys) {
|
||||
|
@ -93,9 +52,9 @@ func (m *MemKVStore) List(start, end []byte, limit int) []Model {
|
|||
keys = keys[:limit]
|
||||
}
|
||||
|
||||
res := make([]Model, len(keys))
|
||||
res := make([]sdk.Model, len(keys))
|
||||
for i, k := range keys {
|
||||
res[i] = Model{
|
||||
res[i] = sdk.Model{
|
||||
Key: []byte(k),
|
||||
Value: m.m[k],
|
||||
}
|
||||
|
@ -104,7 +63,7 @@ func (m *MemKVStore) List(start, end []byte, limit int) []Model {
|
|||
}
|
||||
|
||||
// First iterates through all keys to find the one that matches
|
||||
func (m *MemKVStore) First(start, end []byte) Model {
|
||||
func (m *MemKVStore) First(start, end []byte) sdk.Model {
|
||||
key := ""
|
||||
for _, k := range m.keysInRange(start, end) {
|
||||
if key == "" || k < key {
|
||||
|
@ -112,15 +71,15 @@ func (m *MemKVStore) First(start, end []byte) Model {
|
|||
}
|
||||
}
|
||||
if key == "" {
|
||||
return Model{}
|
||||
return sdk.Model{}
|
||||
}
|
||||
return Model{
|
||||
return sdk.Model{
|
||||
Key: []byte(key),
|
||||
Value: m.m[key],
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MemKVStore) Last(start, end []byte) Model {
|
||||
func (m *MemKVStore) Last(start, end []byte) sdk.Model {
|
||||
key := ""
|
||||
for _, k := range m.keysInRange(start, end) {
|
||||
if key == "" || k > key {
|
||||
|
@ -128,9 +87,9 @@ func (m *MemKVStore) Last(start, end []byte) Model {
|
|||
}
|
||||
}
|
||||
if key == "" {
|
||||
return Model{}
|
||||
return sdk.Model{}
|
||||
}
|
||||
return Model{
|
||||
return sdk.Model{
|
||||
Key: []byte(key),
|
||||
Value: m.m[key],
|
||||
}
|
||||
|
@ -140,11 +99,11 @@ func (m *MemKVStore) Discard() {
|
|||
m.m = make(map[string][]byte, 0)
|
||||
}
|
||||
|
||||
func (m *MemKVStore) Checkpoint() SimpleDB {
|
||||
func (m *MemKVStore) Checkpoint() sdk.SimpleDB {
|
||||
return NewMemKVCache(m)
|
||||
}
|
||||
|
||||
func (m *MemKVStore) Commit(sub SimpleDB) error {
|
||||
func (m *MemKVStore) Commit(sub sdk.SimpleDB) error {
|
||||
cache, ok := sub.(*MemKVCache)
|
||||
if !ok {
|
||||
return ErrNotASubTransaction()
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
package state
|
||||
|
||||
import "github.com/tendermint/iavl"
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk"
|
||||
"github.com/tendermint/iavl"
|
||||
)
|
||||
|
||||
// State represents the app states, separating the commited state (for queries)
|
||||
// from the working state (for CheckTx and AppendTx)
|
||||
type State struct {
|
||||
committed *Bonsai
|
||||
deliverTx SimpleDB
|
||||
checkTx SimpleDB
|
||||
deliverTx sdk.SimpleDB
|
||||
checkTx sdk.SimpleDB
|
||||
historySize uint64
|
||||
}
|
||||
|
||||
|
@ -42,13 +45,13 @@ func (s State) Committed() *Bonsai {
|
|||
|
||||
// Append gives us read-write access to the current working
|
||||
// state (to be committed at EndBlock)
|
||||
func (s State) Append() SimpleDB {
|
||||
func (s State) Append() sdk.SimpleDB {
|
||||
return s.deliverTx
|
||||
}
|
||||
|
||||
// Append gives us read-write access to the current scratch
|
||||
// state (to be reset at EndBlock)
|
||||
func (s State) Check() SimpleDB {
|
||||
func (s State) Check() sdk.SimpleDB {
|
||||
return s.checkTx
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package state
|
||||
|
||||
import "encoding/binary"
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk"
|
||||
)
|
||||
|
||||
var (
|
||||
headKey = []byte("h")
|
||||
|
@ -25,7 +29,7 @@ func QueueItemKey(i uint64) []byte {
|
|||
|
||||
// Queue allows us to fill up a range of the db, and grab from either end
|
||||
type Queue struct {
|
||||
store KVStore
|
||||
store sdk.KVStore
|
||||
head uint64 // if Size() > 0, the first element is here
|
||||
tail uint64 // this is the first empty slot to Push() to
|
||||
}
|
||||
|
@ -33,7 +37,7 @@ type Queue struct {
|
|||
// NewQueue will load or initialize a queue in this state-space
|
||||
//
|
||||
// Generally, you will want to stack.PrefixStore() the space first
|
||||
func NewQueue(store KVStore) *Queue {
|
||||
func NewQueue(store sdk.KVStore) *Queue {
|
||||
q := &Queue{store: store}
|
||||
q.head = q.getCount(headKey)
|
||||
q.tail = q.getCount(tailKey)
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"sort"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
)
|
||||
|
||||
|
@ -18,14 +19,14 @@ func SetKey() []byte {
|
|||
// If we had full access to the IAVL tree, this would be completely
|
||||
// trivial and redundant
|
||||
type Set struct {
|
||||
store KVStore
|
||||
store sdk.KVStore
|
||||
keys KeyList
|
||||
}
|
||||
|
||||
var _ KVStore = &Set{}
|
||||
var _ sdk.KVStore = &Set{}
|
||||
|
||||
// NewSet loads or initializes a span of keys
|
||||
func NewSet(store KVStore) *Set {
|
||||
func NewSet(store sdk.KVStore) *Set {
|
||||
s := &Set{store: store}
|
||||
s.loadKeys()
|
||||
return s
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package state
|
||||
|
||||
import wire "github.com/tendermint/go-wire"
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
)
|
||||
|
||||
var (
|
||||
keys = []byte("keys")
|
||||
|
@ -16,13 +19,13 @@ var (
|
|||
//
|
||||
// TODO: doesn't handle deleting....
|
||||
type Span struct {
|
||||
store KVStore
|
||||
store sdk.KVStore
|
||||
// keys is sorted ascending and cannot contain duplicates
|
||||
keys []uint64
|
||||
}
|
||||
|
||||
// NewSpan loads or initializes a span of keys
|
||||
func NewSpan(store KVStore) *Span {
|
||||
func NewSpan(store sdk.KVStore) *Span {
|
||||
s := &Span{store: store}
|
||||
s.loadKeys()
|
||||
return s
|
||||
|
|
|
@ -4,13 +4,14 @@ import (
|
|||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/tendermint/iavl"
|
||||
dbm "github.com/tendermint/tmlibs/db"
|
||||
)
|
||||
|
||||
func GetDBs() []SimpleDB {
|
||||
func GetDBs() []sdk.SimpleDB {
|
||||
// tree with persistence....
|
||||
tmpDir, err := ioutil.TempDir("", "state-tests")
|
||||
if err != nil {
|
||||
|
@ -19,7 +20,7 @@ func GetDBs() []SimpleDB {
|
|||
db := dbm.NewDB("test-get-dbs", dbm.LevelDBBackendStr, tmpDir)
|
||||
persist := iavl.NewVersionedTree(500, db)
|
||||
|
||||
return []SimpleDB{
|
||||
return []sdk.SimpleDB{
|
||||
NewMemKVStore(),
|
||||
NewBonsai(iavl.NewVersionedTree(0, dbm.NewMemDB())),
|
||||
NewBonsai(persist),
|
||||
|
@ -33,8 +34,8 @@ func b(k string) []byte {
|
|||
return []byte(k)
|
||||
}
|
||||
|
||||
func m(k, v string) Model {
|
||||
return Model{
|
||||
func m(k, v string) sdk.Model {
|
||||
return sdk.Model{
|
||||
Key: b(k),
|
||||
Value: b(v),
|
||||
}
|
||||
|
@ -45,9 +46,9 @@ type listQuery struct {
|
|||
start, end string
|
||||
limit int
|
||||
// expected result from List, first element also expected for First
|
||||
expected []Model
|
||||
expected []sdk.Model
|
||||
// expected result from Last
|
||||
last Model
|
||||
last sdk.Model
|
||||
}
|
||||
|
||||
// TestKVStore makes sure that get/set/remove operations work,
|
||||
|
@ -56,39 +57,39 @@ func TestKVStore(t *testing.T) {
|
|||
assert := assert.New(t)
|
||||
|
||||
cases := []struct {
|
||||
toSet []Model
|
||||
toRemove []Model
|
||||
toGet []Model
|
||||
toSet []sdk.Model
|
||||
toRemove []sdk.Model
|
||||
toGet []sdk.Model
|
||||
toList []listQuery
|
||||
}{
|
||||
// simple add
|
||||
{
|
||||
toSet: []Model{m("a", "b"), m("c", "d")},
|
||||
toSet: []sdk.Model{m("a", "b"), m("c", "d")},
|
||||
toRemove: nil,
|
||||
toGet: []Model{m("a", "b")},
|
||||
toGet: []sdk.Model{m("a", "b")},
|
||||
toList: []listQuery{
|
||||
{
|
||||
"a", "d", 0,
|
||||
[]Model{m("a", "b"), m("c", "d")},
|
||||
[]sdk.Model{m("a", "b"), m("c", "d")},
|
||||
m("c", "d"),
|
||||
},
|
||||
{
|
||||
"a", "c", 10,
|
||||
[]Model{m("a", "b")},
|
||||
[]sdk.Model{m("a", "b")},
|
||||
m("a", "b"),
|
||||
},
|
||||
},
|
||||
},
|
||||
// over-write data, remove
|
||||
{
|
||||
toSet: []Model{
|
||||
toSet: []sdk.Model{
|
||||
m("a", "1"),
|
||||
m("b", "2"),
|
||||
m("c", "3"),
|
||||
m("b", "4"),
|
||||
},
|
||||
toRemove: []Model{m("c", "3")},
|
||||
toGet: []Model{
|
||||
toRemove: []sdk.Model{m("c", "3")},
|
||||
toGet: []sdk.Model{
|
||||
m("a", "1"),
|
||||
m("b", "4"),
|
||||
m("c", ""),
|
||||
|
@ -96,17 +97,17 @@ func TestKVStore(t *testing.T) {
|
|||
toList: []listQuery{
|
||||
{
|
||||
"0d", "h", 1,
|
||||
[]Model{m("a", "1")},
|
||||
[]sdk.Model{m("a", "1")},
|
||||
m("b", "4"),
|
||||
},
|
||||
{
|
||||
"ad", "ak", 10,
|
||||
[]Model{},
|
||||
Model{},
|
||||
[]sdk.Model{},
|
||||
sdk.Model{},
|
||||
},
|
||||
{
|
||||
"ad", "k", 0,
|
||||
[]Model{m("b", "4")},
|
||||
[]sdk.Model{m("b", "4")},
|
||||
m("b", "4"),
|
||||
},
|
||||
},
|
||||
|
@ -132,7 +133,7 @@ func TestKVStore(t *testing.T) {
|
|||
start, end := []byte(lq.start), []byte(lq.end)
|
||||
list := db.List(start, end, lq.limit)
|
||||
if assert.EqualValues(lq.expected, list, "%d/%d/%d", i, j, k) {
|
||||
var first Model
|
||||
var first sdk.Model
|
||||
if len(lq.expected) > 0 {
|
||||
first = lq.expected[0]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue