mirror of
https://github.com/tendermint/tendermint.git
synced 2026-02-10 22:10:11 +00:00
* rename adjusted to adjacent Refs https://github.com/tendermint/tendermint/pull/3989#discussion_r352140829 * rename ErrTooMuchChange to ErrNotEnoughVotingPowerSigned Refs https://github.com/tendermint/tendermint/pull/3989#discussion_r352142785 * verify commit is properly signed * remove no longer trusted headers * restore trustedHeader and trustedNextVals * check trustedHeader using options Refs https://github.com/tendermint/tendermint/pull/4209#issuecomment-562462165 * use correct var when checking if headers are adjacent in bisection func + replace TODO with a comment https://github.com/tendermint/tendermint/pull/3989#discussion_r352125455 * return header in VerifyHeaderAtHeight because that way we avoid DB call + add godoc comments + check if there are no headers yet in AutoClient https://github.com/tendermint/tendermint/pull/3989#pullrequestreview-315454506 * TestVerifyAdjacentHeaders: add 2 more test-cases + add TestVerifyReturnsErrorIfTrustLevelIsInvalid * lite: avoid overflow when parsing key in db store! * lite: rename AutoClient#Err to Errs * lite: add a test for AutoClient * lite: fix keyPattern and call itr.Next in db store * lite: add two tests for db store * lite: add TestClientRemovesNoLongerTrustedHeaders * lite: test Client#Cleanup * lite: test restoring trustedHeader https://github.com/tendermint/tendermint/pull/4209#issuecomment-562462165 * lite: comment out unused code in test_helpers * fix TestVerifyReturnsErrorIfTrustLevelIsInvalid after merge * change defaultRemoveNoLongerTrustedHeadersPeriod and add docs * write more doc * lite: uncomment testable examples * use stdlog.Fatal to stop AutoClient tests * make lll linter happy * separate errors for 2 cases - the validator set of a skipped header cannot be trusted, i.e. <1/3rd of h1 validator set has signed (new error, something like ErrNewValSetCantBeTrusted) - the validator set is trusted but < 2/3rds has signed (ErrNewHeaderCantBeTrusted) https://github.com/tendermint/tendermint/pull/4209#discussion_r360331253 * remove all headers (even the last one) that are outside of the trusting period. By doing this, we avoid checking the trustedHeader's hash in checkTrustedHeaderUsingOptions (case #1). https://github.com/tendermint/tendermint/pull/4209#discussion_r360332460 * explain restoreTrustedHeaderAndNextVals better https://github.com/tendermint/tendermint/pull/4209#discussion_r360602328 * add ConfirmationFunction option for optionally prompting for user input Y/n before removing headers Refs https://github.com/tendermint/tendermint/pull/4209#discussion_r360602945 * make cleaning optional https://github.com/tendermint/tendermint/pull/4209#discussion_r364838189 * return error when user refused to remove headers * check for double votes in VerifyCommitTrusting * leave only ErrNewValSetCantBeTrusted error to differenciate between h2Vals.VerifyCommit and h1NextVals.VerifyCommitTrusting * fix example tests * remove unnecessary if condition https://github.com/tendermint/tendermint/pull/4209#discussion_r365171847 It will be handled by the above switch. * verifyCommitBasic does not depend on vals Co-authored-by: Marko <marbar3778@yahoo.com>
77 lines
1.6 KiB
Go
77 lines
1.6 KiB
Go
package lite
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/tendermint/tendermint/types"
|
|
)
|
|
|
|
// AutoClient can auto update itself by fetching headers every N seconds.
|
|
type AutoClient struct {
|
|
base *Client
|
|
updatePeriod time.Duration
|
|
quit chan struct{}
|
|
|
|
trustedHeaders chan *types.SignedHeader
|
|
errs chan error
|
|
}
|
|
|
|
// NewAutoClient creates a new client and starts a polling goroutine.
|
|
func NewAutoClient(base *Client, updatePeriod time.Duration) *AutoClient {
|
|
c := &AutoClient{
|
|
base: base,
|
|
updatePeriod: updatePeriod,
|
|
quit: make(chan struct{}),
|
|
trustedHeaders: make(chan *types.SignedHeader),
|
|
errs: make(chan error),
|
|
}
|
|
go c.autoUpdate()
|
|
return c
|
|
}
|
|
|
|
// TrustedHeaders returns a channel onto which new trusted headers are posted.
|
|
func (c *AutoClient) TrustedHeaders() <-chan *types.SignedHeader {
|
|
return c.trustedHeaders
|
|
}
|
|
|
|
// Err returns a channel onto which errors are posted.
|
|
func (c *AutoClient) Errs() <-chan error {
|
|
return c.errs
|
|
}
|
|
|
|
// Stop stops the client.
|
|
func (c *AutoClient) Stop() {
|
|
close(c.quit)
|
|
}
|
|
|
|
func (c *AutoClient) autoUpdate() {
|
|
ticker := time.NewTicker(c.updatePeriod)
|
|
defer ticker.Stop()
|
|
|
|
for {
|
|
select {
|
|
case <-ticker.C:
|
|
lastTrustedHeight, err := c.base.LastTrustedHeight()
|
|
if err != nil {
|
|
c.errs <- err
|
|
continue
|
|
}
|
|
|
|
if lastTrustedHeight == -1 {
|
|
// no headers yet => wait
|
|
continue
|
|
}
|
|
|
|
h, err := c.base.VerifyHeaderAtHeight(lastTrustedHeight+1, time.Now())
|
|
if err != nil {
|
|
// no header yet or verification error => try again after updatePeriod
|
|
c.errs <- err
|
|
continue
|
|
}
|
|
c.trustedHeaders <- h
|
|
case <-c.quit:
|
|
return
|
|
}
|
|
}
|
|
}
|