github.com/okex/exchain@v1.8.0/libs/tendermint/state/helpers_test.go (about) 1 package state_test 2 3 import ( 4 "bytes" 5 "fmt" 6 "time" 7 8 dbm "github.com/okex/exchain/libs/tm-db" 9 10 abci "github.com/okex/exchain/libs/tendermint/abci/types" 11 "github.com/okex/exchain/libs/tendermint/crypto" 12 "github.com/okex/exchain/libs/tendermint/crypto/ed25519" 13 tmrand "github.com/okex/exchain/libs/tendermint/libs/rand" 14 "github.com/okex/exchain/libs/tendermint/proxy" 15 sm "github.com/okex/exchain/libs/tendermint/state" 16 "github.com/okex/exchain/libs/tendermint/types" 17 tmtime "github.com/okex/exchain/libs/tendermint/types/time" 18 ) 19 20 type paramsChangeTestCase struct { 21 height int64 22 params types.ConsensusParams 23 } 24 25 // always returns true if asked if any evidence was already committed. 26 type mockEvPoolAlwaysCommitted struct{} 27 28 func (m mockEvPoolAlwaysCommitted) PendingEvidence(int64) []types.Evidence { return nil } 29 func (m mockEvPoolAlwaysCommitted) AddEvidence(types.Evidence) error { return nil } 30 func (m mockEvPoolAlwaysCommitted) Update(*types.Block, sm.State) {} 31 func (m mockEvPoolAlwaysCommitted) IsCommitted(types.Evidence) bool { return true } 32 33 func newTestApp() proxy.AppConns { 34 app := &testApp{} 35 cc := proxy.NewLocalClientCreator(app) 36 return proxy.NewAppConns(cc) 37 } 38 39 func makeAndCommitGoodBlock( 40 state sm.State, 41 height int64, 42 lastCommit *types.Commit, 43 proposerAddr []byte, 44 blockExec *sm.BlockExecutor, 45 privVals map[string]types.PrivValidator, 46 evidence []types.Evidence) (sm.State, types.BlockID, *types.Commit, error) { 47 // A good block passes 48 state, blockID, err := makeAndApplyGoodBlock(state, height, lastCommit, proposerAddr, blockExec, evidence) 49 if err != nil { 50 return state, types.BlockID{}, nil, err 51 } 52 53 // Simulate a lastCommit for this block from all validators for the next height 54 commit, err := makeValidCommit(height, blockID, state.Validators, privVals) 55 if err != nil { 56 return state, types.BlockID{}, nil, err 57 } 58 return state, blockID, commit, nil 59 } 60 61 func makeAndApplyGoodBlock(state sm.State, height int64, lastCommit *types.Commit, proposerAddr []byte, 62 blockExec *sm.BlockExecutor, evidence []types.Evidence) (sm.State, types.BlockID, error) { 63 block, _ := state.MakeBlock(height, makeTxs(height), lastCommit, evidence, proposerAddr) 64 if err := blockExec.ValidateBlock(state, block); err != nil { 65 return state, types.BlockID{}, err 66 } 67 blockID := types.BlockID{Hash: block.Hash(), 68 PartsHeader: types.PartSetHeader{Total: 3, Hash: tmrand.Bytes(32)}} 69 state, _, err := blockExec.ApplyBlock(state, blockID, block) 70 if err != nil { 71 return state, types.BlockID{}, err 72 } 73 return state, blockID, nil 74 } 75 76 func makeValidCommit( 77 height int64, 78 blockID types.BlockID, 79 vals *types.ValidatorSet, 80 privVals map[string]types.PrivValidator, 81 ) (*types.Commit, error) { 82 sigs := make([]types.CommitSig, 0) 83 for i := 0; i < vals.Size(); i++ { 84 _, val := vals.GetByIndex(i) 85 vote, err := types.MakeVote(height, blockID, vals, privVals[val.Address.String()], chainID, time.Now()) 86 if err != nil { 87 return nil, err 88 } 89 sigs = append(sigs, vote.CommitSig()) 90 } 91 return types.NewCommit(height, 0, blockID, sigs), nil 92 } 93 94 // make some bogus txs 95 func makeTxs(height int64) (txs []types.Tx) { 96 for i := 0; i < nTxsPerBlock; i++ { 97 txs = append(txs, types.Tx([]byte{byte(height), byte(i)})) 98 } 99 return txs 100 } 101 102 func makeState(nVals, height int) (sm.State, dbm.DB, map[string]types.PrivValidator) { 103 vals := make([]types.GenesisValidator, nVals) 104 privVals := make(map[string]types.PrivValidator, nVals) 105 for i := 0; i < nVals; i++ { 106 secret := []byte(fmt.Sprintf("test%d", i)) 107 pk := ed25519.GenPrivKeyFromSecret(secret) 108 valAddr := pk.PubKey().Address() 109 vals[i] = types.GenesisValidator{ 110 Address: valAddr, 111 PubKey: pk.PubKey(), 112 Power: 1000, 113 Name: fmt.Sprintf("test%d", i), 114 } 115 privVals[valAddr.String()] = types.NewMockPVWithParams(pk, false, false) 116 } 117 s, _ := sm.MakeGenesisState(&types.GenesisDoc{ 118 ChainID: chainID, 119 Validators: vals, 120 AppHash: nil, 121 }) 122 123 stateDB := dbm.NewMemDB() 124 sm.SaveState(stateDB, s) 125 126 for i := 1; i < height; i++ { 127 s.LastBlockHeight++ 128 s.LastValidators = s.Validators.Copy() 129 sm.SaveState(stateDB, s) 130 } 131 return s, stateDB, privVals 132 } 133 134 func makeBlock(state sm.State, height int64) *types.Block { 135 block, _ := state.MakeBlock( 136 height, 137 makeTxs(state.LastBlockHeight), 138 new(types.Commit), 139 nil, 140 state.Validators.GetProposer().Address, 141 ) 142 return block 143 } 144 145 func genValSet(size int) *types.ValidatorSet { 146 vals := make([]*types.Validator, size) 147 for i := 0; i < size; i++ { 148 vals[i] = types.NewValidator(ed25519.GenPrivKey().PubKey(), 10) 149 } 150 return types.NewValidatorSet(vals) 151 } 152 153 func makeConsensusParams( 154 blockBytes, blockGas int64, 155 blockTimeIotaMs int64, 156 evidenceAge int64, 157 ) types.ConsensusParams { 158 return types.ConsensusParams{ 159 Block: types.BlockParams{ 160 MaxBytes: blockBytes, 161 MaxGas: blockGas, 162 TimeIotaMs: blockTimeIotaMs, 163 }, 164 Evidence: types.EvidenceParams{ 165 MaxAgeNumBlocks: evidenceAge, 166 MaxAgeDuration: time.Duration(evidenceAge), 167 }, 168 } 169 } 170 171 func makeHeaderPartsResponsesValPubKeyChange( 172 state sm.State, 173 pubkey crypto.PubKey, 174 ) (types.Header, types.BlockID, *sm.ABCIResponses) { 175 176 block := makeBlock(state, state.LastBlockHeight+1) 177 abciResponses := &sm.ABCIResponses{ 178 EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, 179 } 180 181 // If the pubkey is new, remove the old and add the new. 182 _, val := state.NextValidators.GetByIndex(0) 183 if !bytes.Equal(pubkey.Bytes(), val.PubKey.Bytes()) { 184 abciResponses.EndBlock = &abci.ResponseEndBlock{ 185 ValidatorUpdates: []abci.ValidatorUpdate{ 186 types.TM2PB.NewValidatorUpdate(val.PubKey, 0), 187 types.TM2PB.NewValidatorUpdate(pubkey, 10), 188 }, 189 } 190 } 191 192 return block.Header, types.BlockID{Hash: block.Hash(), PartsHeader: types.PartSetHeader{}}, abciResponses 193 } 194 195 func makeHeaderPartsResponsesValPowerChange( 196 state sm.State, 197 power int64, 198 ) (types.Header, types.BlockID, *sm.ABCIResponses) { 199 200 block := makeBlock(state, state.LastBlockHeight+1) 201 abciResponses := &sm.ABCIResponses{ 202 EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, 203 } 204 205 // If the pubkey is new, remove the old and add the new. 206 _, val := state.NextValidators.GetByIndex(0) 207 if val.VotingPower != power { 208 abciResponses.EndBlock = &abci.ResponseEndBlock{ 209 ValidatorUpdates: []abci.ValidatorUpdate{ 210 types.TM2PB.NewValidatorUpdate(val.PubKey, power), 211 }, 212 } 213 } 214 215 return block.Header, types.BlockID{Hash: block.Hash(), PartsHeader: types.PartSetHeader{}}, abciResponses 216 } 217 218 func makeHeaderPartsResponsesParams( 219 state sm.State, 220 params types.ConsensusParams, 221 ) (types.Header, types.BlockID, *sm.ABCIResponses) { 222 223 block := makeBlock(state, state.LastBlockHeight+1) 224 abciResponses := &sm.ABCIResponses{ 225 EndBlock: &abci.ResponseEndBlock{ConsensusParamUpdates: types.TM2PB.ConsensusParams(¶ms)}, 226 } 227 return block.Header, types.BlockID{Hash: block.Hash(), PartsHeader: types.PartSetHeader{}}, abciResponses 228 } 229 230 func randomGenesisDoc() *types.GenesisDoc { 231 pubkey := ed25519.GenPrivKey().PubKey() 232 return &types.GenesisDoc{ 233 GenesisTime: tmtime.Now(), 234 ChainID: "abc", 235 Validators: []types.GenesisValidator{ 236 { 237 Address: pubkey.Address(), 238 PubKey: pubkey, 239 Power: 10, 240 Name: "myval", 241 }, 242 }, 243 ConsensusParams: types.DefaultConsensusParams(), 244 } 245 } 246 247 //---------------------------------------------------------------------------- 248 249 type testApp struct { 250 abci.BaseApplication 251 252 CommitVotes []abci.VoteInfo 253 ByzantineValidators []abci.Evidence 254 ValidatorUpdates []abci.ValidatorUpdate 255 } 256 257 var _ abci.Application = (*testApp)(nil) 258 259 func (app *testApp) Info(req abci.RequestInfo) (resInfo abci.ResponseInfo) { 260 return abci.ResponseInfo{} 261 } 262 263 func (app *testApp) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginBlock { 264 app.CommitVotes = req.LastCommitInfo.Votes 265 app.ByzantineValidators = req.ByzantineValidators 266 return abci.ResponseBeginBlock{} 267 } 268 269 func (app *testApp) EndBlock(req abci.RequestEndBlock) abci.ResponseEndBlock { 270 return abci.ResponseEndBlock{ValidatorUpdates: app.ValidatorUpdates} 271 } 272 273 func (app *testApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx { 274 return abci.ResponseDeliverTx{Events: []abci.Event{}} 275 } 276 277 func (app *testApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { 278 return abci.ResponseCheckTx{} 279 } 280 281 func (app *testApp) Commit(abci.RequestCommit) abci.ResponseCommit { 282 return abci.ResponseCommit{} 283 } 284 285 func (app *testApp) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQuery) { 286 return 287 }