diff --git a/x/mock/simulation/random_simulate_blocks.go b/x/mock/simulation/random_simulate_blocks.go index 5b1d4030c902..adeec4163deb 100644 --- a/x/mock/simulation/random_simulate_blocks.go +++ b/x/mock/simulation/random_simulate_blocks.go @@ -67,14 +67,16 @@ func SimulateFromSeed( header := abci.Header{Height: 0, Time: timestamp} opCount := 0 - request := abci.RequestBeginBlock{Header: header} - var pastTimes []time.Time + var pastSigningValidators [][]abci.SigningValidator + + request := RandomRequestBeginBlock(t, r, validators, livenessTransitionMatrix, evidenceFraction, pastTimes, pastSigningValidators, event, header, log) for i := 0; i < numBlocks; i++ { // Log the header time for future lookup pastTimes = append(pastTimes, header.Time) + pastSigningValidators = append(pastSigningValidators, request.LastCommitInfo.Validators) // Run the BeginBlock handler app.BeginBlock(request) @@ -124,7 +126,7 @@ func SimulateFromSeed( } // Generate a random RequestBeginBlock with the current validator set for the next block - request = RandomRequestBeginBlock(t, r, validators, livenessTransitionMatrix, evidenceFraction, pastTimes, event, header, log) + request = RandomRequestBeginBlock(t, r, validators, livenessTransitionMatrix, evidenceFraction, pastTimes, pastSigningValidators, event, header, log) // Update the validator set validators = updateValidators(t, r, validators, res.ValidatorUpdates, event) @@ -147,13 +149,12 @@ func getKeys(validators map[string]mockValidator) []string { // RandomRequestBeginBlock generates a list of signing validators according to the provided list of validators, signing fraction, and evidence fraction func RandomRequestBeginBlock(t *testing.T, r *rand.Rand, validators map[string]mockValidator, livenessTransitions TransitionMatrix, evidenceFraction float64, - pastTimes []time.Time, event func(string), header abci.Header, log string) abci.RequestBeginBlock { + pastTimes []time.Time, pastSigningValidators [][]abci.SigningValidator, event func(string), header abci.Header, log string) abci.RequestBeginBlock { if len(validators) == 0 { return abci.RequestBeginBlock{Header: header} } signingValidators := make([]abci.SigningValidator, len(validators)) i := 0 - for _, key := range getKeys(validators) { mVal := validators[key] mVal.livenessState = livenessTransitions.NextState(r, mVal.livenessState) @@ -180,26 +181,30 @@ func RandomRequestBeginBlock(t *testing.T, r *rand.Rand, validators map[string]m i++ } evidence := make([]abci.Evidence, 0) - for r.Float64() < evidenceFraction { - height := header.Height - time := header.Time - if r.Float64() < pastEvidenceFraction { - height = int64(r.Intn(int(header.Height))) - time = pastTimes[height] - } - validator := signingValidators[r.Intn(len(signingValidators))].Validator - var currentTotalVotingPower int64 - for _, mVal := range validators { - currentTotalVotingPower += mVal.val.Power + // Anything but the first block + if len(pastTimes) > 0 { + for r.Float64() < evidenceFraction { + height := header.Height + time := header.Time + if r.Float64() < pastEvidenceFraction { + height = int64(r.Intn(int(header.Height))) + time = pastTimes[height] + } + past := pastSigningValidators[height] + validator := past[r.Intn(len(past))].Validator + var totalVotingPower int64 + for _, val := range past { + totalVotingPower += val.Validator.Power + } + evidence = append(evidence, abci.Evidence{ + Type: tmtypes.ABCIEvidenceTypeDuplicateVote, + Validator: validator, + Height: height, + Time: time, + TotalVotingPower: totalVotingPower, + }) + event("beginblock/evidence") } - evidence = append(evidence, abci.Evidence{ - Type: tmtypes.ABCIEvidenceTypeDuplicateVote, - Validator: validator, - Height: height, - Time: time, - TotalVotingPower: currentTotalVotingPower, - }) - event("beginblock/evidence") } return abci.RequestBeginBlock{ Header: header, diff --git a/x/slashing/slashing_period.go b/x/slashing/slashing_period.go index 528120f0f2fc..0e5806aee97b 100644 --- a/x/slashing/slashing_period.go +++ b/x/slashing/slashing_period.go @@ -35,8 +35,8 @@ func (k Keeper) getValidatorSlashingPeriodForHeight(ctx sdk.Context, address sdk panic("expected to find slashing period, but none was found") } slashingPeriod = k.unmarshalSlashingPeriodKeyValue(iterator.Key(), iterator.Value()) - if slashingPeriod.EndHeight < height { - panic("slashing period ended before infraction") + if slashingPeriod.EndHeight > 0 && slashingPeriod.EndHeight < height { + panic(fmt.Sprintf("slashing period ended before infraction: infraction height %d, slashing period ended at %d", height, slashingPeriod.EndHeight)) } return }