github.com/okex/exchain@v1.8.0/libs/tendermint/state/test_common.go (about) 1 package state 2 3 import ( 4 "bytes" 5 "fmt" 6 "time" 7 8 "github.com/okex/exchain/libs/iavl" 9 "github.com/okex/exchain/libs/tendermint/libs/log" 10 11 dbm "github.com/okex/exchain/libs/tm-db" 12 13 abci "github.com/okex/exchain/libs/tendermint/abci/types" 14 "github.com/okex/exchain/libs/tendermint/crypto" 15 "github.com/okex/exchain/libs/tendermint/crypto/ed25519" 16 tmrand "github.com/okex/exchain/libs/tendermint/libs/rand" 17 "github.com/okex/exchain/libs/tendermint/proxy" 18 "github.com/okex/exchain/libs/tendermint/types" 19 tmtime "github.com/okex/exchain/libs/tendermint/types/time" 20 ) 21 22 var ( 23 chainID = "execution_chain" 24 testPartSize = 65536 25 nTxsPerBlock = 10 26 ) 27 28 type paramsChangeTestCase struct { 29 height int64 30 params types.ConsensusParams 31 } 32 33 // always returns true if asked if any evidence was already committed. 34 type mockEvPoolAlwaysCommitted struct{} 35 36 func (m mockEvPoolAlwaysCommitted) PendingEvidence(int64) []types.Evidence { return nil } 37 func (m mockEvPoolAlwaysCommitted) AddEvidence(types.Evidence) error { return nil } 38 func (m mockEvPoolAlwaysCommitted) Update(*types.Block, State) {} 39 func (m mockEvPoolAlwaysCommitted) IsCommitted(types.Evidence) bool { return true } 40 41 func newTestApp() proxy.AppConns { 42 app := &testApp{} 43 cc := proxy.NewLocalClientCreator(app) 44 return proxy.NewAppConns(cc) 45 } 46 47 func makeAndCommitGoodBlock( 48 state State, 49 height int64, 50 lastCommit *types.Commit, 51 proposerAddr []byte, 52 blockExec *BlockExecutor, 53 privVals map[string]types.PrivValidator, 54 evidence []types.Evidence) (State, types.BlockID, *types.Commit, error) { 55 // A good block passes 56 state, blockID, err := makeAndApplyGoodBlock(state, height, lastCommit, proposerAddr, blockExec, evidence) 57 if err != nil { 58 return state, types.BlockID{}, nil, err 59 } 60 61 // Simulate a lastCommit for this block from all validators for the next height 62 commit, err := makeValidCommit(height, blockID, state.Validators, privVals) 63 if err != nil { 64 return state, types.BlockID{}, nil, err 65 } 66 return state, blockID, commit, nil 67 } 68 69 func makeAndApplyGoodBlock(state State, height int64, lastCommit *types.Commit, proposerAddr []byte, 70 blockExec *BlockExecutor, evidence []types.Evidence) (State, types.BlockID, error) { 71 block, _ := state.MakeBlock(height, makeTxs(height), lastCommit, evidence, proposerAddr) 72 if err := blockExec.ValidateBlock(state, block); err != nil { 73 return state, types.BlockID{}, err 74 } 75 blockID := types.BlockID{Hash: block.Hash(), 76 PartsHeader: types.PartSetHeader{Total: 3, Hash: tmrand.Bytes(32)}} 77 state, _, err := blockExec.ApplyBlock(state, blockID, block) 78 if err != nil { 79 return state, types.BlockID{}, err 80 } 81 return state, blockID, nil 82 } 83 84 func makeValidCommit( 85 height int64, 86 blockID types.BlockID, 87 vals *types.ValidatorSet, 88 privVals map[string]types.PrivValidator, 89 ) (*types.Commit, error) { 90 sigs := make([]types.CommitSig, 0) 91 for i := 0; i < vals.Size(); i++ { 92 _, val := vals.GetByIndex(i) 93 vote, err := types.MakeVote(height, blockID, vals, privVals[val.Address.String()], chainID, time.Now()) 94 if err != nil { 95 return nil, err 96 } 97 sigs = append(sigs, vote.CommitSig()) 98 } 99 return types.NewCommit(height, 0, blockID, sigs), nil 100 } 101 102 // make some bogus txs 103 func makeTxs(height int64) (txs []types.Tx) { 104 for i := 0; i < nTxsPerBlock; i++ { 105 txs = append(txs, types.Tx([]byte{byte(height), byte(i)})) 106 } 107 return txs 108 } 109 110 func makeState(nVals, height int) (State, dbm.DB, map[string]types.PrivValidator) { 111 vals := make([]types.GenesisValidator, nVals) 112 privVals := make(map[string]types.PrivValidator, nVals) 113 for i := 0; i < nVals; i++ { 114 secret := []byte(fmt.Sprintf("test%d", i)) 115 pk := ed25519.GenPrivKeyFromSecret(secret) 116 valAddr := pk.PubKey().Address() 117 vals[i] = types.GenesisValidator{ 118 Address: valAddr, 119 PubKey: pk.PubKey(), 120 Power: 1000, 121 Name: fmt.Sprintf("test%d", i), 122 } 123 privVals[valAddr.String()] = types.NewMockPVWithParams(pk, false, false) 124 } 125 s, _ := MakeGenesisState(&types.GenesisDoc{ 126 ChainID: chainID, 127 Validators: vals, 128 AppHash: nil, 129 }) 130 131 stateDB := dbm.NewMemDB() 132 SaveState(stateDB, s) 133 134 for i := 1; i < height; i++ { 135 s.LastBlockHeight++ 136 s.LastValidators = s.Validators.Copy() 137 SaveState(stateDB, s) 138 } 139 return s, stateDB, privVals 140 } 141 142 func makeBlock(state State, height int64) *types.Block { 143 block, _ := state.MakeBlock( 144 height, 145 makeTxs(state.LastBlockHeight), 146 new(types.Commit), 147 nil, 148 state.Validators.GetProposer().Address, 149 ) 150 return block 151 } 152 153 func genValSet(size int) *types.ValidatorSet { 154 vals := make([]*types.Validator, size) 155 for i := 0; i < size; i++ { 156 vals[i] = types.NewValidator(ed25519.GenPrivKey().PubKey(), 10) 157 } 158 return types.NewValidatorSet(vals) 159 } 160 161 func makeConsensusParams( 162 blockBytes, blockGas int64, 163 blockTimeIotaMs int64, 164 evidenceAge int64, 165 ) types.ConsensusParams { 166 return types.ConsensusParams{ 167 Block: types.BlockParams{ 168 MaxBytes: blockBytes, 169 MaxGas: blockGas, 170 TimeIotaMs: blockTimeIotaMs, 171 }, 172 Evidence: types.EvidenceParams{ 173 MaxAgeNumBlocks: evidenceAge, 174 MaxAgeDuration: time.Duration(evidenceAge), 175 }, 176 } 177 } 178 179 func makeHeaderPartsResponsesValPubKeyChange( 180 state State, 181 pubkey crypto.PubKey, 182 ) (types.Header, types.BlockID, *ABCIResponses) { 183 184 block := makeBlock(state, state.LastBlockHeight+1) 185 abciResponses := &ABCIResponses{ 186 EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, 187 } 188 189 // If the pubkey is new, remove the old and add the new. 190 _, val := state.NextValidators.GetByIndex(0) 191 if !bytes.Equal(pubkey.Bytes(), val.PubKey.Bytes()) { 192 abciResponses.EndBlock = &abci.ResponseEndBlock{ 193 ValidatorUpdates: []abci.ValidatorUpdate{ 194 types.TM2PB.NewValidatorUpdate(val.PubKey, 0), 195 types.TM2PB.NewValidatorUpdate(pubkey, 10), 196 }, 197 } 198 } 199 200 return block.Header, types.BlockID{Hash: block.Hash(), PartsHeader: types.PartSetHeader{}}, abciResponses 201 } 202 203 func makeHeaderPartsResponsesValPowerChange( 204 state State, 205 power int64, 206 ) (types.Header, types.BlockID, *ABCIResponses) { 207 208 block := makeBlock(state, state.LastBlockHeight+1) 209 abciResponses := &ABCIResponses{ 210 EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, 211 } 212 213 // If the pubkey is new, remove the old and add the new. 214 _, val := state.NextValidators.GetByIndex(0) 215 if val.VotingPower != power { 216 abciResponses.EndBlock = &abci.ResponseEndBlock{ 217 ValidatorUpdates: []abci.ValidatorUpdate{ 218 types.TM2PB.NewValidatorUpdate(val.PubKey, power), 219 }, 220 } 221 } 222 223 return block.Header, types.BlockID{Hash: block.Hash(), PartsHeader: types.PartSetHeader{}}, abciResponses 224 } 225 226 func makeHeaderPartsResponsesParams( 227 state State, 228 params types.ConsensusParams, 229 ) (types.Header, types.BlockID, *ABCIResponses) { 230 231 block := makeBlock(state, state.LastBlockHeight+1) 232 abciResponses := &ABCIResponses{ 233 EndBlock: &abci.ResponseEndBlock{ConsensusParamUpdates: types.TM2PB.ConsensusParams(¶ms)}, 234 } 235 return block.Header, types.BlockID{Hash: block.Hash(), PartsHeader: types.PartSetHeader{}}, abciResponses 236 } 237 238 func randomGenesisDoc() *types.GenesisDoc { 239 pubkey := ed25519.GenPrivKey().PubKey() 240 return &types.GenesisDoc{ 241 GenesisTime: tmtime.Now(), 242 ChainID: "abc", 243 Validators: []types.GenesisValidator{ 244 { 245 Address: pubkey.Address(), 246 PubKey: pubkey, 247 Power: 10, 248 Name: "myval", 249 }, 250 }, 251 ConsensusParams: types.DefaultConsensusParams(), 252 } 253 } 254 255 //---------------------------------------------------------------------------- 256 257 type testApp struct { 258 abci.BaseApplication 259 260 CommitVotes []abci.VoteInfo 261 ByzantineValidators []abci.Evidence 262 ValidatorUpdates []abci.ValidatorUpdate 263 } 264 265 var _ abci.Application = (*testApp)(nil) 266 267 func (app *testApp) Info(req abci.RequestInfo) (resInfo abci.ResponseInfo) { 268 return abci.ResponseInfo{} 269 } 270 271 func (app *testApp) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginBlock { 272 app.CommitVotes = req.LastCommitInfo.Votes 273 app.ByzantineValidators = req.ByzantineValidators 274 return abci.ResponseBeginBlock{} 275 } 276 277 func (app *testApp) EndBlock(req abci.RequestEndBlock) abci.ResponseEndBlock { 278 return abci.ResponseEndBlock{ValidatorUpdates: app.ValidatorUpdates} 279 } 280 281 func (app *testApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx { 282 return abci.ResponseDeliverTx{Events: []abci.Event{}} 283 } 284 285 func (app *testApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { 286 return abci.ResponseCheckTx{} 287 } 288 289 func (app *testApp) Commit(abci.RequestCommit) abci.ResponseCommit { 290 return abci.ResponseCommit{} 291 } 292 293 func (app *testApp) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQuery) { 294 return 295 } 296 297 //---------------------------------------------------------------------------------------------------- 298 // Execute block without state. TODO: eliminate 299 300 // ExecCommitBlock executes and commits a block on the proxyApp without validating or mutating the state. 301 // It returns the application root hash (result of abci.Commit). 302 func ExecCommitBlock( 303 appConnConsensus proxy.AppConnConsensus, 304 block *types.Block, 305 logger log.Logger, 306 stateDB dbm.DB, 307 ) ([]byte, error) { 308 309 ctx := &executionTask{ 310 logger: logger, 311 block: block, 312 db: stateDB, 313 proxyApp: appConnConsensus, 314 } 315 316 _, err := execBlockOnProxyApp(ctx) 317 if err != nil { 318 logger.Error("Error executing block on proxy app", "height", block.Height, "err", err) 319 return nil, err 320 } 321 // Commit block, get hash back 322 res, err := appConnConsensus.CommitSync(abci.RequestCommit{}) 323 if err != nil { 324 logger.Error("Client error during proxyAppConn.CommitSync", "err", res) 325 return nil, err 326 } 327 // ResponseCommit has no error or log, just data 328 return res.Data, nil 329 } 330 331 func execCommitBlockDelta( 332 appConnConsensus proxy.AppConnConsensus, 333 block *types.Block, 334 logger log.Logger, 335 stateDB dbm.DB, 336 ) (*types.Deltas, []byte, error) { 337 iavl.SetProduceDelta(true) 338 types.UploadDelta = true 339 deltas := &types.Deltas{Height: block.Height} 340 341 ctx := &executionTask{ 342 logger: logger, 343 block: block, 344 db: stateDB, 345 proxyApp: appConnConsensus, 346 } 347 348 abciResponses, err := execBlockOnProxyApp(ctx) 349 if err != nil { 350 logger.Error("Error executing block on proxy app", "height", block.Height, "err", err) 351 return nil, nil, err 352 } 353 abciResponsesBytes, err := types.Json.Marshal(abciResponses) 354 if err != nil { 355 return nil, nil, err 356 } 357 deltas.Payload.ABCIRsp = abciResponsesBytes 358 359 // Commit block, get hash back 360 res, err := appConnConsensus.CommitSync(abci.RequestCommit{}) 361 if err != nil { 362 logger.Error("Client error during proxyAppConn.CommitSync", "err", res) 363 return nil, nil, err 364 } 365 366 if res.DeltaMap != nil { 367 deltaBytes, err := types.Json.Marshal(res.DeltaMap) 368 if err != nil { 369 return nil, nil, err 370 } 371 deltas.Payload.DeltasBytes = deltaBytes 372 wdFunc := evmWatchDataManager.CreateWatchDataGenerator() 373 if wd, err := wdFunc(); err == nil { 374 deltas.Payload.WatchBytes = wd 375 } 376 wasmWdFunc := wasmWatchDataManager.CreateWatchDataGenerator() 377 if wd, err := wasmWdFunc(); err == nil { 378 deltas.Payload.WasmWatchBytes = wd 379 } 380 } 381 382 // ResponseCommit has no error or log, just data 383 return deltas, res.Data, nil 384 }