github.com/Gessiux/neatchain@v1.3.1/chain/consensus/neatcon/state/state.go (about) 1 package state 2 3 import ( 4 "bytes" 5 "time" 6 7 "github.com/Gessiux/neatchain/chain/log" 8 9 . "github.com/Gessiux/go-common" 10 //cfg "github.com/Gessiux/go-config" 11 //dbm "github.com/Gessiux/go-db" 12 "github.com/Gessiux/go-wire" 13 //"github.com/Gessiux/neatchain/chain/consensus/neatcon/state/txindex" 14 //"github.com/Gessiux/neatchain/chain/consensus/neatcon/state/txindex/null" 15 "github.com/Gessiux/neatchain/chain/consensus/neatcon/types" 16 //"fmt" 17 "github.com/Gessiux/neatchain/chain/consensus/neatcon/epoch" 18 "github.com/pkg/errors" 19 ) 20 21 /* 22 var ( 23 stateKey = []byte("stateKey") 24 ) 25 */ 26 //----------------------------------------------------------------------------- 27 28 // NOTE: not goroutine-safe. 29 type State struct { 30 // mtx for writing to db 31 //mtx sync.Mutex 32 //db dbm.DB 33 34 // should not change 35 //GenesisDoc *types.GenesisDoc 36 37 /* 38 ChainID string 39 Height uint64 // Genesis state has this set to 0. So, Block(H=0) does not exist. 40 Time time.Time 41 BlockID types.BlockID 42 NeedToSave bool //record the number of the block which should be saved to main chain 43 EpochNumber uint64 44 */ 45 NTCExtra *types.NeatConExtra 46 47 Epoch *epoch.Epoch 48 //Validators *types.ValidatorSet 49 //LastValidators *types.ValidatorSet // block.LastCommit validated against this 50 51 // AppHash is updated after Commit 52 //AppHash []byte 53 54 //TxIndexer txindex.TxIndexer `json:"-"` // Transaction indexer. 55 56 // Intermediate results from processing 57 // Persisted separately from the state 58 //abciResponses *ABCIResponses 59 60 logger log.Logger 61 } 62 63 func NewState(logger log.Logger) *State { 64 return &State{logger: logger} 65 } 66 67 /* 68 func LoadState(stateDB dbm.DB) *State { 69 state := loadState(stateDB, stateKey) 70 return state 71 } 72 73 func loadState(db dbm.DB, key []byte) *State { 74 s := &State{db: db, TxIndexer: &null.TxIndex{}} 75 buf := db.Get(key) 76 if len(buf) == 0 { 77 return nil 78 } else { 79 r, n, err := bytes.NewReader(buf), new(int), new(error) 80 wire.ReadBinaryPtr(&s, r, 0, n, err) 81 if *err != nil { 82 // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED 83 Exit(Fmt("LoadState: Data has been corrupted or its spec has changed: %v\n", *err)) 84 } 85 // TODO: ensure that buf is completely read. 86 } 87 return s 88 } 89 */ 90 91 func (s *State) Copy() *State { 92 //fmt.Printf("State.Copy(), s.LastValidators are %v\n",s.LastValidators) 93 //debug.PrintStack() 94 95 return &State{ 96 //db: s.db, 97 //GenesisDoc: s.GenesisDoc, 98 /* 99 ChainID: s.ChainID, 100 Height: s.Height, 101 BlockID: s.BlockID, 102 Time: s.Time, 103 EpochNumber: s.EpochNumber, 104 NeedToSave: s.NeedToSave, 105 */ 106 NTCExtra: s.NTCExtra.Copy(), 107 Epoch: s.Epoch.Copy(), 108 //Validators: s.Validators.Copy(), 109 //LastValidators: s.LastValidators.Copy(), 110 //AppHash: s.AppHash, 111 //TxIndexer: s.TxIndexer, // pointer here, not value 112 logger: s.logger, 113 } 114 } 115 116 /* 117 func (s *State) Save() { 118 s.mtx.Lock() 119 defer s.mtx.Unlock() 120 s.db.SetSync(stateKey, s.Bytes()) 121 } 122 */ 123 func (s *State) Equals(s2 *State) bool { 124 return bytes.Equal(s.Bytes(), s2.Bytes()) 125 } 126 127 func (s *State) Bytes() []byte { 128 buf, n, err := new(bytes.Buffer), new(int), new(error) 129 wire.WriteBinary(s, buf, n, err) 130 if *err != nil { 131 PanicCrisis(*err) 132 } 133 return buf.Bytes() 134 } 135 136 func (s *State) GetValidators() (*types.ValidatorSet, *types.ValidatorSet, error) { 137 138 if s.Epoch == nil { 139 return nil, nil, errors.New("epoch does not exist") 140 } 141 142 if s.NTCExtra.EpochNumber == uint64(s.Epoch.Number) { 143 return s.Epoch.Validators, s.Epoch.Validators, nil 144 } else if s.NTCExtra.EpochNumber == uint64(s.Epoch.Number-1) { 145 return s.Epoch.GetPreviousEpoch().Validators, s.Epoch.Validators, nil 146 } 147 148 return nil, nil, errors.New("epoch information error") 149 } 150 151 //----------------------------------------------------------------------------- 152 // Genesis 153 154 // MakeGenesisState creates state from types.GenesisDoc. 155 // 156 // Used in tests. 157 func MakeGenesisState( /*db dbm.DB, genDoc *types.GenesisDoc,*/ chainID string, logger log.Logger) *State { 158 //if len(genDoc.CurrentEpoch.Validators) == 0 { 159 // Exit(Fmt("The genesis file has no validators")) 160 //} 161 // 162 //if genDoc.GenesisTime.IsZero() { 163 // genDoc.GenesisTime = time.Now() 164 //} 165 166 // Make validators slice 167 //validators := make([]*types.Validator, len(genDoc.CurrentEpoch.Validators)) 168 //for i, val := range genDoc.CurrentEpoch.Validators { 169 // pubKey := val.PubKey 170 // address := pubKey.Address() 171 // 172 // // Make validator 173 // validators[i] = &types.Validator{ 174 // Address: address, 175 // PubKey: pubKey, 176 // VotingPower: val.Amount, 177 // } 178 //} 179 180 return &State{ 181 //db: db, 182 //GenesisDoc: genDoc, 183 NTCExtra: &types.NeatConExtra{ 184 ChainID: chainID, 185 Height: 0, 186 Time: time.Now(), 187 EpochNumber: 0, 188 NeedToSave: false, 189 NeedToBroadcast: false, 190 }, 191 //Validators: types.NewValidatorSet(validators), 192 //LastValidators: types.NewValidatorSet(nil), 193 //AppHash: genDoc.AppHash, 194 //TxIndexer: &null.TxIndex{}, // we do not need indexer during replay and in tests 195 logger: logger, 196 } 197 }