Skip to content

Commit 26dc17f

Browse files
committed
Add ValidateBlock tests for median time
1 parent c36a8ed commit 26dc17f

1 file changed

Lines changed: 178 additions & 0 deletions

File tree

state/validation_test.go

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package state_test
22

33
import (
4+
"strings"
45
"testing"
56
"time"
67

@@ -366,3 +367,180 @@ func TestValidateBlockEvidence(t *testing.T) {
366367

367368
}
368369
}
370+
371+
func TestValidateBlockMedianTime(t *testing.T) {
372+
proxyApp := newTestApp()
373+
require.NoError(t, proxyApp.Start())
374+
defer proxyApp.Stop() //nolint:errcheck // ignore for tests
375+
376+
state, stateDB, privVals := makeState(3, 1)
377+
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
378+
DiscardABCIResponses: false,
379+
})
380+
mp := &mpmocks.Mempool{}
381+
mp.On("Lock").Return()
382+
mp.On("Unlock").Return()
383+
mp.On("FlushAppConn", mock.Anything).Return(nil)
384+
mp.On("Update",
385+
mock.Anything,
386+
mock.Anything,
387+
mock.Anything,
388+
mock.Anything,
389+
mock.Anything,
390+
mock.Anything).Return(nil)
391+
392+
blockStore := store.NewBlockStore(dbm.NewMemDB())
393+
394+
blockExec := sm.NewBlockExecutor(
395+
stateStore,
396+
log.TestingLogger(),
397+
proxyApp.Consensus(),
398+
mp,
399+
sm.EmptyEvidencePool{},
400+
blockStore,
401+
)
402+
lastCommit := &types.Commit{}
403+
var lastExtCommit *types.ExtendedCommit
404+
405+
// Build up state for test
406+
for height := int64(1); height < 3; height++ {
407+
var err error
408+
state, _, lastExtCommit, err = makeAndCommitGoodBlock(
409+
state, height, lastCommit, state.Validators.GetProposer().Address, blockExec, privVals, nil)
410+
require.NoError(t, err, "height %d", height)
411+
lastCommit = lastExtCommit.ToCommit()
412+
}
413+
414+
// Now test invalid median times at height 3
415+
t.Run("block time before median time", func(t *testing.T) {
416+
height := int64(3)
417+
block, err := makeBlock(state, height, lastCommit)
418+
require.NoError(t, err)
419+
420+
// Set time to before the median time but after last block time
421+
// This requires the median to be after last block time
422+
block.Time = block.Time.Add(-time.Millisecond * 10)
423+
block.Header.Time = block.Time
424+
425+
err = blockExec.ValidateBlock(state, block)
426+
require.Error(t, err)
427+
// Could be either error depending on whether we went before last block time
428+
require.True(t,
429+
err.Error() == "invalid block time. Expected "+block.Time.Add(time.Millisecond*10).Format(time.RFC3339Nano)+", got "+block.Time.Format(time.RFC3339Nano) ||
430+
strings.Contains(err.Error(), "not greater than last block time") ||
431+
strings.Contains(err.Error(), "invalid block time"),
432+
"unexpected error: %v", err)
433+
})
434+
435+
t.Run("block time after median time", func(t *testing.T) {
436+
height := int64(3)
437+
block, err := makeBlock(state, height, lastCommit)
438+
require.NoError(t, err)
439+
440+
// Set time to after the median time
441+
block.Time = block.Time.Add(time.Second)
442+
block.Header.Time = block.Time
443+
444+
err = blockExec.ValidateBlock(state, block)
445+
require.Error(t, err)
446+
require.Contains(t, err.Error(), "invalid block time")
447+
})
448+
449+
t.Run("block time far in future", func(t *testing.T) {
450+
height := int64(3)
451+
block, err := makeBlock(state, height, lastCommit)
452+
require.NoError(t, err)
453+
454+
// Set time far in the future
455+
block.Time = block.Time.Add(time.Hour)
456+
block.Header.Time = block.Time
457+
458+
err = blockExec.ValidateBlock(state, block)
459+
require.Error(t, err)
460+
require.Contains(t, err.Error(), "invalid block time")
461+
})
462+
463+
t.Run("block time in past", func(t *testing.T) {
464+
height := int64(3)
465+
block, err := makeBlock(state, height, lastCommit)
466+
require.NoError(t, err)
467+
468+
// Set time to state.LastBlockTime (should fail because must be after)
469+
block.Time = state.LastBlockTime
470+
block.Header.Time = block.Time
471+
472+
err = blockExec.ValidateBlock(state, block)
473+
require.Error(t, err)
474+
require.Contains(t, err.Error(), "not greater than last block time")
475+
})
476+
}
477+
478+
func TestValidateBlockInvalidCommit(t *testing.T) {
479+
proxyApp := newTestApp()
480+
require.NoError(t, proxyApp.Start())
481+
defer proxyApp.Stop() //nolint:errcheck // ignore for tests
482+
483+
state, stateDB, privVals := makeState(3, 1)
484+
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
485+
DiscardABCIResponses: false,
486+
})
487+
mp := &mpmocks.Mempool{}
488+
mp.On("Lock").Return()
489+
mp.On("Unlock").Return()
490+
mp.On("FlushAppConn", mock.Anything).Return(nil)
491+
mp.On("Update",
492+
mock.Anything,
493+
mock.Anything,
494+
mock.Anything,
495+
mock.Anything,
496+
mock.Anything,
497+
mock.Anything).Return(nil)
498+
499+
blockStore := store.NewBlockStore(dbm.NewMemDB())
500+
501+
blockExec := sm.NewBlockExecutor(
502+
stateStore,
503+
log.TestingLogger(),
504+
proxyApp.Consensus(),
505+
mp,
506+
sm.EmptyEvidencePool{},
507+
blockStore,
508+
)
509+
lastCommit := &types.Commit{}
510+
var lastExtCommit *types.ExtendedCommit
511+
512+
// Build up state for test
513+
for height := int64(1); height < 3; height++ {
514+
var err error
515+
state, _, lastExtCommit, err = makeAndCommitGoodBlock(
516+
state, height, lastCommit, state.Validators.GetProposer().Address, blockExec, privVals, nil)
517+
require.NoError(t, err, "height %d", height)
518+
lastCommit = lastExtCommit.ToCommit()
519+
}
520+
521+
t.Run("commit with unknown validator flagged as commit", func(t *testing.T) {
522+
height := int64(3)
523+
524+
// Create a commit where only unknown validators have BlockIDFlagCommit
525+
unknownVal := ed25519.GenPrivKey()
526+
now := time.Now()
527+
528+
invalidCommit := &types.Commit{
529+
Height: height - 1,
530+
Round: 0,
531+
BlockID: state.LastBlockID,
532+
Signatures: []types.CommitSig{
533+
{
534+
BlockIDFlag: types.BlockIDFlagCommit,
535+
ValidatorAddress: unknownVal.PubKey().Address(),
536+
Timestamp: now,
537+
Signature: []byte("dummy"),
538+
},
539+
},
540+
}
541+
542+
_, err := makeBlock(state, height, invalidCommit)
543+
require.Error(t, err)
544+
require.Contains(t, err.Error(), "commit validator not found in validator set")
545+
})
546+
}

0 commit comments

Comments
 (0)