add proposal step waiting time with tests

This commit is contained in:
William Banfield
2021-11-15 16:45:52 -05:00
parent 12eb73d51d
commit 4a5e6da299
2 changed files with 75 additions and 1 deletions

View File

@@ -2424,3 +2424,19 @@ func proposerWaitTime(lt tmtime.Source, h types.Header) time.Duration {
}
return h.Time.Sub(t)
}
// proposalStepWaitingTime determines how long a validator should wait for a block
// to be sent from a proposer. This duration is determined as a result of the
// previous block's time as well as by the Accuracy and MsgDelay timestamp parameter.
// The validator and the proposer's clock should differ from eachother by at most
// 2 * Accuracy and the proposal should take at most MsgDelay to arrive at the validator.
// The validator must therefore wait at least 2 * Accuracy + MsgDelay for the proposal
// to arrive.
func proposalStepWaitingTime(lt tmtime.Source, h types.Header, tp types.TimestampParams) time.Duration {
t := lt.Now()
wt := h.Time.Add(2 * tp.Accuracy).Add(tp.MsgDelay)
if t.After(wt) {
return 0
}
return wt.Sub(t)
}

View File

@@ -2441,7 +2441,7 @@ func TestSignSameVoteTwice(t *testing.T) {
require.Equal(t, vote, vote2)
}
func TestProposerWaitUntil(t *testing.T) {
func TestProposerWaitTime(t *testing.T) {
genesisTime, err := time.Parse(time.RFC3339, "2019-03-13T23:00:00Z")
require.NoError(t, err)
testCases := []struct {
@@ -2486,6 +2486,64 @@ func TestProposerWaitUntil(t *testing.T) {
}
}
func TestProposalTimeout(t *testing.T) {
genesisTime, err := time.Parse(time.RFC3339, "2019-03-13T23:00:00Z")
require.NoError(t, err)
testCases := []struct {
name string
localTime time.Time
previousBlockTime time.Time
accuracy time.Duration
msgDelay time.Duration
expectedDuration time.Duration
}{
{
name: "MsgDelay + 2 * Accuracy has not quite elapsed",
localTime: genesisTime.Add(525 * time.Millisecond),
previousBlockTime: genesisTime.Add(6 * time.Millisecond),
accuracy: time.Millisecond * 10,
msgDelay: time.Millisecond * 500,
expectedDuration: 1 * time.Millisecond,
},
{
name: "MsgDelay + 2 * Accuracy equals current time",
localTime: genesisTime.Add(525 * time.Millisecond),
previousBlockTime: genesisTime.Add(5 * time.Millisecond),
accuracy: time.Millisecond * 10,
msgDelay: time.Millisecond * 500,
expectedDuration: 0,
},
{
name: "MsgDelay + 2 * Accuracy has elapsed",
localTime: genesisTime.Add(725 * time.Millisecond),
previousBlockTime: genesisTime.Add(5 * time.Millisecond),
accuracy: time.Millisecond * 10,
msgDelay: time.Millisecond * 500,
expectedDuration: 0,
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
b := types.Block{
Header: types.Header{
Time: testCase.previousBlockTime,
},
}
mockSource := new(tmtimemocks.Source)
mockSource.On("Now").Return(testCase.localTime)
tp := types.TimestampParams{
Accuracy: testCase.accuracy,
MsgDelay: testCase.msgDelay,
}
ti := proposalStepWaitingTime(mockSource, b.Header, tp)
assert.Equal(t, testCase.expectedDuration, ti)
})
}
}
// subscribe subscribes test client to the given query and returns a channel with cap = 1.
func subscribe(eventBus *types.EventBus, q tmpubsub.Query) <-chan tmpubsub.Message {
sub, err := eventBus.Subscribe(context.Background(), testSubscriber, q)