Plugin interface methods take store
This commit is contained in:
+10
-18
@@ -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
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user