mirror of
https://github.com/tendermint/tendermint.git
synced 2026-01-08 14:21:14 +00:00
lite2: add Start, TrustedValidatorSet funcs (#4337)
* lite2: add Start method There are few reasons to do that: 1) separation of state and dynamics (some users will want to delay starting the light client; does not matter we should not allow them to create a light client object) 2) less important, but some users might not need autoUpdateRoutine and removeNoLongerTrustedHeadersRoutine routines * lite2: wait till routines are finished in Stop because they are started in Start, it feels more natural to wait for them to finish in Stop. * lite2: add TrustedValidatorSet func
This commit is contained in:
@@ -209,16 +209,6 @@ func NewClient(
|
||||
}
|
||||
}
|
||||
|
||||
if c.removeNoLongerTrustedHeadersPeriod > 0 {
|
||||
c.routinesWaitGroup.Add(1)
|
||||
go c.removeNoLongerTrustedHeadersRoutine()
|
||||
}
|
||||
|
||||
if c.updatePeriod > 0 {
|
||||
c.routinesWaitGroup.Add(1)
|
||||
go c.autoUpdateRoutine()
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
@@ -367,10 +357,30 @@ func (c *Client) initializeWithTrustOptions(options TrustOptions) error {
|
||||
return c.updateTrustedHeaderAndVals(h, nextVals)
|
||||
}
|
||||
|
||||
// Stop stops all the goroutines. If you wish to remove all the data, call
|
||||
// Cleanup.
|
||||
// Start starts two processes: 1) auto updating 2) removing outdated headers.
|
||||
func (c *Client) Start() error {
|
||||
c.logger.Info("Starting light client")
|
||||
|
||||
if c.removeNoLongerTrustedHeadersPeriod > 0 {
|
||||
c.routinesWaitGroup.Add(1)
|
||||
go c.removeNoLongerTrustedHeadersRoutine()
|
||||
}
|
||||
|
||||
if c.updatePeriod > 0 {
|
||||
c.routinesWaitGroup.Add(1)
|
||||
go c.autoUpdateRoutine()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop stops two processes: 1) auto updating 2) removing outdated headers.
|
||||
// Stop only returns after both of them are finished running. If you wish to
|
||||
// remove all the data, call Cleanup.
|
||||
func (c *Client) Stop() {
|
||||
c.logger.Info("Stopping light client")
|
||||
close(c.quit)
|
||||
c.routinesWaitGroup.Wait()
|
||||
}
|
||||
|
||||
// TrustedHeader returns a trusted header at the given height (0 - the latest)
|
||||
@@ -415,6 +425,30 @@ func (c *Client) TrustedHeader(height int64, now time.Time) (*types.SignedHeader
|
||||
return h, nil
|
||||
}
|
||||
|
||||
// TrustedValidatorSet returns a trusted validator set at the given height (0 -
|
||||
// the latest) or nil if no such validator set exist. The second return
|
||||
// parameter is height validator set corresponds to (useful when you pass 0).
|
||||
//
|
||||
// height must be >= 0.
|
||||
//
|
||||
// It returns an error if:
|
||||
// - header signed by that validator set expired (ErrOldHeaderExpired)
|
||||
// - there are some issues with the trusted store, although that should not
|
||||
// happen normally;
|
||||
// - negative height is passed;
|
||||
// - validator set is not found.
|
||||
//
|
||||
// Safe for concurrent use by multiple goroutines.
|
||||
func (c *Client) TrustedValidatorSet(height int64, now time.Time) (*types.ValidatorSet, error) {
|
||||
// Checks height is positive and header is not expired.
|
||||
_, err := c.TrustedHeader(height, now)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c.trustedStore.ValidatorSet(height)
|
||||
}
|
||||
|
||||
// LastTrustedHeight returns a last trusted height. -1 and nil are returned if
|
||||
// there are no trusted headers.
|
||||
//
|
||||
@@ -511,12 +545,10 @@ func (c *Client) VerifyHeader(newHeader *types.SignedHeader, newVals *types.Vali
|
||||
return c.updateTrustedHeaderAndVals(newHeader, nextVals)
|
||||
}
|
||||
|
||||
// Cleanup removes all the data (headers and validator sets) stored. It blocks
|
||||
// until internal routines are finished. Note: the client must be stopped at
|
||||
// this point.
|
||||
// Cleanup removes all the data (headers and validator sets) stored. Note: the
|
||||
// client must be stopped at this point.
|
||||
func (c *Client) Cleanup() error {
|
||||
c.routinesWaitGroup.Wait()
|
||||
c.logger.Info("Cleanup everything")
|
||||
c.logger.Info("Removing all the data")
|
||||
return c.cleanup(0)
|
||||
}
|
||||
|
||||
|
||||
@@ -137,6 +137,8 @@ func TestClient_SequentialVerification(t *testing.T) {
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
err = c.Start()
|
||||
require.NoError(t, err)
|
||||
defer c.Stop()
|
||||
|
||||
_, err = c.VerifyHeaderAtHeight(3, bTime.Add(3*time.Hour))
|
||||
@@ -235,6 +237,8 @@ func TestClient_SkippingVerification(t *testing.T) {
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
err = c.Start()
|
||||
require.NoError(t, err)
|
||||
defer c.Stop()
|
||||
|
||||
_, err = c.VerifyHeaderAtHeight(3, bTime.Add(3*time.Hour))
|
||||
@@ -290,6 +294,8 @@ func TestClientRemovesNoLongerTrustedHeaders(t *testing.T) {
|
||||
Logger(log.TestingLogger()),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
err = c.Start()
|
||||
require.NoError(t, err)
|
||||
defer c.Stop()
|
||||
|
||||
// Verify new headers.
|
||||
@@ -349,6 +355,8 @@ func TestClient_Cleanup(t *testing.T) {
|
||||
Logger(log.TestingLogger()),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
err = c.Start()
|
||||
require.NoError(t, err)
|
||||
|
||||
c.Stop()
|
||||
c.Cleanup()
|
||||
@@ -402,6 +410,9 @@ func TestClientRestoreTrustedHeaderAfterStartup1(t *testing.T) {
|
||||
Logger(log.TestingLogger()),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
err = c.Start()
|
||||
require.NoError(t, err)
|
||||
defer c.Stop()
|
||||
|
||||
h, err := c.TrustedHeader(1, bTime.Add(1*time.Second))
|
||||
assert.NoError(t, err)
|
||||
@@ -441,6 +452,9 @@ func TestClientRestoreTrustedHeaderAfterStartup1(t *testing.T) {
|
||||
Logger(log.TestingLogger()),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
err = c.Start()
|
||||
require.NoError(t, err)
|
||||
defer c.Stop()
|
||||
|
||||
h, err := c.TrustedHeader(1, bTime.Add(1*time.Second))
|
||||
assert.NoError(t, err)
|
||||
@@ -496,6 +510,9 @@ func TestClientRestoreTrustedHeaderAfterStartup2(t *testing.T) {
|
||||
Logger(log.TestingLogger()),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
err = c.Start()
|
||||
require.NoError(t, err)
|
||||
defer c.Stop()
|
||||
|
||||
// Check we still have the 1st header (+header+).
|
||||
h, err := c.TrustedHeader(1, bTime.Add(2*time.Hour).Add(1*time.Second))
|
||||
@@ -541,6 +558,9 @@ func TestClientRestoreTrustedHeaderAfterStartup2(t *testing.T) {
|
||||
Logger(log.TestingLogger()),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
err = c.Start()
|
||||
require.NoError(t, err)
|
||||
defer c.Stop()
|
||||
|
||||
// Check we no longer have the invalid 1st header (+header+).
|
||||
h, err := c.TrustedHeader(1, bTime.Add(2*time.Hour).Add(1*time.Second))
|
||||
@@ -598,6 +618,9 @@ func TestClientRestoreTrustedHeaderAfterStartup3(t *testing.T) {
|
||||
Logger(log.TestingLogger()),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
err = c.Start()
|
||||
require.NoError(t, err)
|
||||
defer c.Stop()
|
||||
|
||||
// Check we still have the 1st header (+header+).
|
||||
h, err := c.TrustedHeader(1, bTime.Add(2*time.Hour).Add(1*time.Second))
|
||||
@@ -648,6 +671,9 @@ func TestClientRestoreTrustedHeaderAfterStartup3(t *testing.T) {
|
||||
Logger(log.TestingLogger()),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
err = c.Start()
|
||||
require.NoError(t, err)
|
||||
defer c.Stop()
|
||||
|
||||
// Check we have swapped invalid 1st header (+header+) with correct one (+header1+).
|
||||
h, err := c.TrustedHeader(1, bTime.Add(2*time.Hour).Add(1*time.Second))
|
||||
@@ -706,6 +732,8 @@ func TestClient_Update(t *testing.T) {
|
||||
Logger(log.TestingLogger()),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
err = c.Start()
|
||||
require.NoError(t, err)
|
||||
defer c.Stop()
|
||||
|
||||
// should result in downloading & verifying header #3
|
||||
@@ -763,6 +791,13 @@ func TestClient_Concurrency(t *testing.T) {
|
||||
Logger(log.TestingLogger()),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
err = c.Start()
|
||||
require.NoError(t, err)
|
||||
defer c.Stop()
|
||||
|
||||
_, err = c.VerifyHeaderAtHeight(2, bTime.Add(2*time.Hour))
|
||||
require.NoError(t, err)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
for i := 0; i < 100; i++ {
|
||||
wg.Add(1)
|
||||
@@ -783,6 +818,10 @@ func TestClient_Concurrency(t *testing.T) {
|
||||
h, err := c.TrustedHeader(1, bTime.Add(2*time.Hour))
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, h)
|
||||
|
||||
vals, err := c.TrustedValidatorSet(2, bTime.Add(2*time.Hour))
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, vals)
|
||||
}()
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,10 @@ func TestExample_Client_AutoUpdate(t *testing.T) {
|
||||
if err != nil {
|
||||
stdlog.Fatal(err)
|
||||
}
|
||||
err = c.Start()
|
||||
if err != nil {
|
||||
stdlog.Fatal(err)
|
||||
}
|
||||
defer func() {
|
||||
c.Stop()
|
||||
c.Cleanup()
|
||||
@@ -125,6 +129,10 @@ func TestExample_Client_ManualUpdate(t *testing.T) {
|
||||
if err != nil {
|
||||
stdlog.Fatal(err)
|
||||
}
|
||||
err = c.Start()
|
||||
if err != nil {
|
||||
stdlog.Fatal(err)
|
||||
}
|
||||
defer func() {
|
||||
c.Stop()
|
||||
c.Cleanup()
|
||||
|
||||
Reference in New Issue
Block a user