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