Browse Source

light: remove legacy timeout scheme (backport #7776) (#7786)

pull/7793/head
mergify[bot] 3 years ago
committed by GitHub
parent
commit
caddddcb3a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 33 deletions
  1. +24
    -12
      internal/statesync/stateprovider.go
  2. +10
    -21
      light/client.go

+ 24
- 12
internal/statesync/stateprovider.go View File

@ -85,6 +85,12 @@ func NewRPCStateProvider(
}, nil
}
func (s *stateProviderRPC) verifyLightBlockAtHeight(ctx context.Context, height uint64, ts time.Time) (*types.LightBlock, error) {
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
return s.lc.VerifyLightBlockAtHeight(ctx, int64(height), ts)
}
// AppHash implements part of StateProvider. It calls the application to verify the
// light blocks at heights h+1 and h+2 and, if verification succeeds, reports the app
// hash for the block at height h+1 which correlates to the state at height h.
@ -93,7 +99,7 @@ func (s *stateProviderRPC) AppHash(ctx context.Context, height uint64) ([]byte,
defer s.Unlock()
// We have to fetch the next height, which contains the app hash for the previous height.
header, err := s.lc.VerifyLightBlockAtHeight(ctx, int64(height+1), time.Now())
header, err := s.verifyLightBlockAtHeight(ctx, height+1, time.Now())
if err != nil {
return nil, err
}
@ -101,7 +107,7 @@ func (s *stateProviderRPC) AppHash(ctx context.Context, height uint64) ([]byte,
// We also try to fetch the blocks at H+2, since we need these
// when building the state while restoring the snapshot. This avoids the race
// condition where we try to restore a snapshot before H+2 exists.
_, err = s.lc.VerifyLightBlockAtHeight(ctx, int64(height+2), time.Now())
_, err = s.verifyLightBlockAtHeight(ctx, height+2, time.Now())
if err != nil {
return nil, err
}
@ -112,7 +118,7 @@ func (s *stateProviderRPC) AppHash(ctx context.Context, height uint64) ([]byte,
func (s *stateProviderRPC) Commit(ctx context.Context, height uint64) (*types.Commit, error) {
s.Lock()
defer s.Unlock()
header, err := s.lc.VerifyLightBlockAtHeight(ctx, int64(height), time.Now())
header, err := s.verifyLightBlockAtHeight(ctx, height, time.Now())
if err != nil {
return nil, err
}
@ -140,15 +146,15 @@ func (s *stateProviderRPC) State(ctx context.Context, height uint64) (sm.State,
//
// We need to fetch the NextValidators from height+2 because if the application changed
// the validator set at the snapshot height then this only takes effect at height+2.
lastLightBlock, err := s.lc.VerifyLightBlockAtHeight(ctx, int64(height), time.Now())
lastLightBlock, err := s.verifyLightBlockAtHeight(ctx, height, time.Now())
if err != nil {
return sm.State{}, err
}
currentLightBlock, err := s.lc.VerifyLightBlockAtHeight(ctx, int64(height+1), time.Now())
currentLightBlock, err := s.verifyLightBlockAtHeight(ctx, height+1, time.Now())
if err != nil {
return sm.State{}, err
}
nextLightBlock, err := s.lc.VerifyLightBlockAtHeight(ctx, int64(height+2), time.Now())
nextLightBlock, err := s.verifyLightBlockAtHeight(ctx, height+2, time.Now())
if err != nil {
return sm.State{}, err
}
@ -233,13 +239,19 @@ func NewP2PStateProvider(
}, nil
}
func (s *stateProviderP2P) verifyLightBlockAtHeight(ctx context.Context, height uint64, ts time.Time) (*types.LightBlock, error) {
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
return s.lc.VerifyLightBlockAtHeight(ctx, int64(height), ts)
}
// AppHash implements StateProvider.
func (s *stateProviderP2P) AppHash(ctx context.Context, height uint64) ([]byte, error) {
s.Lock()
defer s.Unlock()
// We have to fetch the next height, which contains the app hash for the previous height.
header, err := s.lc.VerifyLightBlockAtHeight(ctx, int64(height+1), time.Now())
header, err := s.verifyLightBlockAtHeight(ctx, height+1, time.Now())
if err != nil {
return nil, err
}
@ -247,7 +259,7 @@ func (s *stateProviderP2P) AppHash(ctx context.Context, height uint64) ([]byte,
// We also try to fetch the blocks at H+2, since we need these
// when building the state while restoring the snapshot. This avoids the race
// condition where we try to restore a snapshot before H+2 exists.
_, err = s.lc.VerifyLightBlockAtHeight(ctx, int64(height+2), time.Now())
_, err = s.verifyLightBlockAtHeight(ctx, height+2, time.Now())
if err != nil {
return nil, err
}
@ -258,7 +270,7 @@ func (s *stateProviderP2P) AppHash(ctx context.Context, height uint64) ([]byte,
func (s *stateProviderP2P) Commit(ctx context.Context, height uint64) (*types.Commit, error) {
s.Lock()
defer s.Unlock()
header, err := s.lc.VerifyLightBlockAtHeight(ctx, int64(height), time.Now())
header, err := s.verifyLightBlockAtHeight(ctx, height, time.Now())
if err != nil {
return nil, err
}
@ -286,15 +298,15 @@ func (s *stateProviderP2P) State(ctx context.Context, height uint64) (sm.State,
//
// We need to fetch the NextValidators from height+2 because if the application changed
// the validator set at the snapshot height then this only takes effect at height+2.
lastLightBlock, err := s.lc.VerifyLightBlockAtHeight(ctx, int64(height), time.Now())
lastLightBlock, err := s.verifyLightBlockAtHeight(ctx, height, time.Now())
if err != nil {
return sm.State{}, err
}
currentLightBlock, err := s.lc.VerifyLightBlockAtHeight(ctx, int64(height+1), time.Now())
currentLightBlock, err := s.verifyLightBlockAtHeight(ctx, height+1, time.Now())
if err != nil {
return sm.State{}, err
}
nextLightBlock, err := s.lc.VerifyLightBlockAtHeight(ctx, int64(height+2), time.Now())
nextLightBlock, err := s.verifyLightBlockAtHeight(ctx, height+2, time.Now())
if err != nil {
return sm.State{}, err
}


+ 10
- 21
light/client.go View File

@ -52,8 +52,6 @@ const (
// 10s is sufficient for most networks.
defaultMaxBlockLag = 10 * time.Second
defaultProviderTimeout = 10 * time.Second
)
// Option sets a parameter for the light client.
@ -113,12 +111,6 @@ func MaxBlockLag(d time.Duration) Option {
return func(c *Client) { c.maxBlockLag = d }
}
// Provider timeout is the maximum time that the light client will wait for a
// provider to respond with a light block.
func ProviderTimeout(d time.Duration) Option {
return func(c *Client) { c.providerTimeout = d }
}
// Client represents a light client, connected to a single chain, which gets
// light blocks from a primary provider, verifies them either sequentially or by
// skipping some and stores them in a trusted store (usually, a local FS).
@ -131,7 +123,6 @@ type Client struct {
trustLevel tmmath.Fraction
maxClockDrift time.Duration
maxBlockLag time.Duration
providerTimeout time.Duration
// Mutex for locking during changes of the light clients providers
providerMutex tmsync.Mutex
@ -202,7 +193,6 @@ func NewClient(
trustLevel: DefaultTrustLevel,
maxClockDrift: defaultMaxClockDrift,
maxBlockLag: defaultMaxBlockLag,
providerTimeout: defaultProviderTimeout,
pruningSize: defaultPruningSize,
logger: log.NewNopLogger(),
}
@ -695,9 +685,7 @@ func (c *Client) verifySkipping(
if depth == len(blockCache)-1 {
// schedule what the next height we need to fetch is
pivotHeight := c.schedule(verifiedBlock.Height, blockCache[depth].Height)
subCtx, cancel := context.WithTimeout(ctx, c.providerTimeout)
defer cancel()
interimBlock, providerErr := c.getLightBlock(subCtx, source, pivotHeight)
interimBlock, providerErr := c.getLightBlock(ctx, source, pivotHeight)
if providerErr != nil {
return nil, ErrVerificationFailed{From: verifiedBlock.Height, To: pivotHeight, Reason: providerErr}
}
@ -962,10 +950,8 @@ func (c *Client) lightBlockFromPrimary(ctx context.Context, height int64) (*type
}
func (c *Client) getLightBlock(ctx context.Context, p provider.Provider, height int64) (*types.LightBlock, error) {
subCtx, cancel := context.WithTimeout(ctx, c.providerTimeout)
defer cancel()
l, err := p.LightBlock(subCtx, height)
if err == context.DeadlineExceeded || ctx.Err() != nil {
l, err := p.LightBlock(ctx, height)
if ctx.Err() != nil {
return nil, provider.ErrNoResponse
}
return l, err
@ -1014,16 +1000,19 @@ func (c *Client) findNewPrimary(ctx context.Context, height int64, remove bool)
wg sync.WaitGroup
)
// send out a light block request to all witnesses
subctx, cancel := context.WithTimeout(ctx, c.providerTimeout)
ctx, cancel := context.WithCancel(ctx)
defer cancel()
// send out a light block request to all witnesses
for index := range c.witnesses {
wg.Add(1)
go func(witnessIndex int, witnessResponsesC chan witnessResponse) {
defer wg.Done()
lb, err := c.witnesses[witnessIndex].LightBlock(subctx, height)
witnessResponsesC <- witnessResponse{lb, witnessIndex, err}
lb, err := c.witnesses[witnessIndex].LightBlock(ctx, height)
select {
case witnessResponsesC <- witnessResponse{lb, witnessIndex, err}:
case <-ctx.Done():
}
}(index, witnessResponsesC)
}


Loading…
Cancel
Save