Plugin interface methods take store

This commit is contained in:
Jae Kwon
2016-05-01 13:52:08 -07:00
parent fefcbbf3b0
commit 324e72f36d
7 changed files with 170 additions and 159 deletions
+10 -18
View File
@@ -8,20 +8,11 @@ import (
)
// If the tx is invalid, a TMSP error will be returned.
func ExecTx(s *State, pgz *types.Plugins, tx types.Tx, isCheckTx bool, evc events.Fireable) tmsp.Result {
func ExecTx(state *State, pgz *types.Plugins, tx types.Tx, isCheckTx bool, evc events.Fireable) tmsp.Result {
// TODO: do something with fees
fees := types.Coins{}
chainID := s.GetChainID()
// Get the state. If isCheckTx, then we use a cache.
// The idea is to throw away this cache after every EndBlock().
var state types.AccountGetterSetter
if isCheckTx {
state = s.GetCheckCache()
} else {
state = s
}
chainID := state.GetChainID()
// Exec tx
switch tx := tx.(type) {
@@ -129,15 +120,16 @@ func ExecTx(s *State, pgz *types.Plugins, tx types.Tx, isCheckTx bool, evc event
}
// Create inAcc checkpoint
inAccCopy := inAcc.Copy()
inAccDeducted := inAcc.Copy()
// Run the tx.
cache := types.NewAccountCache(state)
// XXX cache := types.NewStateCache(state)
cache := state.CacheWrap()
cache.SetAccount(tx.Input.Address, inAcc)
ctx := types.NewCallContext(cache, inAcc, coins)
res = plugin.RunTx(ctx, tx.Data)
ctx := types.NewCallContext(tx.Input.Address, coins)
res = plugin.RunTx(cache, ctx, tx.Data)
if res.IsOK() {
cache.Sync()
cache.CacheSync()
log.Info("Successful execution")
// Fire events
/*
@@ -153,10 +145,10 @@ func ExecTx(s *State, pgz *types.Plugins, tx types.Tx, isCheckTx bool, evc event
} else {
log.Info("AppTx failed", "error", res)
// Just return the coins and return.
inAccCopy.Balance = inAccCopy.Balance.Plus(coins)
inAccDeducted.Balance = inAccDeducted.Balance.Plus(coins)
// But take the gas
// TODO
state.SetAccount(tx.Input.Address, inAccCopy)
state.SetAccount(tx.Input.Address, inAccDeducted)
}
return res
+48 -36
View File
@@ -4,26 +4,21 @@ import (
"github.com/tendermint/basecoin/types"
. "github.com/tendermint/go-common"
"github.com/tendermint/go-wire"
eyes "github.com/tendermint/merkleeyes/client"
)
// CONTRACT: State should be quick to copy.
// See CacheWrap().
type State struct {
chainID string
eyesCli *eyes.Client
checkCache *types.AccountCache
LastBlockHeight uint64
LastBlockHash []byte
GasLimit int64
chainID string
store types.KVStore
cache *types.KVCache // optional
}
func NewState(eyesCli *eyes.Client) *State {
s := &State{
func NewState(store types.KVStore) *State {
return &State{
chainID: "",
eyesCli: eyesCli,
store: store,
}
s.checkCache = types.NewAccountCache(s)
return s
}
func (s *State) SetChainID(chainID string) {
@@ -37,36 +32,34 @@ func (s *State) GetChainID() string {
return s.chainID
}
func (s *State) Get(key []byte) (value []byte) {
return s.store.Get(key)
}
func (s *State) Set(key []byte, value []byte) {
s.store.Set(key, value)
}
func (s *State) GetAccount(addr []byte) *types.Account {
res := s.eyesCli.GetSync(AccountKey(addr))
if res.IsErr() {
panic(Fmt("Error loading account addr %X error: %v", addr, res.Error()))
}
if len(res.Data) == 0 {
return nil
}
var acc *types.Account
err := wire.ReadBinaryBytes(res.Data, &acc)
if err != nil {
panic(Fmt("Error reading account %X error: %v", res.Data, err.Error()))
}
return acc
return GetAccount(s.store, addr)
}
func (s *State) SetAccount(addr []byte, acc *types.Account) {
accBytes := wire.BinaryBytes(acc)
res := s.eyesCli.SetSync(AccountKey(addr), accBytes)
if res.IsErr() {
panic(Fmt("Error storing account addr %X error: %v", addr, res.Error()))
SetAccount(s.store, addr, acc)
}
func (s *State) CacheWrap() *State {
cache := types.NewKVCache(s.store)
return &State{
chainID: s.chainID,
store: cache,
cache: cache,
}
}
func (s *State) GetCheckCache() *types.AccountCache {
return s.checkCache
}
func (s *State) ResetCacheState() {
s.checkCache = types.NewAccountCache(s)
// NOTE: errors if s is not from CacheWrap()
func (s *State) CacheSync() {
s.cache.Sync()
}
//----------------------------------------
@@ -74,3 +67,22 @@ func (s *State) ResetCacheState() {
func AccountKey(addr []byte) []byte {
return append([]byte("base/a/"), addr...)
}
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)
}