Browse Source

lite2: actually run example tests + clock drift (#4487)

Closes: #4488

## Commits:

* run example tests

* introduce max clock drift

clockDrift variable from the spec.
10s should cover most of the clients.

References:

- http://vancouver-webpages.com/time/web.html
- https://blog.codinghorror.com/keeping-time-on-the-pc/

* fix ExampleClient_Update

* add test

* increase clock drift

* fix linter warning
pull/4485/head v0.33.1-dev2
Anton Kaliaev 4 years ago
committed by GitHub
parent
commit
3f883bb80a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 24 deletions
  1. +21
    -15
      lite2/example_test.go
  2. +8
    -3
      lite2/verifier.go
  3. +17
    -6
      lite2/verifier_test.go

+ 21
- 15
lite2/example_test.go View File

@ -11,7 +11,6 @@ import (
dbm "github.com/tendermint/tm-db"
"github.com/tendermint/tendermint/abci/example/kvstore"
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/lite2/provider"
httpp "github.com/tendermint/tendermint/lite2/provider/http"
dbs "github.com/tendermint/tendermint/lite2/store/db"
@ -19,7 +18,7 @@ import (
)
// Automatically getting new headers and verifying them.
func TestExample_Client_AutoUpdate(t *testing.T) {
func ExampleClient_Update() {
// give Tendermint time to generate some blocks
time.Sleep(5 * time.Second)
@ -57,10 +56,10 @@ func TestExample_Client_AutoUpdate(t *testing.T) {
Hash: header.Hash(),
},
primary,
[]provider.Provider{primary}, // TODO: primary should not be used here
[]provider.Provider{primary}, // NOTE: primary should not be used here
dbs.New(db, chainID),
UpdatePeriod(1*time.Second),
Logger(log.TestingLogger()),
UpdatePeriod(0), // NOTE: value should be greater than zero
// Logger(log.TestingLogger()),
)
if err != nil {
stdlog.Fatal(err)
@ -76,17 +75,29 @@ func TestExample_Client_AutoUpdate(t *testing.T) {
time.Sleep(2 * time.Second)
// XXX: 30 * time.Minute clock drift is needed because a) Tendermint strips
// monotonic component (see types/time/time.go) b) single instance is being
// run.
err = c.Update(time.Now().Add(30 * time.Minute))
if err != nil {
stdlog.Fatal(err)
}
h, err := c.TrustedHeader(0)
if err != nil {
stdlog.Fatal(err)
}
fmt.Println("got header", h.Height)
// Output: got header 3
if h.Height > 2 {
fmt.Println("successful update")
} else {
fmt.Println("update failed")
}
// Output: successful update
}
// Manually getting headers and verifying them.
func TestExample_Client_ManualUpdate(t *testing.T) {
func ExampleClient_VerifyHeaderAtHeight() {
// give Tendermint time to generate some blocks
time.Sleep(5 * time.Second)
@ -127,17 +138,12 @@ func TestExample_Client_ManualUpdate(t *testing.T) {
[]provider.Provider{primary}, // TODO: primary should not be used here
dbs.New(db, chainID),
UpdatePeriod(0),
Logger(log.TestingLogger()),
// Logger(log.TestingLogger()),
)
if err != nil {
stdlog.Fatal(err)
}
err = c.Start()
if err != nil {
stdlog.Fatal(err)
}
defer func() {
c.Stop()
c.Cleanup()
}()
@ -158,7 +164,7 @@ func TestExample_Client_ManualUpdate(t *testing.T) {
func TestMain(m *testing.M) {
// start a tendermint node (and kvstore) in the background to test against
app := kvstore.NewApplication()
node := rpctest.StartTendermint(app)
node := rpctest.StartTendermint(app, rpctest.SuppressStdout)
code := m.Run()


+ 8
- 3
lite2/verifier.go View File

@ -10,6 +10,10 @@ import (
"github.com/tendermint/tendermint/types"
)
const (
maxClockDrift = 10 * time.Second
)
var (
// DefaultTrustLevel - new header can be trusted if at least one correct
// validator signed it.
@ -162,10 +166,11 @@ func verifyNewHeaderAndVals(
trustedHeader.Time)
}
if !untrustedHeader.Time.Before(now) {
return errors.Errorf("new header has a time from the future %v (now: %v)",
if !untrustedHeader.Time.Before(now.Add(maxClockDrift)) {
return errors.Errorf("new header has a time from the future %v (now: %v; max clock drift: %v)",
untrustedHeader.Time,
now)
now,
maxClockDrift)
}
if !bytes.Equal(untrustedHeader.ValidatorsHash, untrustedVals.Hash()) {


+ 17
- 6
lite2/verifier_test.go View File

@ -75,8 +75,19 @@ func TestVerifyAdjacentHeaders(t *testing.T) {
nil,
"new header has a time from the future",
},
// 3/3 signed -> no error
// new header's time is from the future, but it's acceptable (< maxClockDrift) -> no error
4: {
keys.GenSignedHeader(chainID, nextHeight,
bTime.Add(2*time.Hour).Add(maxClockDrift).Add(-1*time.Millisecond), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)),
vals,
3 * time.Hour,
bTime.Add(2 * time.Hour),
nil,
"",
},
// 3/3 signed -> no error
5: {
keys.GenSignedHeader(chainID, nextHeight, bTime.Add(1*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)),
vals,
@ -86,7 +97,7 @@ func TestVerifyAdjacentHeaders(t *testing.T) {
"",
},
// 2/3 signed -> no error
5: {
6: {
keys.GenSignedHeader(chainID, nextHeight, bTime.Add(1*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 1, len(keys)),
vals,
@ -96,7 +107,7 @@ func TestVerifyAdjacentHeaders(t *testing.T) {
"",
},
// 1/3 signed -> error
6: {
7: {
keys.GenSignedHeader(chainID, nextHeight, bTime.Add(1*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), len(keys)-1, len(keys)),
vals,
@ -106,7 +117,7 @@ func TestVerifyAdjacentHeaders(t *testing.T) {
"",
},
// vals does not match with what we have -> error
7: {
8: {
keys.GenSignedHeader(chainID, nextHeight, bTime.Add(1*time.Hour), nil, keys.ToValidators(10, 1), vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)),
keys.ToValidators(10, 1),
@ -116,7 +127,7 @@ func TestVerifyAdjacentHeaders(t *testing.T) {
"to match those from new header",
},
// vals are inconsistent with newHeader -> error
8: {
9: {
keys.GenSignedHeader(chainID, nextHeight, bTime.Add(1*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)),
keys.ToValidators(10, 1),
@ -126,7 +137,7 @@ func TestVerifyAdjacentHeaders(t *testing.T) {
"to match those that were supplied",
},
// old header has expired -> error
9: {
10: {
keys.GenSignedHeader(chainID, nextHeight, bTime.Add(1*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)),
keys.ToValidators(10, 1),


Loading…
Cancel
Save