types: implement Header#ValidateBasic (#4638)

- Move core stateless validation of the Header type to a ValidateBasic method.
- Call header.ValidateBasic during a SignedHeader validation.
- Call header.ValidateBasic during a PhantomValidatorEvidence validation.
- Call header.ValidateBasic during a LunaticValidatorEvidence validation.

lite tests are skipped since the package is deprecated, no need to waste time on it

closes: #4572

Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
This commit is contained in:
Alexander Bezobchuk
2020-04-24 11:45:38 +04:00
committed by GitHub
co-authored by Anton Kaliaev
parent 1f64430cb5
commit 9f29672e23
9 changed files with 196 additions and 144 deletions
+22 -22
View File
@@ -27,13 +27,13 @@ var (
vals = keys.ToValidators(20, 10)
bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z")
h1 = keys.GenSignedHeader(chainID, 1, bTime, nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys))
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys))
// 3/3 signed
h2 = keys.GenSignedHeaderLastBlockID(chainID, 2, bTime.Add(30*time.Minute), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys), types.BlockID{Hash: h1.Hash()})
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys), types.BlockID{Hash: h1.Hash()})
// 3/3 signed
h3 = keys.GenSignedHeaderLastBlockID(chainID, 3, bTime.Add(1*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys), types.BlockID{Hash: h2.Hash()})
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys), types.BlockID{Hash: h2.Hash()})
trustPeriod = 4 * time.Hour
trustOptions = lite.TrustOptions{
Period: 4 * time.Hour,
@@ -85,7 +85,7 @@ func TestClient_SequentialVerification(t *testing.T) {
map[int64]*types.SignedHeader{
// different header
1: keys.GenSignedHeader(chainID, 1, bTime.Add(1*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys)),
},
map[int64]*types.ValidatorSet{
1: vals,
@@ -100,10 +100,10 @@ func TestClient_SequentialVerification(t *testing.T) {
1: h1,
// interim header (1/3 signed)
2: keys.GenSignedHeader(chainID, 2, bTime.Add(1*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), len(keys)-1, len(keys)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), len(keys)-1, len(keys)),
// last header (3/3 signed)
3: keys.GenSignedHeader(chainID, 3, bTime.Add(2*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys)),
},
valSet,
false,
@@ -116,10 +116,10 @@ func TestClient_SequentialVerification(t *testing.T) {
1: h1,
// interim header (3/3 signed)
2: keys.GenSignedHeader(chainID, 2, bTime.Add(1*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys)),
// last header (1/3 signed)
3: keys.GenSignedHeader(chainID, 3, bTime.Add(2*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), len(keys)-1, len(keys)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), len(keys)-1, len(keys)),
},
valSet,
false,
@@ -209,7 +209,7 @@ func TestClient_SkippingVerification(t *testing.T) {
// trusted header
1: h1,
3: transitKeys.GenSignedHeader(chainID, 3, bTime.Add(2*time.Hour), nil, transitVals, transitVals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(transitKeys)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(transitKeys)),
},
map[int64]*types.ValidatorSet{
1: vals,
@@ -226,10 +226,10 @@ func TestClient_SkippingVerification(t *testing.T) {
1: h1,
// interim header (3/3 signed)
2: keys.GenSignedHeader(chainID, 2, bTime.Add(1*time.Hour), nil, vals, newVals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys)),
// last header (0/4 of the original val set signed)
3: newKeys.GenSignedHeader(chainID, 3, bTime.Add(2*time.Hour), nil, newVals, newVals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(newKeys)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(newKeys)),
},
map[int64]*types.ValidatorSet{
1: vals,
@@ -246,10 +246,10 @@ func TestClient_SkippingVerification(t *testing.T) {
1: h1,
// last header (0/4 of the original val set signed)
2: keys.GenSignedHeader(chainID, 2, bTime.Add(1*time.Hour), nil, vals, newVals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, 0),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, 0),
// last header (0/4 of the original val set signed)
3: newKeys.GenSignedHeader(chainID, 3, bTime.Add(2*time.Hour), nil, newVals, newVals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(newKeys)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(newKeys)),
},
map[int64]*types.ValidatorSet{
1: vals,
@@ -362,7 +362,7 @@ func TestClientRestoresTrustedHeaderAfterStartup1(t *testing.T) {
// header1 != header
header1 := keys.GenSignedHeader(chainID, 1, bTime.Add(1*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys))
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys))
primary := mockp.New(
chainID,
@@ -447,10 +447,10 @@ func TestClientRestoresTrustedHeaderAfterStartup2(t *testing.T) {
// header1 != header
diffHeader1 := keys.GenSignedHeader(chainID, 1, bTime.Add(1*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys))
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys))
diffHeader2 := keys.GenSignedHeader(chainID, 2, bTime.Add(2*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys))
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys))
primary := mockp.New(
chainID,
@@ -541,10 +541,10 @@ func TestClientRestoresTrustedHeaderAfterStartup3(t *testing.T) {
// header1 != header
header1 := keys.GenSignedHeader(chainID, 1, bTime.Add(1*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys))
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys))
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))
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys))
err = trustedStore.SaveSignedHeaderAndValidatorSet(header2, vals)
require.NoError(t, err)
@@ -748,7 +748,7 @@ func TestClient_BackwardsVerification(t *testing.T) {
map[int64]*types.SignedHeader{
1: h1,
2: keys.GenSignedHeader(chainID, 1, bTime.Add(1*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys)),
3: h3,
},
valSet,
@@ -761,7 +761,7 @@ func TestClient_BackwardsVerification(t *testing.T) {
map[int64]*types.SignedHeader{
1: h1,
2: keys.GenSignedHeader(chainID, 2, bTime.Add(30*time.Minute), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys)),
3: h3,
},
valSet,
@@ -841,7 +841,7 @@ func TestClientRemovesWitnessIfItSendsUsIncorrectHeader(t *testing.T) {
map[int64]*types.SignedHeader{
1: h1,
2: keys.GenSignedHeaderLastBlockID(chainID, 2, bTime.Add(30*time.Minute), nil, vals, vals,
[]byte("app_hash2"), []byte("cons_hash"), []byte("results_hash"),
hash("app_hash2"), hash("cons_hash"), hash("results_hash"),
len(keys), len(keys), types.BlockID{Hash: h1.Hash()}),
},
map[int64]*types.ValidatorSet{
@@ -913,7 +913,7 @@ func TestClientTrustedValidatorSet(t *testing.T) {
func TestClientReportsConflictingHeadersEvidence(t *testing.T) {
// fullNode2 sends us different header
altH2 := keys.GenSignedHeaderLastBlockID(chainID, 2, bTime.Add(30*time.Minute), nil, vals, vals,
[]byte("app_hash2"), []byte("cons_hash"), []byte("results_hash"),
hash("app_hash2"), hash("cons_hash"), hash("results_hash"),
0, len(keys), types.BlockID{Hash: h1.Hash()})
fullNode2 := mockp.New(
chainID,
+10 -4
View File
@@ -5,6 +5,7 @@ import (
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/types"
tmtime "github.com/tendermint/tendermint/types/time"
@@ -134,6 +135,7 @@ func genHeader(chainID string, height int64, bTime time.Time, txs types.Txs,
AppHash: appHash,
ConsensusHash: consHash,
LastResultsHash: resHash,
ProposerAddress: valset.Validators[0].Address,
}
}
@@ -194,8 +196,8 @@ func GenMockNode(
// genesis header and vals
lastHeader := keys.GenSignedHeader(chainID, 1, bTime.Add(1*time.Minute), nil,
keys.ToValidators(2, 2), newKeys.ToValidators(2, 2), []byte("app_hash"), []byte("cons_hash"),
[]byte("results_hash"), 0, len(keys))
keys.ToValidators(2, 2), newKeys.ToValidators(2, 2), hash("app_hash"), hash("cons_hash"),
hash("results_hash"), 0, len(keys))
currentHeader := lastHeader
headers[1] = currentHeader
valset[1] = keys.ToValidators(2, 2)
@@ -208,8 +210,8 @@ func GenMockNode(
newKeys = keys.ChangeKeys(valVariationInt)
currentHeader = keys.GenSignedHeaderLastBlockID(chainID, height, bTime.Add(time.Duration(height)*time.Minute),
nil,
keys.ToValidators(2, 2), newKeys.ToValidators(2, 2), []byte("app_hash"), []byte("cons_hash"),
[]byte("results_hash"), 0, len(keys), types.BlockID{Hash: lastHeader.Hash()})
keys.ToValidators(2, 2), newKeys.ToValidators(2, 2), hash("app_hash"), hash("cons_hash"),
hash("results_hash"), 0, len(keys), types.BlockID{Hash: lastHeader.Hash()})
headers[height] = currentHeader
valset[height] = keys.ToValidators(2, 2)
lastHeader = currentHeader
@@ -218,3 +220,7 @@ func GenMockNode(
return chainID, headers, valset
}
func hash(s string) []byte {
return tmhash.Sum([]byte(s))
}
+19 -19
View File
@@ -29,7 +29,7 @@ func TestVerifyAdjacentHeaders(t *testing.T) {
vals = keys.ToValidators(20, 10)
bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z")
header = keys.GenSignedHeader(chainID, lastHeight, bTime, nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys))
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys))
)
testCases := []struct {
@@ -52,7 +52,7 @@ func TestVerifyAdjacentHeaders(t *testing.T) {
// different chainID -> error
1: {
keys.GenSignedHeader("different-chainID", nextHeight, bTime.Add(1*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys)),
vals,
3 * time.Hour,
bTime.Add(2 * time.Hour),
@@ -62,7 +62,7 @@ func TestVerifyAdjacentHeaders(t *testing.T) {
// new header's time is before old header's time -> error
2: {
keys.GenSignedHeader(chainID, nextHeight, bTime.Add(-1*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys)),
vals,
3 * time.Hour,
bTime.Add(2 * time.Hour),
@@ -72,7 +72,7 @@ func TestVerifyAdjacentHeaders(t *testing.T) {
// new header's time is from the future -> error
3: {
keys.GenSignedHeader(chainID, nextHeight, bTime.Add(3*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys)),
vals,
3 * time.Hour,
bTime.Add(2 * time.Hour),
@@ -83,7 +83,7 @@ func TestVerifyAdjacentHeaders(t *testing.T) {
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)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys)),
vals,
3 * time.Hour,
bTime.Add(2 * time.Hour),
@@ -93,7 +93,7 @@ func TestVerifyAdjacentHeaders(t *testing.T) {
// 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)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys)),
vals,
3 * time.Hour,
bTime.Add(2 * time.Hour),
@@ -103,7 +103,7 @@ func TestVerifyAdjacentHeaders(t *testing.T) {
// 2/3 signed -> no error
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)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 1, len(keys)),
vals,
3 * time.Hour,
bTime.Add(2 * time.Hour),
@@ -113,7 +113,7 @@ func TestVerifyAdjacentHeaders(t *testing.T) {
// 1/3 signed -> error
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)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), len(keys)-1, len(keys)),
vals,
3 * time.Hour,
bTime.Add(2 * time.Hour),
@@ -123,7 +123,7 @@ func TestVerifyAdjacentHeaders(t *testing.T) {
// vals does not match with what we have -> error
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)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys)),
keys.ToValidators(10, 1),
3 * time.Hour,
bTime.Add(2 * time.Hour),
@@ -133,7 +133,7 @@ func TestVerifyAdjacentHeaders(t *testing.T) {
// vals are inconsistent with newHeader -> error
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)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys)),
keys.ToValidators(10, 1),
3 * time.Hour,
bTime.Add(2 * time.Hour),
@@ -143,7 +143,7 @@ func TestVerifyAdjacentHeaders(t *testing.T) {
// old header has expired -> error
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)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys)),
keys.ToValidators(10, 1),
1 * time.Hour,
bTime.Add(1 * time.Hour),
@@ -181,7 +181,7 @@ func TestVerifyNonAdjacentHeaders(t *testing.T) {
vals = keys.ToValidators(20, 10)
bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z")
header = keys.GenSignedHeader(chainID, lastHeight, bTime, nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys))
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys))
// 30, 40, 50
twoThirds = keys[1:]
@@ -207,7 +207,7 @@ func TestVerifyNonAdjacentHeaders(t *testing.T) {
// 3/3 new vals signed, 3/3 old vals present -> no error
0: {
keys.GenSignedHeader(chainID, 3, bTime.Add(1*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys)),
vals,
3 * time.Hour,
bTime.Add(2 * time.Hour),
@@ -217,7 +217,7 @@ func TestVerifyNonAdjacentHeaders(t *testing.T) {
// 2/3 new vals signed, 3/3 old vals present -> no error
1: {
keys.GenSignedHeader(chainID, 4, bTime.Add(1*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 1, len(keys)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 1, len(keys)),
vals,
3 * time.Hour,
bTime.Add(2 * time.Hour),
@@ -227,7 +227,7 @@ func TestVerifyNonAdjacentHeaders(t *testing.T) {
// 1/3 new vals signed, 3/3 old vals present -> error
2: {
keys.GenSignedHeader(chainID, 5, bTime.Add(1*time.Hour), nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), len(keys)-1, len(keys)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), len(keys)-1, len(keys)),
vals,
3 * time.Hour,
bTime.Add(2 * time.Hour),
@@ -237,7 +237,7 @@ func TestVerifyNonAdjacentHeaders(t *testing.T) {
// 3/3 new vals signed, 2/3 old vals present -> no error
3: {
twoThirds.GenSignedHeader(chainID, 5, bTime.Add(1*time.Hour), nil, twoThirdsVals, twoThirdsVals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(twoThirds)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(twoThirds)),
twoThirdsVals,
3 * time.Hour,
bTime.Add(2 * time.Hour),
@@ -247,7 +247,7 @@ func TestVerifyNonAdjacentHeaders(t *testing.T) {
// 3/3 new vals signed, 1/3 old vals present -> no error
4: {
oneThird.GenSignedHeader(chainID, 5, bTime.Add(1*time.Hour), nil, oneThirdVals, oneThirdVals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(oneThird)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(oneThird)),
oneThirdVals,
3 * time.Hour,
bTime.Add(2 * time.Hour),
@@ -257,7 +257,7 @@ func TestVerifyNonAdjacentHeaders(t *testing.T) {
// 3/3 new vals signed, less than 1/3 old vals present -> error
5: {
lessThanOneThird.GenSignedHeader(chainID, 5, bTime.Add(1*time.Hour), nil, lessThanOneThirdVals, lessThanOneThirdVals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(lessThanOneThird)),
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(lessThanOneThird)),
lessThanOneThirdVals,
3 * time.Hour,
bTime.Add(2 * time.Hour),
@@ -297,7 +297,7 @@ func TestVerifyReturnsErrorIfTrustLevelIsInvalid(t *testing.T) {
vals = keys.ToValidators(20, 10)
bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z")
header = keys.GenSignedHeader(chainID, lastHeight, bTime, nil, vals, vals,
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys))
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys))
)
err := lite.Verify(chainID, header, vals, header, vals, 2*time.Hour, time.Now(), maxClockDrift,