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