light: added more tests for pruning, initialization and bisection (#4978)

This commit is contained in:
Callum Waters
2020-06-10 18:56:24 +02:00
committed by GitHub
parent 46f6d17601
commit b1dba352b0
3 changed files with 164 additions and 15 deletions

View File

@@ -62,6 +62,52 @@ var (
largeFullNode = mockp.New(GenMockNode(chainID, 10, 3, 0, bTime))
)
func TestValidateTrustOptions(t *testing.T) {
testCases := []struct {
err bool
to light.TrustOptions
}{
{
false,
trustOptions,
},
{
true,
light.TrustOptions{
Period: -1 * time.Hour,
Height: 1,
Hash: h1.Hash(),
},
},
{
true,
light.TrustOptions{
Period: 1 * time.Hour,
Height: 0,
Hash: h1.Hash(),
},
},
{
true,
light.TrustOptions{
Period: 1 * time.Hour,
Height: 1,
Hash: []byte("incorrect hash"),
},
},
}
for _, tc := range testCases {
err := tc.to.ValidateBasic()
if tc.err {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
}
}
func TestClient_SequentialVerification(t *testing.T) {
newKeys := genPrivKeys(4)
newVals := newKeys.ToValidators(10, 1)
@@ -296,8 +342,11 @@ func TestClient_SkippingVerification(t *testing.T) {
})
}
// start from a large header to make sure that the pivot height doesn't select a height outside
// the appropriate range
}
// start from a large header to make sure that the pivot height doesn't select a height outside
// the appropriate range
func TestClientLargeBisectionVerification(t *testing.T) {
veryLargeFullNode := mockp.New(GenMockNode(chainID, 100, 3, 1, bTime))
h1, err := veryLargeFullNode.SignedHeader(90)
require.NoError(t, err)
@@ -321,6 +370,34 @@ func TestClient_SkippingVerification(t *testing.T) {
assert.Equal(t, h, h2)
}
func TestClientBisectionBetweenTrustedHeaders(t *testing.T) {
c, err := light.NewClient(
chainID,
light.TrustOptions{
Period: 4 * time.Hour,
Height: 1,
Hash: h1.Hash(),
},
fullNode,
[]provider.Provider{fullNode},
dbs.New(dbm.NewMemDB(), chainID),
light.SkippingVerification(light.DefaultTrustLevel),
)
require.NoError(t, err)
_, err = c.VerifyHeaderAtHeight(3, bTime.Add(2*time.Hour))
require.NoError(t, err)
// confirm that the client already doesn't have the header
_, err = c.TrustedHeader(2)
require.Error(t, err)
// verify using bisection the header between the two trusted headers
_, err = c.VerifyHeaderAtHeight(2, bTime.Add(1*time.Hour))
assert.NoError(t, err)
}
func TestClient_Cleanup(t *testing.T) {
c, err := light.NewClient(
chainID,
@@ -514,12 +591,11 @@ func TestClientRestoresTrustedHeaderAfterStartup2(t *testing.T) {
func TestClientRestoresTrustedHeaderAfterStartup3(t *testing.T) {
// 1. options.Hash == trustedHeader.Hash
{
// load the first three headers into the trusted store
trustedStore := dbs.New(dbm.NewMemDB(), chainID)
err := trustedStore.SaveSignedHeaderAndValidatorSet(h1, vals)
require.NoError(t, err)
//header2 := keys.GenSignedHeader(chainID, 2, bTime.Add(2*time.Hour), nil, vals, vals,
// []byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys))
err = trustedStore.SaveSignedHeaderAndValidatorSet(h2, vals)
require.NoError(t, err)
@@ -554,6 +630,10 @@ func TestClientRestoresTrustedHeaderAfterStartup3(t *testing.T) {
valSet, _, err = c.TrustedValidatorSet(2)
assert.Error(t, err)
assert.Nil(t, valSet)
h, err = c.TrustedHeader(3)
assert.Error(t, err)
assert.Nil(t, h)
}
// 2. options.Hash != trustedHeader.Hash
@@ -907,26 +987,60 @@ func TestClientRemovesWitnessIfItSendsUsIncorrectHeader(t *testing.T) {
// header should still be verified
assert.EqualValues(t, 2, h.Height)
// no witnesses left to verify -> error
// remaining withness doesn't have header -> error
_, err = c.VerifyHeaderAtHeight(3, bTime.Add(2*time.Hour))
assert.Error(t, err)
if assert.Error(t, err) {
assert.Equal(t, "awaiting response from all witnesses exceeded dropout time", err.Error())
}
assert.EqualValues(t, 0, len(c.Witnesses()))
// no witnesses left, will not be allowed to verify a header
_, err = c.VerifyHeaderAtHeight(3, bTime.Add(2*time.Hour))
if assert.Error(t, err) {
assert.Equal(t, "no witnesses connected. please reset light client", err.Error())
}
}
func TestClientTrustedValidatorSet(t *testing.T) {
noValSetNode := mockp.New(
chainID,
headerSet,
map[int64]*types.ValidatorSet{
1: nil,
2: nil,
3: nil,
},
)
differentVals, _ := types.RandValidatorSet(10, 100)
badValSetNode := mockp.New(
chainID,
headerSet,
map[int64]*types.ValidatorSet{
1: vals,
2: differentVals,
3: differentVals,
},
)
c, err := light.NewClient(
chainID,
trustOptions,
fullNode,
[]provider.Provider{fullNode},
noValSetNode,
[]provider.Provider{badValSetNode, fullNode, fullNode},
dbs.New(dbm.NewMemDB(), chainID),
light.Logger(log.TestingLogger()),
)
require.NoError(t, err)
assert.Equal(t, 2, len(c.Witnesses()))
_, err = c.VerifyHeaderAtHeight(2, bTime.Add(2*time.Hour).Add(1*time.Second))
require.NoError(t, err)
assert.Error(t, err)
assert.Equal(t, 1, len(c.Witnesses()))
_, err = c.VerifyHeaderAtHeight(2, bTime.Add(2*time.Hour).Add(1*time.Second))
assert.NoError(t, err)
valSet, height, err := c.TrustedValidatorSet(0)
assert.NoError(t, err)
@@ -974,6 +1088,28 @@ func TestClientReportsConflictingHeadersEvidence(t *testing.T) {
assert.True(t, fullNode.HasEvidence(ev))
}
func TestClientPrunesHeadersAndValidatorSets(t *testing.T) {
c, err := light.NewClient(
chainID,
trustOptions,
fullNode,
[]provider.Provider{fullNode},
dbs.New(dbm.NewMemDB(), chainID),
light.Logger(log.TestingLogger()),
light.PruningSize(1),
)
require.NoError(t, err)
_, err = c.TrustedHeader(1)
require.NoError(t, err)
h, err := c.Update(bTime.Add(2 * time.Hour))
require.NoError(t, err)
require.Equal(t, int64(3), h.Height)
_, err = c.TrustedHeader(1)
assert.Error(t, err)
}
func TestClientEnsureValidHeadersAndValSets(t *testing.T) {
emptyValSet := &types.ValidatorSet{
Validators: nil,