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