func LoadState(db dbm.DB) *State { s := &State{DB: db} buf := db.Get(stateKey) if len(buf) == 0 { return nil } else { r, n, err := bytes.NewReader(buf), new(int64), new(error) s.ChainID = wire.ReadString(r, n, err) s.LastBlockHeight = wire.ReadVarint(r, n, err) s.LastBlockHash = wire.ReadByteSlice(r, n, err) s.LastBlockParts = wire.ReadBinary(types.PartSetHeader{}, r, n, err).(types.PartSetHeader) s.LastBlockTime = wire.ReadTime(r, n, err) s.BondedValidators = wire.ReadBinary(&types.ValidatorSet{}, r, n, err).(*types.ValidatorSet) s.LastBondedValidators = wire.ReadBinary(&types.ValidatorSet{}, r, n, err).(*types.ValidatorSet) s.UnbondingValidators = wire.ReadBinary(&types.ValidatorSet{}, r, n, err).(*types.ValidatorSet) accountsHash := wire.ReadByteSlice(r, n, err) s.accounts = merkle.NewIAVLTree(wire.BasicCodec, acm.AccountCodec, defaultAccountsCacheCapacity, db) s.accounts.Load(accountsHash) validatorInfosHash := wire.ReadByteSlice(r, n, err) s.validatorInfos = merkle.NewIAVLTree(wire.BasicCodec, types.ValidatorInfoCodec, 0, db) s.validatorInfos.Load(validatorInfosHash) nameRegHash := wire.ReadByteSlice(r, n, err) s.nameReg = merkle.NewIAVLTree(wire.BasicCodec, NameRegCodec, 0, db) s.nameReg.Load(nameRegHash) if *err != nil { // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED Exit(Fmt("Data has been corrupted or its spec has changed: %v\n", *err)) } // TODO: ensure that buf is completely read. } return s }
// restore state from json blob // set tendermint config before calling func CoreRestore(chainID string, jsonBytes []byte) { var stJ State var err error wire.ReadJSON(&stJ, jsonBytes, &err) IfExit(err) st := new(sm.State) st.ChainID = chainID st.BondedValidators = stJ.BondedValidators st.LastBondedValidators = stJ.LastBondedValidators st.UnbondingValidators = stJ.UnbondingValidators stateDB := dbm.GetDB("state") // fill the accounts tree accounts := merkle.NewIAVLTree(wire.BasicCodec, acm.AccountCodec, 1000, stateDB) for _, account := range stJ.Accounts { accounts.Set(account.Address, account.Copy()) } // fill the storage tree for each contract for _, accStorage := range stJ.AccountsStorage { st := merkle.NewIAVLTree(wire.BasicCodec, wire.BasicCodec, 1024, stateDB) for _, accSt := range accStorage.Storage { set := st.Set(accSt.Key, accSt.Value) if !set { panic("failed to update storage tree") } } // TODO: sanity check vs acc.StorageRoot st.Save() } valInfos := merkle.NewIAVLTree(wire.BasicCodec, types.ValidatorInfoCodec, 0, stateDB) for _, valInfo := range stJ.ValidatorInfos { valInfos.Set(valInfo.Address, valInfo) } nameReg := merkle.NewIAVLTree(wire.BasicCodec, sm.NameRegCodec, 0, stateDB) for _, entry := range stJ.NameReg { nameReg.Set(entry.Name, entry) } // persists accounts/valInfos/nameReg trees st.SetAccounts(accounts) st.SetValidatorInfos(valInfos) st.SetNameReg(nameReg) st.SetDB(stateDB) st.Save() }
func makeStorage(db dbm.DB, root []byte) merkle.Tree { storage := merkle.NewIAVLTree( wire.BasicCodec, wire.BasicCodec, 1024, db, ) storage.Load(root) return storage }
// dump the latest state to json func CoreDump(dumpval bool) []byte { // Get State stateDB := dbm.GetDB("state") st := sm.LoadState(stateDB) if st == nil { Exit(fmt.Errorf("Error: state loaded from %s is nil!", config.GetString("db_dir"))) } stJ := new(State) //default is true, flag omits vals from dump if dumpval { stJ.BondedValidators = st.BondedValidators stJ.LastBondedValidators = st.LastBondedValidators stJ.UnbondingValidators = st.UnbondingValidators } // iterate through accounts tree // track storage roots as we go storageRoots := [][]byte{} st.GetAccounts().Iterate(func(key interface{}, value interface{}) (stopped bool) { acc := value.(*acm.Account) stJ.Accounts = append(stJ.Accounts, acc) storageRoots = append(storageRoots, acc.StorageRoot) return false }) // grab all storage for i, root := range storageRoots { if len(root) == 0 { continue } accStorage := &AccountStorage{Address: stJ.Accounts[i].Address} storage := merkle.NewIAVLTree(wire.BasicCodec, wire.BasicCodec, 1024, stateDB) storage.Load(root) storage.Iterate(func(key interface{}, value interface{}) (stopped bool) { k, v := key.([]byte), value.([]byte) accStorage.Storage = append(accStorage.Storage, &Storage{k, v}) return false }) stJ.AccountsStorage = append(stJ.AccountsStorage, accStorage) } // get all validator infos if dumpval { st.GetValidatorInfos().Iterate(func(key interface{}, value interface{}) (stopped bool) { vi := value.(*types.ValidatorInfo) stJ.ValidatorInfos = append(stJ.ValidatorInfos, vi) return false }) } // get all name entries st.GetNames().Iterate(func(key interface{}, value interface{}) (stopped bool) { name := value.(*types.NameRegEntry) stJ.NameReg = append(stJ.NameReg, name) return false }) w, n, err := new(bytes.Buffer), new(int64), new(error) wire.WriteJSON(stJ, w, n, err) IfExit(*err) w2 := new(bytes.Buffer) json.Indent(w2, w.Bytes(), "", "\t") return w2.Bytes() }
func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State { if len(genDoc.Validators) == 0 { Exit(Fmt("The genesis file has no validators")) } if genDoc.GenesisTime.IsZero() { genDoc.GenesisTime = time.Now() } // Make accounts state tree accounts := merkle.NewIAVLTree(wire.BasicCodec, acm.AccountCodec, defaultAccountsCacheCapacity, db) for _, genAcc := range genDoc.Accounts { perm := ptypes.ZeroAccountPermissions if genAcc.Permissions != nil { perm = *genAcc.Permissions } acc := &acm.Account{ Address: genAcc.Address, PubKey: nil, Sequence: 0, Balance: genAcc.Amount, Permissions: perm, } accounts.Set(acc.Address, acc) } // global permissions are saved as the 0 address // so they are included in the accounts tree globalPerms := ptypes.DefaultAccountPermissions if genDoc.Params != nil && genDoc.Params.GlobalPermissions != nil { globalPerms = *genDoc.Params.GlobalPermissions // XXX: make sure the set bits are all true // Without it the HasPermission() functions will fail globalPerms.Base.SetBit = ptypes.AllPermFlags } permsAcc := &acm.Account{ Address: ptypes.GlobalPermissionsAddress, PubKey: nil, Sequence: 0, Balance: 1337, Permissions: globalPerms, } accounts.Set(permsAcc.Address, permsAcc) // Make validatorInfos state tree && validators slice validatorInfos := merkle.NewIAVLTree(wire.BasicCodec, types.ValidatorInfoCodec, 0, db) validators := make([]*types.Validator, len(genDoc.Validators)) for i, val := range genDoc.Validators { pubKey := val.PubKey address := pubKey.Address() // Make ValidatorInfo valInfo := &types.ValidatorInfo{ Address: address, PubKey: pubKey, UnbondTo: make([]*types.TxOutput, len(val.UnbondTo)), FirstBondHeight: 0, FirstBondAmount: val.Amount, } for i, unbondTo := range val.UnbondTo { valInfo.UnbondTo[i] = &types.TxOutput{ Address: unbondTo.Address, Amount: unbondTo.Amount, } } validatorInfos.Set(address, valInfo) // Make validator validators[i] = &types.Validator{ Address: address, PubKey: pubKey, VotingPower: val.Amount, } } // Make namereg tree nameReg := merkle.NewIAVLTree(wire.BasicCodec, NameRegCodec, 0, db) // TODO: add names, contracts to genesis.json // IAVLTrees must be persisted before copy operations. accounts.Save() validatorInfos.Save() nameReg.Save() return &State{ DB: db, ChainID: genDoc.ChainID, LastBlockHeight: 0, LastBlockHash: nil, LastBlockParts: types.PartSetHeader{}, LastBlockTime: genDoc.GenesisTime, BondedValidators: types.NewValidatorSet(validators), LastBondedValidators: types.NewValidatorSet(nil), UnbondingValidators: types.NewValidatorSet(nil), accounts: accounts, validatorInfos: validatorInfos, nameReg: nameReg, } }
func (s *State) LoadStorage(hash []byte) (storage merkle.Tree) { storage = merkle.NewIAVLTree(wire.BasicCodec, wire.BasicCodec, 1024, s.DB) storage.Load(hash) return storage }