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(&params)},
   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  }