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