Set first block time to now, fix evidence tests

This commit is contained in:
Anca Zamfir
2022-01-10 11:28:00 +01:00
parent 693bae7a29
commit 741dfea340
7 changed files with 26 additions and 67 deletions

View File

@@ -1319,7 +1319,7 @@ func (cs *State) proposalIsTimely() bool {
MessageDelay: cs.state.ConsensusParams.Timing.MessageDelay,
}
return cs.Proposal.IsTimely(cs.ProposalReceiveTime, tp, cs.state.InitialHeight)
return cs.Proposal.IsTimely(cs.ProposalReceiveTime, tp)
}
func (cs *State) defaultDoPrevote(height int64, round int32) {
@@ -1417,7 +1417,7 @@ func (cs *State) defaultDoPrevote(height int64, round int32) {
}
}
logger.Debug("prevote step: ProposalBlock is valid but was not our locked block or" +
logger.Debug("prevote step: ProposalBlock is valid but was not our locked block or " +
"did not receive a more recent majority; prevoting nil")
cs.signAddVote(tmproto.PrevoteType, nil, types.PartSetHeader{})
}

View File

@@ -263,18 +263,10 @@ func (state State) MakeBlock(
// Build base block with block data.
block := types.MakeBlock(height, txs, commit, evidence)
// Set time.
var timestamp time.Time
if height == state.InitialHeight {
timestamp = state.LastBlockTime // genesis time
} else {
timestamp = time.Now()
}
// Fill rest of header with state data.
block.Header.Populate(
state.Version.Consensus, state.ChainID,
timestamp, state.LastBlockID,
time.Now(), state.LastBlockID,
state.Validators.Hash(), state.NextValidators.Hash(),
state.ConsensusParams.HashConsensusParams(), state.AppHash, state.LastResultsHash,
proposerAddress,

View File

@@ -117,8 +117,8 @@ func validateBlock(state State, block *types.Block) error {
case block.Height == state.InitialHeight:
genesisTime := state.LastBlockTime
if !block.Time.Equal(genesisTime) {
return fmt.Errorf("block time %v is not equal to genesis time %v",
if block.Time.Before(genesisTime) {
return fmt.Errorf("block time %v is before genesis time %v",
block.Time,
genesisTime,
)

View File

@@ -15,15 +15,11 @@ import (
"github.com/tendermint/tendermint/types"
)
// For some reason the empty node used in tests has a time of
// 2018-10-10 08:20:13.695936996 +0000 UTC
// this is because the test genesis time is set here
// so in order to validate evidence we need evidence to be the same time
var defaultTestTime = time.Date(2018, 10, 10, 8, 20, 13, 695936996, time.UTC)
func newEvidence(t *testing.T, val *privval.FilePV,
vote *types.Vote, vote2 *types.Vote,
chainID string) *types.DuplicateVoteEvidence {
chainID string,
timestamp time.Time,
) *types.DuplicateVoteEvidence {
t.Helper()
var err error
@@ -39,7 +35,7 @@ func newEvidence(t *testing.T, val *privval.FilePV,
validator := types.NewValidator(val.Key.PubKey, 10)
valSet := types.NewValidatorSet([]*types.Validator{validator})
ev, err := types.NewDuplicateVoteEvidence(vote, vote2, defaultTestTime, valSet)
ev, err := types.NewDuplicateVoteEvidence(vote, vote2, timestamp, valSet)
require.NoError(t, err)
return ev
}
@@ -48,6 +44,7 @@ func makeEvidences(
t *testing.T,
val *privval.FilePV,
chainID string,
timestamp time.Time,
) (correct *types.DuplicateVoteEvidence, fakes []*types.DuplicateVoteEvidence) {
vote := types.Vote{
ValidatorAddress: val.Key.Address,
@@ -55,7 +52,7 @@ func makeEvidences(
Height: 1,
Round: 0,
Type: tmproto.PrevoteType,
Timestamp: defaultTestTime,
Timestamp: timestamp,
BlockID: types.BlockID{
Hash: tmhash.Sum(tmrand.Bytes(tmhash.Size)),
PartSetHeader: types.PartSetHeader{
@@ -67,7 +64,7 @@ func makeEvidences(
vote2 := vote
vote2.BlockID.Hash = tmhash.Sum([]byte("blockhash2"))
correct = newEvidence(t, val, &vote, &vote2, chainID)
correct = newEvidence(t, val, &vote, &vote2, chainID, timestamp)
fakes = make([]*types.DuplicateVoteEvidence, 0)
@@ -75,34 +72,34 @@ func makeEvidences(
{
v := vote2
v.ValidatorAddress = []byte("some_address")
fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID))
fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID, timestamp))
}
// different height
{
v := vote2
v.Height = vote.Height + 1
fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID))
fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID, timestamp))
}
// different round
{
v := vote2
v.Round = vote.Round + 1
fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID))
fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID, timestamp))
}
// different type
{
v := vote2
v.Type = tmproto.PrecommitType
fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID))
fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID, timestamp))
}
// exactly same vote
{
v := vote
fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID))
fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID, timestamp))
}
return correct, fakes

View File

@@ -516,10 +516,12 @@ func TestClientMethodCalls(t *testing.T) {
t.Run("BraodcastDuplicateVote", func(t *testing.T) {
chainID := conf.ChainID()
correct, fakes := makeEvidences(t, pv, chainID)
// make sure that the node has produced enough blocks
waitForBlock(ctx, t, c, 2)
evidenceHeight := int64(1)
block, _ := c.Block(ctx, &evidenceHeight)
ts := block.Block.Time
correct, fakes := makeEvidences(t, pv, chainID, ts)
result, err := c.BroadcastEvidence(ctx, correct)
require.NoError(t, err, "BroadcastEvidence(%s) failed", correct)

View File

@@ -89,18 +89,16 @@ func (p *Proposal) ValidateBasic() error {
//
// For more information on the meaning of 'timely', see the proposer-based timestamp specification:
// https://github.com/tendermint/spec/tree/master/spec/consensus/proposer-based-timestamp
func (p *Proposal) IsTimely(recvTime time.Time, tp TimingParams, initialHeight int64) bool {
func (p *Proposal) IsTimely(recvTime time.Time, tp TimingParams) bool {
// lhs is `proposedBlockTime - Precision` in the first inequality
lhs := p.Timestamp.Add(-tp.Precision)
// rhs is `proposedBlockTime + MsgDelay + Precision` in the second inequality
rhs := p.Timestamp.Add(tp.MessageDelay).Add(tp.Precision)
recvTimeAfterOrEqLHS := recvTime.After(lhs) || recvTime.Equal(lhs)
recvTimeBeforeOrEqRHS := recvTime.Before(rhs) || recvTime.Equal(rhs)
if recvTimeAfterOrEqLHS && (p.Height == initialHeight || recvTimeBeforeOrEqRHS) {
return true
if recvTime.Before(lhs) || recvTime.After(rhs) {
return false
}
return false
return true
}
// String returns a string representation of the Proposal.

View File

@@ -198,7 +198,6 @@ func TestIsTimely(t *testing.T) {
require.NoError(t, err)
testCases := []struct {
name string
genesisHeight int64
proposalHeight int64
proposalTime time.Time
recvTime time.Time
@@ -211,7 +210,6 @@ func TestIsTimely(t *testing.T) {
// Checking that the following inequality evaluates to true:
// 0 - 2 <= 1 <= 0 + 1 + 2
name: "basic timely",
genesisHeight: 1,
proposalHeight: 2,
proposalTime: genesisTime,
recvTime: genesisTime.Add(1 * time.Nanosecond),
@@ -223,7 +221,6 @@ func TestIsTimely(t *testing.T) {
// Checking that the following inequality evaluates to false:
// 0 - 2 <= 4 <= 0 + 1 + 2
name: "local time too large",
genesisHeight: 1,
proposalHeight: 2,
proposalTime: genesisTime,
recvTime: genesisTime.Add(4 * time.Nanosecond),
@@ -235,7 +232,6 @@ func TestIsTimely(t *testing.T) {
// Checking that the following inequality evaluates to false:
// 4 - 2 <= 0 <= 4 + 2 + 1
name: "proposal time too large",
genesisHeight: 1,
proposalHeight: 2,
proposalTime: genesisTime.Add(4 * time.Nanosecond),
recvTime: genesisTime,
@@ -243,32 +239,6 @@ func TestIsTimely(t *testing.T) {
msgDelay: time.Nanosecond,
expectTimely: false,
},
{
// Checking that the following inequality evaluates to true:
// 0 - 2 <= 4
// and the following check is skipped
// 4 <= 0 + 1 + 2
name: "local time too large but proposal is for genesis",
genesisHeight: 1,
proposalHeight: 1,
proposalTime: genesisTime,
recvTime: genesisTime.Add(4 * time.Nanosecond),
precision: time.Nanosecond * 2,
msgDelay: time.Nanosecond,
expectTimely: true,
},
{
// Checking that the following inequality evaluates to false:
// 4 - 2 <= 0
name: "proposal time too large for genesis block proposal",
genesisHeight: 1,
proposalHeight: 1,
proposalTime: genesisTime.Add(4 * time.Nanosecond),
recvTime: genesisTime,
precision: time.Nanosecond * 2,
msgDelay: time.Nanosecond,
expectTimely: false,
},
}
for _, testCase := range testCases {
@@ -283,7 +253,7 @@ func TestIsTimely(t *testing.T) {
MessageDelay: testCase.msgDelay,
}
ti := p.IsTimely(testCase.recvTime, tp, testCase.genesisHeight)
ti := p.IsTimely(testCase.recvTime, tp)
assert.Equal(t, testCase.expectTimely, ti)
})
}