Skip to content

Commit

Permalink
Enable maverick node for e2e test (#301)
Browse files Browse the repository at this point in the history
* Update `e2e.App` and `marverick.App` with `Ostracon` features

* Enable maverick node
  • Loading branch information
tnasu authored Aug 10, 2021
1 parent 1132e00 commit 79b76eb
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 62 deletions.
1 change: 0 additions & 1 deletion test/e2e/app/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ type Config struct {
PrivValKey string `toml:"privval_key"`
PrivValState string `toml:"privval_state"`
Misbehaviors map[string]string `toml:"misbehaviors"`
KeyType string `toml:"key_type"`
}

// LoadConfig loads the configuration from disk.
Expand Down
3 changes: 2 additions & 1 deletion test/e2e/app/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,9 @@ func startMaverick(cfg *Config) error {
misbehaviors[height] = mcs.MisbehaviorList[misbehaviorString]
}

privKey, _ := maverick.LoadOrGenFilePV(tmcfg.PrivValidatorKeyFile(), tmcfg.PrivValidatorStateFile(), tmcfg.PrivKeyType)
n, err := maverick.NewNode(tmcfg,
maverick.LoadOrGenFilePV(tmcfg.PrivValidatorKeyFile(), tmcfg.PrivValidatorStateFile()),
privKey,
nodeKey,
proxy.NewLocalClientCreator(app),
maverick.DefaultGenesisDocProviderFunc(tmcfg),
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/networks/ci.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ seeds = ["seed01"]
seeds = ["seed01"]
snapshot_interval = 5
perturb = ["disconnect"]
#misbehaviors = { 1018 = "double-prevote" }
misbehaviors = { 1018 = "double-prevote" }

[node.validator02]
seeds = ["seed02"]
Expand Down
4 changes: 3 additions & 1 deletion test/maverick/consensus/misbehavior.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,9 +378,11 @@ func defaultReceiveProposal(cs *State, proposal *types.Proposal) error {
return ErrInvalidProposalPOLRound
}

proposer := cs.Validators.SelectProposer(cs.state.LastProofHash, proposal.Height, proposal.Round)

p := proposal.ToProto()
// Verify signature
if !cs.Proposer.PubKey.VerifySignature(
if !proposer.PubKey.VerifySignature(
types.ProposalSignBytes(cs.state.ChainID, p), proposal.Signature) {
return ErrInvalidProposalSignature
}
Expand Down
38 changes: 22 additions & 16 deletions test/maverick/consensus/reactor.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ type ReactorOption func(*Reactor)

// NewReactor returns a new Reactor with the given
// consensusState.
func NewReactor(consensusState *State, waitSync bool, options ...ReactorOption) *Reactor {
func NewReactor(consensusState *State, waitSync bool, async bool, recvBufSize int, options ...ReactorOption) *Reactor {
conR := &Reactor{
conS: consensusState,
waitSync: waitSync,
Metrics: tmcon.NopMetrics(),
}
conR.BaseReactor = *p2p.NewBaseReactor("Consensus", conR, true, 1000)
conR.BaseReactor = *p2p.NewBaseReactor("Consensus", conR, async, recvBufSize)

for _, option := range options {
option(conR)
Expand All @@ -75,6 +75,12 @@ func NewReactor(consensusState *State, waitSync bool, options ...ReactorOption)
func (conR *Reactor) OnStart() error {
conR.Logger.Info("Reactor ", "waitSync", conR.WaitSync())

// call BaseReactor's OnStart()
err := conR.BaseReactor.OnStart()
if err != nil {
return err
}

// start routine that computes peer statistics for evaluating peer quality
go conR.peerStatsRoutine()

Expand Down Expand Up @@ -331,9 +337,9 @@ func (conR *Reactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) {
case *tmcon.VoteMessage:
cs := conR.conS
cs.mtx.RLock()
height, valSize, lastCommitSize := cs.Height, cs.Validators.Size(), cs.LastCommit.Size()
height, voterSize, lastCommitSize := cs.Height, cs.Voters.Size(), cs.LastCommit.Size()
cs.mtx.RUnlock()
ps.EnsureVoteBitArrays(height, valSize)
ps.EnsureVoteBitArrays(height, voterSize)
ps.EnsureVoteBitArrays(height-1, lastCommitSize)
ps.SetHasVote(msg.Vote)

Expand Down Expand Up @@ -1135,7 +1141,7 @@ func (ps *PeerState) getVoteBitArray(height int64, round int32, votesType tmprot
}

// 'round': A round for which we have a +2/3 commit.
func (ps *PeerState) ensureCatchupCommitRound(height int64, round int32, numValidators int) {
func (ps *PeerState) ensureCatchupCommitRound(height int64, round int32, numVoters int) {
if ps.PRS.Height != height {
return
}
Expand All @@ -1159,37 +1165,37 @@ func (ps *PeerState) ensureCatchupCommitRound(height int64, round int32, numVali
if round == ps.PRS.Round {
ps.PRS.CatchupCommit = ps.PRS.Precommits
} else {
ps.PRS.CatchupCommit = bits.NewBitArray(numValidators)
ps.PRS.CatchupCommit = bits.NewBitArray(numVoters)
}
}

// EnsureVoteBitArrays ensures the bit-arrays have been allocated for tracking
// what votes this peer has received.
// NOTE: It's important to make sure that numValidators actually matches
// what the node sees as the number of validators for height.
func (ps *PeerState) EnsureVoteBitArrays(height int64, numValidators int) {
// NOTE: It's important to make sure that numVoters actually matches
// what the node sees as the number of voters for height.
func (ps *PeerState) EnsureVoteBitArrays(height int64, numVoters int) {
ps.mtx.Lock()
defer ps.mtx.Unlock()
ps.ensureVoteBitArrays(height, numValidators)
ps.ensureVoteBitArrays(height, numVoters)
}

func (ps *PeerState) ensureVoteBitArrays(height int64, numValidators int) {
func (ps *PeerState) ensureVoteBitArrays(height int64, numVoters int) {
if ps.PRS.Height == height {
if ps.PRS.Prevotes == nil {
ps.PRS.Prevotes = bits.NewBitArray(numValidators)
ps.PRS.Prevotes = bits.NewBitArray(numVoters)
}
if ps.PRS.Precommits == nil {
ps.PRS.Precommits = bits.NewBitArray(numValidators)
ps.PRS.Precommits = bits.NewBitArray(numVoters)
}
if ps.PRS.CatchupCommit == nil {
ps.PRS.CatchupCommit = bits.NewBitArray(numValidators)
ps.PRS.CatchupCommit = bits.NewBitArray(numVoters)
}
if ps.PRS.ProposalPOL == nil {
ps.PRS.ProposalPOL = bits.NewBitArray(numValidators)
ps.PRS.ProposalPOL = bits.NewBitArray(numVoters)
}
} else if ps.PRS.Height == height+1 {
if ps.PRS.LastCommit == nil {
ps.PRS.LastCommit = bits.NewBitArray(numValidators)
ps.PRS.LastCommit = bits.NewBitArray(numVoters)
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions test/maverick/consensus/replay.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ func (h *Handshaker) ReplayBlocks(
ChainId: h.genDoc.ChainID,
InitialHeight: h.genDoc.InitialHeight,
ConsensusParams: csParams,
Validators: nextVals,
Validators: nextVals, // ValidatorOrVoter: validator
AppStateBytes: h.genDoc.AppState,
}
res, err := proxyApp.Consensus().InitChainSync(req)
Expand All @@ -338,7 +338,9 @@ func (h *Handshaker) ReplayBlocks(
return nil, err
}
state.Validators = types.NewValidatorSet(vals)
state.NextValidators = types.NewValidatorSet(vals).CopyIncrementProposerPriority(1)
state.Voters = types.SelectVoter(state.Validators, h.genDoc.Hash(), state.VoterParams)
// Should sync it with MakeGenesisState()
state.NextValidators = types.NewValidatorSet(vals)
} else if len(h.genDoc.Validators) == 0 {
// If validator set is not set in genesis and still empty after InitChain, exit.
return nil, fmt.Errorf("validator set is nil in genesis and still empty after InitChain")
Expand Down
4 changes: 2 additions & 2 deletions test/maverick/consensus/replay_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,8 @@ func (pb *playback) replayConsoleLoop() int {
switch tokens[1] {
case "short":
fmt.Printf("%v/%v/%v\n", rs.Height, rs.Round, rs.Step)
case "validators":
fmt.Println(rs.Validators)
case "voters":
fmt.Println(rs.Voters)
case "proposal":
fmt.Println(rs.Proposal)
case "proposal_block":
Expand Down
26 changes: 12 additions & 14 deletions test/maverick/consensus/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,7 @@ func (cs *State) GetRoundStateSimpleJSON() ([]byte, error) {
}

// GetValidators returns a copy of the current validators.
// ValidatorOrVoter: validator
func (cs *State) GetValidators() (int64, []*types.Validator) {
cs.mtx.RLock()
defer cs.mtx.RUnlock()
Expand Down Expand Up @@ -899,7 +900,8 @@ func (cs *State) updateToState(state sm.State) {
cs.StartTime = cs.config.Commit(cs.CommitTime)
}

cs.Validators = validators
cs.Validators = state.Validators.Copy()
cs.Voters = state.Voters.Copy()
cs.Proposal = nil
cs.ProposalBlock = nil
cs.ProposalBlockParts = nil
Expand All @@ -913,6 +915,7 @@ func (cs *State) updateToState(state sm.State) {
cs.CommitRound = -1
cs.LastVoters = state.LastVoters
cs.TriggeredTimeoutPrecommit = false
cs.Proposer = validators.SelectProposer(state.LastProofHash, cs.Height, cs.Round)

cs.state = state

Expand Down Expand Up @@ -1120,18 +1123,13 @@ func (cs *State) enterNewRound(height int64, round int32) {

logger.Info(fmt.Sprintf("enterNewRound(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step))

// Increment validators if necessary
validators := cs.Validators
if cs.Round < round {
validators = validators.Copy()
validators.IncrementProposerPriority(tmmath.SafeSubInt32(round, cs.Round))
}
// Select the current height and round Proposer
cs.Proposer = cs.Validators.SelectProposer(cs.state.LastProofHash, height, round)

// Setup new round
// we don't fire newStep for this step,
// but we fire an event, so update the round step first
cs.updateRoundStep(round, cstypes.RoundStepNewRound)
cs.Validators = validators
if round == 0 {
// We've already reset these upon new height,
// and meanwhile we might have received a proposal
Expand Down Expand Up @@ -1192,7 +1190,7 @@ func (cs *State) defaultDecideProposal(height int64, round int32) {
block, blockParts = cs.ValidBlock, cs.ValidBlockParts
} else {
// Create a new proposal block from state/txs from the mempool.
block, blockParts = cs.createProposalBlock()
block, blockParts = cs.createProposalBlock(round)
if block == nil {
return
}
Expand Down Expand Up @@ -1247,7 +1245,7 @@ func (cs *State) isProposalComplete() bool {
//
// NOTE: keep it side-effect free for clarity.
// CONTRACT: cs.privValidator is not nil.
func (cs *State) createProposalBlock() (block *types.Block, blockParts *types.PartSet) {
func (cs *State) createProposalBlock(round int32) (block *types.Block, blockParts *types.PartSet) {
if cs.privValidator == nil {
panic("entered createProposalBlock with privValidator being nil")
}
Expand All @@ -1274,13 +1272,13 @@ func (cs *State) createProposalBlock() (block *types.Block, blockParts *types.Pa
}
proposerAddr := cs.privValidatorPubKey.Address()

message := cs.GetState().MakeHashMessage(cs.Round)
message := cs.state.MakeHashMessage(round)
proof, err := cs.privValidator.GenerateVRFProof(message)
if err != nil {
cs.Logger.Error(fmt.Sprintf("enterPropose: %v", err))
return
}
return cs.blockExec.CreateProposalBlock(cs.Height, cs.state, commit, proposerAddr, cs.Round, proof)
return cs.blockExec.CreateProposalBlock(cs.Height, cs.state, commit, proposerAddr, round, proof)
}

// Enter: any +2/3 prevotes at next round.
Expand Down Expand Up @@ -1858,8 +1856,8 @@ func (cs *State) signAddVote(msgType tmproto.SignedMsgType, hash []byte, header
return nil
}

// If the node not in the validator set, do nothing.
if !cs.Validators.HasAddress(cs.privValidatorPubKey.Address()) {
// If the node not in the voter set, do nothing.
if !cs.Voters.HasAddress(cs.privValidatorPubKey.Address()) {
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion test/maverick/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ func initFilesWithConfig(config *cfg.Config) error {
logger.Info("Found private validator", "keyFile", privValKeyFile,
"stateFile", privValStateFile)
} else {
pv = nd.GenFilePV(privValKeyFile, privValStateFile)
pv, _ = nd.GenFilePV(privValKeyFile, privValStateFile, config.PrivKeyType)
pv.Save()
logger.Info("Generated private validator", "keyFile", privValKeyFile,
"stateFile", privValStateFile)
Expand Down
27 changes: 22 additions & 5 deletions test/maverick/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,19 @@ type Provider func(*cfg.Config, log.Logger) (*Node, error)
func DefaultNewNode(config *cfg.Config, logger log.Logger, misbehaviors map[int64]cs.Misbehavior) (*Node, error) {
nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile())
if err != nil {
return nil, fmt.Errorf("failed to load or gen node key %s, err: %w", config.NodeKeyFile(), err)
return nil, fmt.Errorf("failed to load or gen node key %s: %w", config.NodeKeyFile(), err)
}

privKey, err := LoadOrGenFilePV(
config.PrivValidatorKeyFile(),
config.PrivValidatorStateFile(),
config.PrivValidatorKeyType())
if err != nil {
return nil, fmt.Errorf("failed to create a private key: %s", err)
}

return NewNode(config,
LoadOrGenFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile()),
privKey,
nodeKey,
proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()),
DefaultGenesisDocProviderFunc(config),
Expand Down Expand Up @@ -466,7 +474,8 @@ func createConsensusReactor(config *cfg.Config,
if privValidator != nil {
consensusState.SetPrivValidator(privValidator)
}
consensusReactor := cs.NewReactor(consensusState, waitSync, cs.ReactorMetrics(csMetrics))
consensusReactor := cs.NewReactor(consensusState, waitSync, config.P2P.RecvAsync, config.P2P.ConsensusRecvBufSize,
cs.ReactorMetrics(csMetrics))
consensusReactor.SetLogger(consensusLogger)
// services which will be publishing and/or subscribing for messages (events)
// consensusReactor will set it on consensusState and blockExecutor
Expand Down Expand Up @@ -618,6 +627,7 @@ func createPEXReactorAndAddToSwitch(addrBook pex.AddrBook, config *cfg.Config,
// https://github.com/tendermint/tendermint/issues/3523
SeedDisconnectWaitPeriod: 28 * time.Hour,
PersistentPeersMaxDialPeriod: config.P2P.PersistentPeersMaxDialPeriod,
RecvBufSize: config.P2P.PexRecvBufSize,
})
pexReactor.SetLogger(logger.With("module", "pex"))
sw.AddReactor("PEX", pexReactor)
Expand Down Expand Up @@ -648,11 +658,18 @@ func startStateSync(ssR *statesync.Reactor, bcR fastSyncReactor, conR *cs.Reacto
}

go func() {
state, _, commit, err := ssR.Sync(stateProvider, config.DiscoveryTime)
state, previousState, commit, err := ssR.Sync(stateProvider, config.DiscoveryTime)
if err != nil {
ssR.Logger.Error("State sync failed", "err", err)
return
}
if previousState.LastBlockHeight > 0 {
err = stateStore.Bootstrap(previousState)
if err != nil {
ssR.Logger.Error("Failed to bootstrap node with previous state", "err", err)
return
}
}
err = stateStore.Bootstrap(state)
if err != nil {
ssR.Logger.Error("Failed to bootstrap node with new state", "err", err)
Expand Down Expand Up @@ -813,7 +830,7 @@ func NewNode(config *cfg.Config,
// we should clean this whole thing up. See:
// https://github.com/tendermint/tendermint/issues/4644
stateSyncReactor := statesync.NewReactor(proxyApp.Snapshot(), proxyApp.Query(),
config.P2P.RecvAsync, config.P2P.BlockchainRecvBufSize)
config.P2P.RecvAsync, config.P2P.StatesyncRecvBufSize)
stateSyncReactor.SetLogger(logger.With("module", "statesync"))

nodeInfo, err := makeNodeInfo(config, nodeKey, txIndexer, genDoc, state)
Expand Down
Loading

0 comments on commit 79b76eb

Please sign in to comment.