func (as *AccState) Load(root []byte) {
	as.mtx.Lock()
	defer as.mtx.Unlock()
	as.accountCache = mlist.NewMapList()
	as.trie.Load(root)
}
Load dumps all the buffer, start every thing from a clean state
package node
import (
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"math/big"
	"sync"
	"github.com/tendermint/tmlibs/db"
	"github.com/Baptist-Publication/chorus-module/lib/go-crypto"
	"github.com/Baptist-Publication/chorus-module/xlib/iavl"
	"github.com/Baptist-Publication/chorus-module/xlib/mlist"
)
type AccState struct {
	mtx      sync.Mutex
	database db.DB
	rootHash []byte
	trie     *iavl.IAVLTree
	accountCache *mlist.MapList
}
type Account struct {
	Nonce   uint64
	Pubkey  []byte
	Balance *big.Int
}
func NewAccState(database db.DB) *AccState {
	return &AccState{
		database:     database,
		trie:         iavl.NewIAVLTree(1024, database),
		accountCache: mlist.NewMapList(),
	}
}
func (as *AccState) Lock() {
	as.mtx.Lock()
}
func (as *AccState) Unlock() {
	as.mtx.Unlock()
}
func (as *AccState) CreateAccount(pubkey []byte, balance *big.Int) {
	if balance.Cmp(big.NewInt(0)) < 0 {
		return
	}
	as.mtx.Lock()
	defer as.mtx.Unlock()
	pub := crypto.PubKeyEd25519{}
	copy(pub[:], pubkey[:])
	acc := &Account{
		Pubkey:  pubkey,
		Balance: new(big.Int).Set(balance),
		Nonce:   1,
	}
	as.accountCache.Set(pub.KeyString(), acc)
}
func (as *AccState) GetAccount(pubkey []byte) (*Account, error) {
	as.mtx.Lock()
	defer as.mtx.Unlock()
	pub := crypto.PubKeyEd25519{}
	copy(pub[:], pubkey)
	if acc, ok := as.accountCache.Get(pub.KeyString()); ok {
		return acc.(*Account), nil
	}
	if _, accountbytes, exist := as.trie.Get([]byte(pub.KeyString())); exist {
		acc := new(Account)
		acc.FromBytes(accountbytes)
		return acc, nil
	}
	return nil, fmt.Errorf("account not exist: %X", pubkey)
}
func (as *AccState) AddBalance(pubkey crypto.PubKey, amount *big.Int) error {
	keystring := pubkey.KeyString()
	as.Lock()
	defer as.Unlock()
	if itfc, ok := as.accountCache.Get(keystring); ok {
		acc := itfc.(*Account)
		acc.Balance = new(big.Int).Add(acc.Balance, amount)
		as.accountCache.Set(keystring, acc)
		return nil
	}
	if _, value, exist := as.trie.Get([]byte(keystring)); exist {
		acc := new(Account)
		err := acc.FromBytes(value)
		if err != nil {
			return err
		}
		acc.Balance = new(big.Int).Add(acc.Balance, amount)
		as.accountCache.Set(keystring, acc)
		return nil
	}
	pk := pubkey.(*crypto.PubKeyEd25519)
	acc := &Account{
		Pubkey:  pk[:],
		Balance: amount,
		Nonce:   1,  
	}
	as.accountCache.Set(pk.KeyString(), acc)
	return nil
}
func (as *AccState) SubBalance(pubkey crypto.PubKey, amount *big.Int) error {
	keystring := pubkey.KeyString()
	as.Lock()
	defer as.Unlock()
	if itfc, ok := as.accountCache.Get(keystring); ok {
		acc := itfc.(*Account)
		if acc.Balance.Cmp(amount) >= 0 {
			acc.Balance = new(big.Int).Sub(acc.Balance, amount)
			return nil
		}
		return errors.New("insufficent balance to sub")
	}
	if _, value, exist := as.trie.Get([]byte(keystring)); exist {
		acc := new(Account)
		err := acc.FromBytes(value)
		if err != nil {
			return err
		}
		if acc.Balance.Cmp(amount) >= 0 {
			acc.Balance = new(big.Int).Sub(acc.Balance, amount)
			as.accountCache.Set(keystring, acc)
			return nil
		}
		return errors.New("insufficent balance to sub")
	}
	return fmt.Errorf("account not exist: %s", keystring)
}
func (as *AccState) IncreaseNonce(pubkey crypto.PubKey, n uint64) error {
	keystring := pubkey.KeyString()
	as.Lock()
	defer as.Unlock()
	if itfc, ok := as.accountCache.Get(keystring); ok {
		acc := itfc.(*Account)
		acc.Nonce += n
		return nil
	}
	if _, value, exist := as.trie.Get([]byte(keystring)); exist {
		acc := new(Account)
		err := acc.FromBytes(value)
		if err != nil {
			return err
		}
		acc.Nonce += n
		as.accountCache.Set(keystring, acc)
		return nil
	}
	return fmt.Errorf("account not exist: %s", keystring)
}
func (as *AccState) QueryNonce(pubkey crypto.PubKey) uint64 {
	keystring := pubkey.KeyString()
	as.Lock()
	defer as.Unlock()
	if itfc, ok := as.accountCache.Get(keystring); ok {
		acc := itfc.(*Account)
		return acc.Nonce
	}
	if _, value, exist := as.trie.Get([]byte(keystring)); exist {
		acc := new(Account)
		err := acc.FromBytes(value)
		if err != nil {
			log.Println(err)
			return 0
		}
		return acc.Nonce
	}
	return 0
}
func (as *AccState) QueryBalance(pubkey crypto.PubKey) *big.Int {
	keystring := pubkey.KeyString()
	as.Lock()
	defer as.Unlock()
	if itfc, ok := as.accountCache.Get(keystring); ok {
		acc := itfc.(*Account)
		return acc.Balance
	}
	if _, value, exist := as.trie.Get([]byte(keystring)); exist {
		acc := new(Account)
		err := acc.FromBytes(value)
		if err != nil {
			log.Println(err)
			return Big0
		}
		return acc.Balance
	}
	return Big0
}
func (as *AccState) Commit() ([]byte, error) {
	as.mtx.Lock()
	defer as.mtx.Unlock()
	as.accountCache.Exec(func(k string, v interface{}) {
		acc := v.(*Account)
		as.trie.Set([]byte(k), acc.ToBytes())
	})
	as.rootHash = as.trie.Save()
	return as.rootHash, nil
}