cosmos-sdk/state/state.go

117 lines
2.6 KiB
Go
Raw Normal View History

2016-03-20 03:00:43 -07:00
package state
import (
2017-01-14 20:42:47 -08:00
abci "github.com/tendermint/abci/types"
2016-03-20 03:00:43 -07:00
"github.com/tendermint/basecoin/types"
2016-03-22 13:07:03 -07:00
. "github.com/tendermint/go-common"
2016-03-20 03:00:43 -07:00
"github.com/tendermint/go-wire"
2017-01-12 17:49:51 -08:00
eyes "github.com/tendermint/merkleeyes/client"
2016-03-20 03:00:43 -07:00
)
2016-05-01 13:52:08 -07:00
// CONTRACT: State should be quick to copy.
// See CacheWrap().
2016-03-20 03:00:43 -07:00
type State struct {
chainID string
store types.KVStore
readCache map[string][]byte // optional, for caching writes to store
writeCache *types.KVCache // optional, for caching writes w/o writing to store
2016-03-20 03:00:43 -07:00
}
2016-05-01 13:52:08 -07:00
func NewState(store types.KVStore) *State {
return &State{
chainID: "",
store: store,
readCache: make(map[string][]byte),
writeCache: nil,
2016-03-20 03:00:43 -07:00
}
}
2016-03-22 13:07:03 -07:00
func (s *State) SetChainID(chainID string) {
s.chainID = chainID
2017-03-14 14:28:49 -07:00
s.store.Set([]byte("base/chain_id"), []byte(chainID))
2016-03-22 13:07:03 -07:00
}
func (s *State) GetChainID() string {
2017-03-14 14:28:49 -07:00
if s.chainID != "" {
return s.chainID
2016-03-22 13:07:03 -07:00
}
2017-03-14 14:28:49 -07:00
s.chainID = string(s.store.Get([]byte("base/chain_id")))
2016-03-22 10:13:34 -07:00
return s.chainID
}
2016-05-01 13:52:08 -07:00
func (s *State) Get(key []byte) (value []byte) {
if s.readCache != nil { //if not a cachewrap
value, ok := s.readCache[string(key)]
if ok {
return value
}
}
2016-05-01 13:52:08 -07:00
return s.store.Get(key)
}
func (s *State) Set(key []byte, value []byte) {
if s.readCache != nil { //if not a cachewrap
s.readCache[string(key)] = value
}
2016-05-01 13:52:08 -07:00
s.store.Set(key, value)
}
2016-03-20 03:00:43 -07:00
func (s *State) GetAccount(addr []byte) *types.Account {
return GetAccount(s, addr)
2016-03-20 03:00:43 -07:00
}
2016-04-17 12:41:26 -07:00
func (s *State) SetAccount(addr []byte, acc *types.Account) {
SetAccount(s, addr, acc)
2016-03-20 03:00:43 -07:00
}
2016-03-29 14:25:17 -07:00
2016-05-01 13:52:08 -07:00
func (s *State) CacheWrap() *State {
cache := types.NewKVCache(s)
2016-05-01 13:52:08 -07:00
return &State{
chainID: s.chainID,
store: cache,
readCache: nil,
writeCache: cache,
2016-05-01 13:52:08 -07:00
}
2016-03-29 14:25:17 -07:00
}
2016-05-01 13:52:08 -07:00
// NOTE: errors if s is not from CacheWrap()
func (s *State) CacheSync() {
s.writeCache.Sync()
2016-03-29 14:25:17 -07:00
}
2016-04-17 12:41:26 -07:00
2017-01-14 20:42:47 -08:00
func (s *State) Commit() abci.Result {
switch s.store.(type) {
case *eyes.Client:
s.readCache = make(map[string][]byte)
return s.store.(*eyes.Client).CommitSync()
default:
2017-02-19 11:22:38 -08:00
return abci.NewError(abci.CodeType_InternalError, "can only use Commit if store is merkleeyes")
}
2017-01-12 17:49:51 -08:00
}
2016-04-17 12:41:26 -07:00
//----------------------------------------
func AccountKey(addr []byte) []byte {
return append([]byte("base/a/"), addr...)
}
2016-05-01 13:52:08 -07:00
func GetAccount(store types.KVStore, addr []byte) *types.Account {
data := store.Get(AccountKey(addr))
if len(data) == 0 {
return nil
}
var acc *types.Account
err := wire.ReadBinaryBytes(data, &acc)
if err != nil {
panic(Fmt("Error reading account %X error: %v",
data, err.Error()))
}
return acc
}
func SetAccount(store types.KVStore, addr []byte, acc *types.Account) {
accBytes := wire.BinaryBytes(acc)
store.Set(AccountKey(addr), accBytes)
}