Skip to content

Commit 00de611

Browse files
authored
Merge pull request #166 from hyperledger-labs/feature/v0.5.13-op
Change the return value type of `Prover::SetupHeadersForUpdate` to support stream processing of huge headers
2 parents 9cd019e + 5abb762 commit 00de611

File tree

7 files changed

+50
-10
lines changed

7 files changed

+50
-10
lines changed

chains/tendermint/prover.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ func (pr *Prover) CreateInitialLightClientState(ctx context.Context, height ibce
9191
}
9292

9393
// SetupHeadersForUpdate returns the finalized header and any intermediate headers needed to apply it to the client on the counterpaty chain
94-
func (pr *Prover) SetupHeadersForUpdate(ctx context.Context, counterparty core.FinalityAwareChain, latestFinalizedHeader core.Header) ([]core.Header, error) {
94+
func (pr *Prover) SetupHeadersForUpdate(ctx context.Context, counterparty core.FinalityAwareChain, latestFinalizedHeader core.Header) (<-chan *core.HeaderOrError, error) {
9595
self := pr.chain
9696
// make copy of header stored in mop
9797
tmp := latestFinalizedHeader.(*tmclient.Header)
@@ -124,7 +124,7 @@ func (pr *Prover) SetupHeadersForUpdate(ctx context.Context, counterparty core.F
124124

125125
// inject TrustedValidators into header
126126
h.TrustedValidators = valSet
127-
return []core.Header{&h}, nil
127+
return core.MakeHeaderStream(&h), nil
128128
}
129129

130130
// GetLatestFinalizedHeader returns the latest finalized header

core/channel-upgrade.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ func CancelChannelUpgrade(ctx context.Context, chain, cp *ProvableChain, settlem
228228
return false, nil
229229
}
230230

231-
cpHeaders, err := cp.SetupHeadersForUpdate(ctx, chain, sh.GetLatestFinalizedHeader(cp.ChainID()))
231+
cpHeaders, err := SetupHeadersForUpdateSync(cp, ctx, chain, sh.GetLatestFinalizedHeader(cp.ChainID()))
232232
if err != nil {
233233
logger.ErrorContext(ctx, "failed to set up headers for LC update", err)
234234
return false, err

core/header-stream.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package core
2+
3+
import "context"
4+
5+
func SetupHeadersForUpdateSync(prover LightClient, ctx context.Context, counterparty FinalityAwareChain, latestFinalizedHeader Header) ([]Header, error) {
6+
ctxForSHFU, cancel := context.WithCancel(ctx)
7+
defer cancel()
8+
headerStream, err := prover.SetupHeadersForUpdate(ctxForSHFU, counterparty, latestFinalizedHeader)
9+
if err != nil {
10+
return nil, err
11+
}
12+
13+
var ret []Header
14+
for h := range headerStream {
15+
if h.Error != nil {
16+
return nil, h.Error
17+
}
18+
ret = append(ret, h.Header)
19+
}
20+
return ret, nil
21+
}
22+
23+
func MakeHeaderStream(headers ...Header) <-chan *HeaderOrError {
24+
ch := make(chan *HeaderOrError, len(headers))
25+
for _, h := range headers {
26+
ch <- &HeaderOrError{
27+
Header: h,
28+
Error: nil,
29+
}
30+
}
31+
close(ch)
32+
return ch
33+
}

core/headers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ func (sh syncHeaders) SetupHeadersForUpdate(ctx context.Context, src, dst ChainL
135135
logger.ErrorContext(ctx, "error ensuring different chains", err)
136136
return nil, err
137137
}
138-
return src.SetupHeadersForUpdate(ctx, dst, sh.GetLatestFinalizedHeader(src.ChainID()))
138+
return SetupHeadersForUpdateSync(src, ctx, dst, sh.GetLatestFinalizedHeader(src.ChainID()))
139139
}
140140

141141
// SetupBothHeadersForUpdate returns both `src` and `dst` chain's headers to update the clients on each chain

core/provers.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ type StateProver interface {
3434
ProveHostConsensusState(ctx QueryContext, height exported.Height, consensusState exported.ConsensusState) (proof []byte, err error)
3535
}
3636

37+
type HeaderOrError struct {
38+
Header Header
39+
Error error
40+
}
41+
3742
// LightClient provides functions for creating and updating on-chain light clients on the counterparty chain
3843
type LightClient interface {
3944
FinalityAware
@@ -44,9 +49,11 @@ type LightClient interface {
4449
CreateInitialLightClientState(ctx context.Context, height exported.Height) (exported.ClientState, exported.ConsensusState, error)
4550

4651
// SetupHeadersForUpdate returns the finalized header and any intermediate headers needed to apply it to the client on the counterpaty chain
47-
// The order of the returned header slice should be as: [<intermediate headers>..., <update header>]
48-
// if the header slice's length == 0 and err == nil, the relayer should skips the update-client
49-
SetupHeadersForUpdate(ctx context.Context, counterparty FinalityAwareChain, latestFinalizedHeader Header) ([]Header, error)
52+
// CONTRACT:
53+
// 1. The order of the returned header stream should be as: [<intermediate headers>..., <update header>]
54+
// 2. If the header stream's length == 0 and err == nil, the relayer should skips the update-client
55+
// 3. Goroutines that create the header stream should check `ctx.Done()` and should terminate processing if `ctx` is cancelled by the caller.
56+
SetupHeadersForUpdate(ctx context.Context, counterparty FinalityAwareChain, latestFinalizedHeader Header) (<-chan *HeaderOrError, error)
5057

5158
// CheckRefreshRequired returns if the on-chain light client needs to be updated.
5259
// For example, this requirement arises due to the trusting period mechanism.

otelcore/prover.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func (p *Prover) CreateInitialLightClientState(ctx context.Context, height ibcex
5252
return clientState, consensusState, err
5353
}
5454

55-
func (p *Prover) SetupHeadersForUpdate(ctx context.Context, counterparty core.FinalityAwareChain, latestFinalizedHeader core.Header) ([]core.Header, error) {
55+
func (p *Prover) SetupHeadersForUpdate(ctx context.Context, counterparty core.FinalityAwareChain, latestFinalizedHeader core.Header) (<-chan *core.HeaderOrError, error) {
5656
ctx, span := p.tracer.Start(ctx, "Prover.SetupHeadersForUpdate",
5757
core.WithChainAttributes(p.chainID),
5858
trace.WithAttributes(attribute.String("counterparty_chain_id", counterparty.ChainID())),

provers/mock/prover.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ func (pr *Prover) CreateInitialLightClientState(ctx context.Context, height expo
7272
}
7373

7474
// SetupHeadersForUpdate returns the finalized header and any intermediate headers needed to apply it to the client on the counterparty chain
75-
func (pr *Prover) SetupHeadersForUpdate(ctx context.Context, counterparty core.FinalityAwareChain, latestFinalizedHeader core.Header) ([]core.Header, error) {
76-
return []core.Header{latestFinalizedHeader.(*mocktypes.Header)}, nil
75+
func (pr *Prover) SetupHeadersForUpdate(ctx context.Context, counterparty core.FinalityAwareChain, latestFinalizedHeader core.Header) (<-chan *core.HeaderOrError, error) {
76+
return core.MakeHeaderStream(latestFinalizedHeader.(*mocktypes.Header)), nil
7777
}
7878

7979
func (pr *Prover) createMockHeader(ctx context.Context, height exported.Height) (core.Header, error) {

0 commit comments

Comments
 (0)