|
|
@ -17,19 +17,44 @@ import ( |
|
|
|
"github.com/tendermint/tendermint/types" |
|
|
|
) |
|
|
|
|
|
|
|
func TestClient_SequentialVerification(t *testing.T) { |
|
|
|
const ( |
|
|
|
chainID = "sequential-verification" |
|
|
|
) |
|
|
|
const ( |
|
|
|
chainID = "test" |
|
|
|
) |
|
|
|
|
|
|
|
var ( |
|
|
|
keys = genPrivKeys(4) |
|
|
|
// 20, 30, 40, 50 - the first 3 don't have 2/3, the last 3 do!
|
|
|
|
vals = keys.ToValidators(20, 10) |
|
|
|
bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z") |
|
|
|
header = keys.GenSignedHeader(chainID, 1, bTime, nil, vals, vals, |
|
|
|
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)) |
|
|
|
var ( |
|
|
|
keys = genPrivKeys(4) |
|
|
|
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)) |
|
|
|
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()}) |
|
|
|
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()}) |
|
|
|
trustPeriod = 4 * time.Hour |
|
|
|
trustOptions = TrustOptions{ |
|
|
|
Period: 4 * time.Hour, |
|
|
|
Height: 1, |
|
|
|
Hash: h1.Hash(), |
|
|
|
} |
|
|
|
fullNode = mockp.New( |
|
|
|
chainID, |
|
|
|
map[int64]*types.SignedHeader{ |
|
|
|
1: h1, |
|
|
|
2: h2, |
|
|
|
3: h3, |
|
|
|
}, |
|
|
|
map[int64]*types.ValidatorSet{ |
|
|
|
1: vals, |
|
|
|
2: vals, |
|
|
|
3: vals, |
|
|
|
4: vals, |
|
|
|
}, |
|
|
|
) |
|
|
|
deadNode = mockp.NewDeadMock(chainID) |
|
|
|
) |
|
|
|
|
|
|
|
func TestClient_SequentialVerification(t *testing.T) { |
|
|
|
|
|
|
|
testCases := []struct { |
|
|
|
otherHeaders map[int64]*types.SignedHeader // all except ^
|
|
|
@ -41,13 +66,11 @@ func TestClient_SequentialVerification(t *testing.T) { |
|
|
|
{ |
|
|
|
map[int64]*types.SignedHeader{ |
|
|
|
// trusted header
|
|
|
|
1: header, |
|
|
|
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)), |
|
|
|
2: h2, |
|
|
|
// 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)), |
|
|
|
3: h3, |
|
|
|
}, |
|
|
|
map[int64]*types.ValidatorSet{ |
|
|
|
1: vals, |
|
|
@ -75,7 +98,7 @@ func TestClient_SequentialVerification(t *testing.T) { |
|
|
|
{ |
|
|
|
map[int64]*types.SignedHeader{ |
|
|
|
// trusted header
|
|
|
|
1: header, |
|
|
|
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)), |
|
|
@ -96,7 +119,7 @@ func TestClient_SequentialVerification(t *testing.T) { |
|
|
|
{ |
|
|
|
map[int64]*types.SignedHeader{ |
|
|
|
// trusted header
|
|
|
|
1: header, |
|
|
|
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)), |
|
|
@ -118,11 +141,7 @@ func TestClient_SequentialVerification(t *testing.T) { |
|
|
|
for _, tc := range testCases { |
|
|
|
c, err := NewClient( |
|
|
|
chainID, |
|
|
|
TrustOptions{ |
|
|
|
Period: 4 * time.Hour, |
|
|
|
Height: 1, |
|
|
|
Hash: header.Hash(), |
|
|
|
}, |
|
|
|
trustOptions, |
|
|
|
mockp.New( |
|
|
|
chainID, |
|
|
|
tc.otherHeaders, |
|
|
@ -157,18 +176,6 @@ func TestClient_SequentialVerification(t *testing.T) { |
|
|
|
} |
|
|
|
|
|
|
|
func TestClient_SkippingVerification(t *testing.T) { |
|
|
|
const ( |
|
|
|
chainID = "skipping-verification" |
|
|
|
) |
|
|
|
|
|
|
|
var ( |
|
|
|
keys = genPrivKeys(4) |
|
|
|
// 20, 30, 40, 50 - the first 3 don't have 2/3, the last 3 do!
|
|
|
|
vals = keys.ToValidators(20, 10) |
|
|
|
bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z") |
|
|
|
header = keys.GenSignedHeader(chainID, 1, bTime, nil, vals, vals, |
|
|
|
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)) |
|
|
|
) |
|
|
|
|
|
|
|
// required for 2nd test case
|
|
|
|
newKeys := genPrivKeys(4) |
|
|
@ -177,17 +184,14 @@ func TestClient_SkippingVerification(t *testing.T) { |
|
|
|
testCases := []struct { |
|
|
|
otherHeaders map[int64]*types.SignedHeader // all except ^
|
|
|
|
vals map[int64]*types.ValidatorSet |
|
|
|
initErr bool |
|
|
|
verifyErr bool |
|
|
|
}{ |
|
|
|
// good
|
|
|
|
{ |
|
|
|
map[int64]*types.SignedHeader{ |
|
|
|
// trusted header
|
|
|
|
1: header, |
|
|
|
1: h1, |
|
|
|
// 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)), |
|
|
|
3: h3, |
|
|
|
}, |
|
|
|
map[int64]*types.ValidatorSet{ |
|
|
|
1: vals, |
|
|
@ -195,14 +199,12 @@ func TestClient_SkippingVerification(t *testing.T) { |
|
|
|
3: vals, |
|
|
|
4: vals, |
|
|
|
}, |
|
|
|
false, |
|
|
|
false, |
|
|
|
}, |
|
|
|
// good, val set changes 100% at height 2
|
|
|
|
{ |
|
|
|
map[int64]*types.SignedHeader{ |
|
|
|
// trusted header
|
|
|
|
1: header, |
|
|
|
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)), |
|
|
@ -216,19 +218,13 @@ func TestClient_SkippingVerification(t *testing.T) { |
|
|
|
3: newVals, |
|
|
|
4: newVals, |
|
|
|
}, |
|
|
|
false, |
|
|
|
false, |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
for _, tc := range testCases { |
|
|
|
c, err := NewClient( |
|
|
|
chainID, |
|
|
|
TrustOptions{ |
|
|
|
Period: 4 * time.Hour, |
|
|
|
Height: 1, |
|
|
|
Hash: header.Hash(), |
|
|
|
}, |
|
|
|
trustOptions, |
|
|
|
mockp.New( |
|
|
|
chainID, |
|
|
|
tc.otherHeaders, |
|
|
@ -242,68 +238,23 @@ func TestClient_SkippingVerification(t *testing.T) { |
|
|
|
dbs.New(dbm.NewMemDB(), chainID), |
|
|
|
SkippingVerification(DefaultTrustLevel), |
|
|
|
) |
|
|
|
if tc.initErr { |
|
|
|
require.Error(t, err) |
|
|
|
continue |
|
|
|
} else { |
|
|
|
require.NoError(t, err) |
|
|
|
} |
|
|
|
require.NoError(t, err) |
|
|
|
err = c.Start() |
|
|
|
require.NoError(t, err) |
|
|
|
defer c.Stop() |
|
|
|
|
|
|
|
_, err = c.VerifyHeaderAtHeight(3, bTime.Add(3*time.Hour)) |
|
|
|
if tc.verifyErr { |
|
|
|
assert.Error(t, err) |
|
|
|
} else { |
|
|
|
assert.NoError(t, err) |
|
|
|
} |
|
|
|
assert.NoError(t, err) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
func TestClientRemovesNoLongerTrustedHeaders(t *testing.T) { |
|
|
|
const ( |
|
|
|
chainID = "TestClientRemovesNoLongerTrustedHeaders" |
|
|
|
) |
|
|
|
|
|
|
|
var ( |
|
|
|
keys = genPrivKeys(4) |
|
|
|
// 20, 30, 40, 50 - the first 3 don't have 2/3, the last 3 do!
|
|
|
|
vals = keys.ToValidators(20, 10) |
|
|
|
bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z") |
|
|
|
header = keys.GenSignedHeader(chainID, 1, bTime, nil, vals, vals, |
|
|
|
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)) |
|
|
|
) |
|
|
|
|
|
|
|
primary := mockp.New( |
|
|
|
chainID, |
|
|
|
map[int64]*types.SignedHeader{ |
|
|
|
// trusted header
|
|
|
|
1: header, |
|
|
|
// interim header (3/3 signed)
|
|
|
|
2: keys.GenSignedHeader(chainID, 2, bTime.Add(2*time.Hour), nil, vals, vals, |
|
|
|
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)), |
|
|
|
// last header (3/3 signed)
|
|
|
|
3: keys.GenSignedHeader(chainID, 3, bTime.Add(4*time.Hour), nil, vals, vals, |
|
|
|
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)), |
|
|
|
}, |
|
|
|
map[int64]*types.ValidatorSet{ |
|
|
|
1: vals, |
|
|
|
2: vals, |
|
|
|
3: vals, |
|
|
|
4: vals, |
|
|
|
}, |
|
|
|
) |
|
|
|
|
|
|
|
c, err := NewClient( |
|
|
|
chainID, |
|
|
|
TrustOptions{ |
|
|
|
Period: 4 * time.Hour, |
|
|
|
Height: 1, |
|
|
|
Hash: header.Hash(), |
|
|
|
}, |
|
|
|
primary, |
|
|
|
[]provider.Provider{primary}, |
|
|
|
trustOptions, |
|
|
|
fullNode, |
|
|
|
[]provider.Provider{fullNode}, |
|
|
|
dbs.New(dbm.NewMemDB(), chainID), |
|
|
|
Logger(log.TestingLogger()), |
|
|
|
) |
|
|
@ -340,40 +291,12 @@ func TestClientRemovesNoLongerTrustedHeaders(t *testing.T) { |
|
|
|
} |
|
|
|
|
|
|
|
func TestClient_Cleanup(t *testing.T) { |
|
|
|
const ( |
|
|
|
chainID = "TestClient_Cleanup" |
|
|
|
) |
|
|
|
|
|
|
|
var ( |
|
|
|
keys = genPrivKeys(4) |
|
|
|
// 20, 30, 40, 50 - the first 3 don't have 2/3, the last 3 do!
|
|
|
|
vals = keys.ToValidators(20, 10) |
|
|
|
bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z") |
|
|
|
header = keys.GenSignedHeader(chainID, 1, bTime, nil, vals, vals, |
|
|
|
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)) |
|
|
|
) |
|
|
|
|
|
|
|
primary := mockp.New( |
|
|
|
chainID, |
|
|
|
map[int64]*types.SignedHeader{ |
|
|
|
// trusted header
|
|
|
|
1: header, |
|
|
|
}, |
|
|
|
map[int64]*types.ValidatorSet{ |
|
|
|
1: vals, |
|
|
|
2: vals, |
|
|
|
}, |
|
|
|
) |
|
|
|
|
|
|
|
c, err := NewClient( |
|
|
|
chainID, |
|
|
|
TrustOptions{ |
|
|
|
Period: 4 * time.Hour, |
|
|
|
Height: 1, |
|
|
|
Hash: header.Hash(), |
|
|
|
}, |
|
|
|
primary, |
|
|
|
[]provider.Provider{primary}, |
|
|
|
trustOptions, |
|
|
|
fullNode, |
|
|
|
[]provider.Provider{fullNode}, |
|
|
|
dbs.New(dbm.NewMemDB(), chainID), |
|
|
|
Logger(log.TestingLogger()), |
|
|
|
) |
|
|
@ -392,46 +315,18 @@ func TestClient_Cleanup(t *testing.T) { |
|
|
|
|
|
|
|
// trustedHeader.Height == options.Height
|
|
|
|
func TestClientRestoreTrustedHeaderAfterStartup1(t *testing.T) { |
|
|
|
const ( |
|
|
|
chainID = "TestClientRestoreTrustedHeaderAfterStartup1" |
|
|
|
) |
|
|
|
|
|
|
|
var ( |
|
|
|
keys = genPrivKeys(4) |
|
|
|
// 20, 30, 40, 50 - the first 3 don't have 2/3, the last 3 do!
|
|
|
|
vals = keys.ToValidators(20, 10) |
|
|
|
bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z") |
|
|
|
header = keys.GenSignedHeader(chainID, 1, bTime, nil, vals, vals, |
|
|
|
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)) |
|
|
|
) |
|
|
|
|
|
|
|
// 1. options.Hash == trustedHeader.Hash
|
|
|
|
{ |
|
|
|
trustedStore := dbs.New(dbm.NewMemDB(), chainID) |
|
|
|
err := trustedStore.SaveSignedHeaderAndNextValidatorSet(header, vals) |
|
|
|
err := trustedStore.SaveSignedHeaderAndNextValidatorSet(h1, vals) |
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
primary := mockp.New( |
|
|
|
chainID, |
|
|
|
map[int64]*types.SignedHeader{ |
|
|
|
// trusted header
|
|
|
|
1: header, |
|
|
|
}, |
|
|
|
map[int64]*types.ValidatorSet{ |
|
|
|
1: vals, |
|
|
|
2: vals, |
|
|
|
}, |
|
|
|
) |
|
|
|
|
|
|
|
c, err := NewClient( |
|
|
|
chainID, |
|
|
|
TrustOptions{ |
|
|
|
Period: 4 * time.Hour, |
|
|
|
Height: 1, |
|
|
|
Hash: header.Hash(), |
|
|
|
}, |
|
|
|
primary, |
|
|
|
[]provider.Provider{primary}, |
|
|
|
trustOptions, |
|
|
|
fullNode, |
|
|
|
[]provider.Provider{fullNode}, |
|
|
|
trustedStore, |
|
|
|
Logger(log.TestingLogger()), |
|
|
|
) |
|
|
@ -443,13 +338,13 @@ func TestClientRestoreTrustedHeaderAfterStartup1(t *testing.T) { |
|
|
|
h, err := c.TrustedHeader(1, bTime.Add(1*time.Second)) |
|
|
|
assert.NoError(t, err) |
|
|
|
assert.NotNil(t, h) |
|
|
|
assert.Equal(t, h.Hash(), header.Hash()) |
|
|
|
assert.Equal(t, h.Hash(), h1.Hash()) |
|
|
|
} |
|
|
|
|
|
|
|
// 2. options.Hash != trustedHeader.Hash
|
|
|
|
{ |
|
|
|
trustedStore := dbs.New(dbm.NewMemDB(), chainID) |
|
|
|
err := trustedStore.SaveSignedHeaderAndNextValidatorSet(header, vals) |
|
|
|
err := trustedStore.SaveSignedHeaderAndNextValidatorSet(h1, vals) |
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
// header1 != header
|
|
|
@ -494,49 +389,22 @@ func TestClientRestoreTrustedHeaderAfterStartup1(t *testing.T) { |
|
|
|
|
|
|
|
// trustedHeader.Height < options.Height
|
|
|
|
func TestClientRestoreTrustedHeaderAfterStartup2(t *testing.T) { |
|
|
|
const ( |
|
|
|
chainID = "TestClientRestoreTrustedHeaderAfterStartup2" |
|
|
|
) |
|
|
|
|
|
|
|
var ( |
|
|
|
keys = genPrivKeys(4) |
|
|
|
// 20, 30, 40, 50 - the first 3 don't have 2/3, the last 3 do!
|
|
|
|
vals = keys.ToValidators(20, 10) |
|
|
|
bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z") |
|
|
|
header = keys.GenSignedHeader(chainID, 1, bTime, nil, vals, vals, |
|
|
|
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)) |
|
|
|
) |
|
|
|
|
|
|
|
// 1. options.Hash == trustedHeader.Hash
|
|
|
|
{ |
|
|
|
trustedStore := dbs.New(dbm.NewMemDB(), chainID) |
|
|
|
err := trustedStore.SaveSignedHeaderAndNextValidatorSet(header, vals) |
|
|
|
err := trustedStore.SaveSignedHeaderAndNextValidatorSet(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)) |
|
|
|
|
|
|
|
primary := mockp.New( |
|
|
|
chainID, |
|
|
|
map[int64]*types.SignedHeader{ |
|
|
|
1: header, |
|
|
|
2: header2, |
|
|
|
}, |
|
|
|
map[int64]*types.ValidatorSet{ |
|
|
|
1: vals, |
|
|
|
2: vals, |
|
|
|
3: vals, |
|
|
|
}, |
|
|
|
) |
|
|
|
c, err := NewClient( |
|
|
|
chainID, |
|
|
|
TrustOptions{ |
|
|
|
Period: 4 * time.Hour, |
|
|
|
Height: 2, |
|
|
|
Hash: header2.Hash(), |
|
|
|
Hash: h2.Hash(), |
|
|
|
}, |
|
|
|
primary, |
|
|
|
[]provider.Provider{primary}, |
|
|
|
fullNode, |
|
|
|
[]provider.Provider{fullNode}, |
|
|
|
trustedStore, |
|
|
|
Logger(log.TestingLogger()), |
|
|
|
) |
|
|
@ -549,28 +417,28 @@ func TestClientRestoreTrustedHeaderAfterStartup2(t *testing.T) { |
|
|
|
h, err := c.TrustedHeader(1, bTime.Add(2*time.Hour).Add(1*time.Second)) |
|
|
|
assert.NoError(t, err) |
|
|
|
assert.NotNil(t, h) |
|
|
|
assert.Equal(t, h.Hash(), header.Hash()) |
|
|
|
assert.Equal(t, h.Hash(), h1.Hash()) |
|
|
|
} |
|
|
|
|
|
|
|
// 2. options.Hash != trustedHeader.Hash
|
|
|
|
// This could happen if previous provider was lying to us.
|
|
|
|
{ |
|
|
|
trustedStore := dbs.New(dbm.NewMemDB(), chainID) |
|
|
|
err := trustedStore.SaveSignedHeaderAndNextValidatorSet(header, vals) |
|
|
|
err := trustedStore.SaveSignedHeaderAndNextValidatorSet(h1, vals) |
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
// header1 != header
|
|
|
|
header1 := keys.GenSignedHeader(chainID, 1, bTime.Add(1*time.Hour), nil, vals, vals, |
|
|
|
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)) |
|
|
|
|
|
|
|
header2 := keys.GenSignedHeader(chainID, 2, bTime.Add(2*time.Hour), nil, vals, vals, |
|
|
|
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)) |
|
|
|
|
|
|
|
primary := mockp.New( |
|
|
|
chainID, |
|
|
|
map[int64]*types.SignedHeader{ |
|
|
|
1: header1, |
|
|
|
2: header2, |
|
|
|
1: diffHeader1, |
|
|
|
2: diffHeader2, |
|
|
|
}, |
|
|
|
map[int64]*types.ValidatorSet{ |
|
|
|
1: vals, |
|
|
@ -584,7 +452,7 @@ func TestClientRestoreTrustedHeaderAfterStartup2(t *testing.T) { |
|
|
|
TrustOptions{ |
|
|
|
Period: 4 * time.Hour, |
|
|
|
Height: 2, |
|
|
|
Hash: header2.Hash(), |
|
|
|
Hash: diffHeader2.Hash(), |
|
|
|
}, |
|
|
|
primary, |
|
|
|
[]provider.Provider{primary}, |
|
|
@ -605,35 +473,23 @@ func TestClientRestoreTrustedHeaderAfterStartup2(t *testing.T) { |
|
|
|
|
|
|
|
// trustedHeader.Height > options.Height
|
|
|
|
func TestClientRestoreTrustedHeaderAfterStartup3(t *testing.T) { |
|
|
|
const ( |
|
|
|
chainID = "TestClientRestoreTrustedHeaderAfterStartup3" |
|
|
|
) |
|
|
|
|
|
|
|
var ( |
|
|
|
keys = genPrivKeys(4) |
|
|
|
// 20, 30, 40, 50 - the first 3 don't have 2/3, the last 3 do!
|
|
|
|
vals = keys.ToValidators(20, 10) |
|
|
|
bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z") |
|
|
|
header = keys.GenSignedHeader(chainID, 1, bTime, nil, vals, vals, |
|
|
|
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)) |
|
|
|
) |
|
|
|
|
|
|
|
// 1. options.Hash == trustedHeader.Hash
|
|
|
|
{ |
|
|
|
trustedStore := dbs.New(dbm.NewMemDB(), chainID) |
|
|
|
err := trustedStore.SaveSignedHeaderAndNextValidatorSet(header, vals) |
|
|
|
err := trustedStore.SaveSignedHeaderAndNextValidatorSet(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.SaveSignedHeaderAndNextValidatorSet(header2, vals) |
|
|
|
//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.SaveSignedHeaderAndNextValidatorSet(h2, vals) |
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
primary := mockp.New( |
|
|
|
chainID, |
|
|
|
map[int64]*types.SignedHeader{ |
|
|
|
1: header, |
|
|
|
2: header2, |
|
|
|
1: h1, |
|
|
|
2: h2, |
|
|
|
}, |
|
|
|
map[int64]*types.ValidatorSet{ |
|
|
|
1: vals, |
|
|
@ -644,11 +500,7 @@ func TestClientRestoreTrustedHeaderAfterStartup3(t *testing.T) { |
|
|
|
|
|
|
|
c, err := NewClient( |
|
|
|
chainID, |
|
|
|
TrustOptions{ |
|
|
|
Period: 4 * time.Hour, |
|
|
|
Height: 1, |
|
|
|
Hash: header.Hash(), |
|
|
|
}, |
|
|
|
trustOptions, |
|
|
|
primary, |
|
|
|
[]provider.Provider{primary}, |
|
|
|
trustedStore, |
|
|
@ -663,7 +515,7 @@ func TestClientRestoreTrustedHeaderAfterStartup3(t *testing.T) { |
|
|
|
h, err := c.TrustedHeader(1, bTime.Add(2*time.Hour).Add(1*time.Second)) |
|
|
|
assert.NoError(t, err) |
|
|
|
assert.NotNil(t, h) |
|
|
|
assert.Equal(t, h.Hash(), header.Hash()) |
|
|
|
assert.Equal(t, h.Hash(), h1.Hash()) |
|
|
|
|
|
|
|
// Check we no longer have 2nd header (+header2+).
|
|
|
|
h, err = c.TrustedHeader(2, bTime.Add(2*time.Hour).Add(1*time.Second)) |
|
|
@ -675,7 +527,7 @@ func TestClientRestoreTrustedHeaderAfterStartup3(t *testing.T) { |
|
|
|
// This could happen if previous provider was lying to us.
|
|
|
|
{ |
|
|
|
trustedStore := dbs.New(dbm.NewMemDB(), chainID) |
|
|
|
err := trustedStore.SaveSignedHeaderAndNextValidatorSet(header, vals) |
|
|
|
err := trustedStore.SaveSignedHeaderAndNextValidatorSet(h1, vals) |
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
// header1 != header
|
|
|
@ -729,48 +581,12 @@ func TestClientRestoreTrustedHeaderAfterStartup3(t *testing.T) { |
|
|
|
} |
|
|
|
|
|
|
|
func TestClient_Update(t *testing.T) { |
|
|
|
const ( |
|
|
|
chainID = "TestClient_Update" |
|
|
|
) |
|
|
|
|
|
|
|
var ( |
|
|
|
keys = genPrivKeys(4) |
|
|
|
// 20, 30, 40, 50 - the first 3 don't have 2/3, the last 3 do!
|
|
|
|
vals = keys.ToValidators(20, 10) |
|
|
|
bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z") |
|
|
|
header = keys.GenSignedHeader(chainID, 1, bTime, nil, vals, vals, |
|
|
|
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)) |
|
|
|
) |
|
|
|
|
|
|
|
primary := mockp.New( |
|
|
|
chainID, |
|
|
|
map[int64]*types.SignedHeader{ |
|
|
|
// trusted header
|
|
|
|
1: header, |
|
|
|
// interim header (3/3 signed)
|
|
|
|
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)), |
|
|
|
// last header (3/3 signed)
|
|
|
|
3: keys.GenSignedHeader(chainID, 3, bTime.Add(1*time.Hour), nil, vals, vals, |
|
|
|
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)), |
|
|
|
}, |
|
|
|
map[int64]*types.ValidatorSet{ |
|
|
|
1: vals, |
|
|
|
2: vals, |
|
|
|
3: vals, |
|
|
|
4: vals, |
|
|
|
}, |
|
|
|
) |
|
|
|
|
|
|
|
c, err := NewClient( |
|
|
|
chainID, |
|
|
|
TrustOptions{ |
|
|
|
Period: 4 * time.Hour, |
|
|
|
Height: 1, |
|
|
|
Hash: header.Hash(), |
|
|
|
}, |
|
|
|
primary, |
|
|
|
[]provider.Provider{primary}, |
|
|
|
trustOptions, |
|
|
|
fullNode, |
|
|
|
[]provider.Provider{fullNode}, |
|
|
|
dbs.New(dbm.NewMemDB(), chainID), |
|
|
|
Logger(log.TestingLogger()), |
|
|
|
) |
|
|
@ -790,48 +606,12 @@ func TestClient_Update(t *testing.T) { |
|
|
|
} |
|
|
|
|
|
|
|
func TestClient_Concurrency(t *testing.T) { |
|
|
|
const ( |
|
|
|
chainID = "TestClient_Concurrency" |
|
|
|
) |
|
|
|
|
|
|
|
var ( |
|
|
|
keys = genPrivKeys(4) |
|
|
|
// 20, 30, 40, 50 - the first 3 don't have 2/3, the last 3 do!
|
|
|
|
vals = keys.ToValidators(20, 10) |
|
|
|
bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z") |
|
|
|
header = keys.GenSignedHeader(chainID, 1, bTime, nil, vals, vals, |
|
|
|
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)) |
|
|
|
) |
|
|
|
|
|
|
|
primary := mockp.New( |
|
|
|
chainID, |
|
|
|
map[int64]*types.SignedHeader{ |
|
|
|
// trusted header
|
|
|
|
1: header, |
|
|
|
// interim header (3/3 signed)
|
|
|
|
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)), |
|
|
|
// last header (3/3 signed)
|
|
|
|
3: keys.GenSignedHeader(chainID, 3, bTime.Add(1*time.Hour), nil, vals, vals, |
|
|
|
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)), |
|
|
|
}, |
|
|
|
map[int64]*types.ValidatorSet{ |
|
|
|
1: vals, |
|
|
|
2: vals, |
|
|
|
3: vals, |
|
|
|
4: vals, |
|
|
|
}, |
|
|
|
) |
|
|
|
|
|
|
|
c, err := NewClient( |
|
|
|
chainID, |
|
|
|
TrustOptions{ |
|
|
|
Period: 4 * time.Hour, |
|
|
|
Height: 1, |
|
|
|
Hash: header.Hash(), |
|
|
|
}, |
|
|
|
primary, |
|
|
|
[]provider.Provider{primary}, |
|
|
|
trustOptions, |
|
|
|
fullNode, |
|
|
|
[]provider.Provider{fullNode}, |
|
|
|
dbs.New(dbm.NewMemDB(), chainID), |
|
|
|
UpdatePeriod(0), |
|
|
|
Logger(log.TestingLogger()), |
|
|
@ -875,93 +655,26 @@ func TestClient_Concurrency(t *testing.T) { |
|
|
|
} |
|
|
|
|
|
|
|
func TestProvider_Replacement(t *testing.T) { |
|
|
|
const ( |
|
|
|
chainID = "TestProvider_Replacement" |
|
|
|
) |
|
|
|
|
|
|
|
var ( |
|
|
|
keys = genPrivKeys(4) |
|
|
|
// 20, 30, 40, 50 - the first 3 don't have 2/3, the last 3 do!
|
|
|
|
vals = keys.ToValidators(20, 10) |
|
|
|
bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z") |
|
|
|
header = keys.GenSignedHeader(chainID, 1, bTime, nil, vals, vals, |
|
|
|
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)) |
|
|
|
primary = mockp.NewDeadMock(chainID) |
|
|
|
witness = mockp.New( |
|
|
|
chainID, |
|
|
|
map[int64]*types.SignedHeader{ |
|
|
|
// trusted header
|
|
|
|
1: header, |
|
|
|
// interim header (3/3 signed)
|
|
|
|
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)), |
|
|
|
// last header (3/3 signed)
|
|
|
|
3: keys.GenSignedHeader(chainID, 3, bTime.Add(1*time.Hour), nil, vals, vals, |
|
|
|
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)), |
|
|
|
}, |
|
|
|
map[int64]*types.ValidatorSet{ |
|
|
|
1: vals, |
|
|
|
2: vals, |
|
|
|
3: vals, |
|
|
|
4: vals, |
|
|
|
}, |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
c, err := NewClient( |
|
|
|
chainID, |
|
|
|
TrustOptions{ |
|
|
|
Period: 4 * time.Hour, |
|
|
|
Height: 1, |
|
|
|
Hash: header.Hash(), |
|
|
|
}, |
|
|
|
primary, |
|
|
|
[]provider.Provider{witness}, |
|
|
|
trustOptions, |
|
|
|
deadNode, |
|
|
|
[]provider.Provider{fullNode, fullNode}, |
|
|
|
dbs.New(dbm.NewMemDB(), chainID), |
|
|
|
UpdatePeriod(0), |
|
|
|
Logger(log.TestingLogger()), |
|
|
|
MaxRetryAttempts(1), |
|
|
|
) |
|
|
|
require.NoError(t, err) |
|
|
|
err = c.Start() |
|
|
|
err = c.Update(bTime.Add(2 * time.Hour)) |
|
|
|
require.NoError(t, err) |
|
|
|
defer c.Stop() |
|
|
|
|
|
|
|
assert.NotEqual(t, c.Primary(), primary) |
|
|
|
assert.Equal(t, 0, len(c.Witnesses())) |
|
|
|
assert.NotEqual(t, c.Primary(), deadNode) |
|
|
|
assert.Equal(t, 1, len(c.Witnesses())) |
|
|
|
} |
|
|
|
|
|
|
|
func TestProvider_TrustedHeaderFetchesMissingHeader(t *testing.T) { |
|
|
|
const ( |
|
|
|
chainID = "TestProvider_TrustedHeaderFetchesMissingHeader" |
|
|
|
) |
|
|
|
|
|
|
|
var ( |
|
|
|
keys = genPrivKeys(4) |
|
|
|
// 20, 30, 40, 50 - the first 3 don't have 2/3, the last 3 do!
|
|
|
|
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)) |
|
|
|
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()}) |
|
|
|
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()}) |
|
|
|
primary = mockp.New( |
|
|
|
chainID, |
|
|
|
map[int64]*types.SignedHeader{ |
|
|
|
1: h1, |
|
|
|
2: h2, |
|
|
|
3: h3, |
|
|
|
}, |
|
|
|
map[int64]*types.ValidatorSet{ |
|
|
|
1: vals, |
|
|
|
2: vals, |
|
|
|
3: vals, |
|
|
|
4: vals, |
|
|
|
}, |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
c, err := NewClient( |
|
|
|
chainID, |
|
|
@ -970,8 +683,8 @@ func TestProvider_TrustedHeaderFetchesMissingHeader(t *testing.T) { |
|
|
|
Height: 3, |
|
|
|
Hash: h3.Hash(), |
|
|
|
}, |
|
|
|
primary, |
|
|
|
[]provider.Provider{primary}, |
|
|
|
fullNode, |
|
|
|
[]provider.Provider{fullNode}, |
|
|
|
dbs.New(dbm.NewMemDB(), chainID), |
|
|
|
UpdatePeriod(0), |
|
|
|
Logger(log.TestingLogger()), |
|
|
@ -995,35 +708,18 @@ func TestProvider_TrustedHeaderFetchesMissingHeader(t *testing.T) { |
|
|
|
} |
|
|
|
|
|
|
|
func Test_NewClientFromTrustedStore(t *testing.T) { |
|
|
|
const ( |
|
|
|
chainID = "Test_NewClientFromTrustedStore" |
|
|
|
) |
|
|
|
|
|
|
|
var ( |
|
|
|
keys = genPrivKeys(4) |
|
|
|
// 20, 30, 40, 50 - the first 3 don't have 2/3, the last 3 do!
|
|
|
|
vals = keys.ToValidators(20, 10) |
|
|
|
bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z") |
|
|
|
header = keys.GenSignedHeader(chainID, 1, bTime, nil, vals, vals, |
|
|
|
[]byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)) |
|
|
|
primary = mockp.New( |
|
|
|
chainID, |
|
|
|
map[int64]*types.SignedHeader{}, |
|
|
|
map[int64]*types.ValidatorSet{}, |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
// 1) Initiate DB and fill with a "trusted" header
|
|
|
|
db := dbs.New(dbm.NewMemDB(), chainID) |
|
|
|
err := db.SaveSignedHeaderAndNextValidatorSet(header, vals) |
|
|
|
err := db.SaveSignedHeaderAndNextValidatorSet(h1, vals) |
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
// 2) Initialize Lite Client from Trusted Store
|
|
|
|
c, err := NewClientFromTrustedStore( |
|
|
|
chainID, |
|
|
|
1*time.Hour, |
|
|
|
primary, |
|
|
|
[]provider.Provider{primary}, |
|
|
|
trustPeriod, |
|
|
|
fullNode, |
|
|
|
[]provider.Provider{fullNode}, |
|
|
|
db, |
|
|
|
) |
|
|
|
require.NoError(t, err) |
|
|
@ -1035,47 +731,12 @@ func Test_NewClientFromTrustedStore(t *testing.T) { |
|
|
|
} |
|
|
|
|
|
|
|
func TestCompareWithWitnesses(t *testing.T) { |
|
|
|
const ( |
|
|
|
chainID = "TestCompareWithWitnesses" |
|
|
|
) |
|
|
|
|
|
|
|
var ( |
|
|
|
keys = genPrivKeys(4) |
|
|
|
// 20, 30, 40, 50 - the first 3 don't have 2/3, the last 3 do!
|
|
|
|
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)) |
|
|
|
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()}) |
|
|
|
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()}) |
|
|
|
liveProvider = mockp.New( |
|
|
|
chainID, |
|
|
|
map[int64]*types.SignedHeader{ |
|
|
|
1: h1, |
|
|
|
2: h2, |
|
|
|
3: h3, |
|
|
|
}, |
|
|
|
map[int64]*types.ValidatorSet{ |
|
|
|
1: vals, |
|
|
|
2: vals, |
|
|
|
3: vals, |
|
|
|
4: vals, |
|
|
|
}, |
|
|
|
) |
|
|
|
deadProvider = mockp.NewDeadMock(chainID) |
|
|
|
) |
|
|
|
|
|
|
|
c, err := NewClient( |
|
|
|
chainID, |
|
|
|
TrustOptions{ |
|
|
|
Period: 1 * time.Hour, |
|
|
|
Height: 2, |
|
|
|
Hash: h2.Hash(), |
|
|
|
}, |
|
|
|
liveProvider, |
|
|
|
[]provider.Provider{deadProvider, deadProvider, deadProvider}, |
|
|
|
trustOptions, |
|
|
|
fullNode, |
|
|
|
[]provider.Provider{deadNode, deadNode, deadNode}, |
|
|
|
dbs.New(dbm.NewMemDB(), chainID), |
|
|
|
UpdatePeriod(0), |
|
|
|
Logger(log.TestingLogger()), |
|
|
|