Skip to content

Commit df66cae

Browse files
authored
Merge pull request #122 from siburu/get-finalized-header
replace `GetLatestFinalizedHeader` with `GetFinalizedHeader`
2 parents 6c8a771 + 3f2a150 commit df66cae

File tree

11 files changed

+89
-48
lines changed

11 files changed

+89
-48
lines changed

chains/tendermint/cmd/light.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func updateLightCmd(ctx *config.Context) *cobra.Command {
103103
return err
104104
}
105105

106-
ah, err := prover.UpdateLightClient()
106+
ah, err := prover.UpdateLightClient(0)
107107
if err != nil {
108108
return err
109109
}

chains/tendermint/prover.go

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"time"
88

99
"github.com/cometbft/cometbft/light"
10+
"github.com/cometbft/cometbft/types"
1011
tmtypes "github.com/cometbft/cometbft/types"
1112
"github.com/cosmos/cosmos-sdk/codec"
1213
sdk "github.com/cosmos/cosmos-sdk/types"
@@ -107,13 +108,9 @@ func (pr *Prover) SetupHeadersForUpdate(counterparty core.FinalityAwareChain, la
107108
return []core.Header{&h}, nil
108109
}
109110

110-
// GetLatestFinalizedHeader returns the latest finalized header
111-
func (pr *Prover) GetLatestFinalizedHeader() (latestFinalizedHeader core.Header, err error) {
112-
h, err := pr.UpdateLightClient()
113-
if err != nil {
114-
return nil, err
115-
}
116-
return h, nil
111+
// GetFinalizedHeader returns the finalized header at `height`
112+
func (pr *Prover) GetFinalizedHeader(height uint64) (core.Header, error) {
113+
return pr.UpdateLightClient(int64(height))
117114
}
118115

119116
func (pr *Prover) CheckRefreshRequired(counterparty core.ChainInfoICS02Querier) (bool, error) {
@@ -183,7 +180,7 @@ func (pr *Prover) GetLatestLightHeight() (int64, error) {
183180
return client.LastTrustedHeight()
184181
}
185182

186-
func (pr *Prover) UpdateLightClient() (core.Header, error) {
183+
func (pr *Prover) UpdateLightClient(height int64) (core.Header, error) {
187184
// create database connection
188185
db, df, err := pr.NewLightDB()
189186
if err != nil {
@@ -196,14 +193,18 @@ func (pr *Prover) UpdateLightClient() (core.Header, error) {
196193
return nil, lightError(err)
197194
}
198195

199-
sh, err := client.Update(context.Background(), time.Now())
200-
if err != nil {
201-
return nil, lightError(err)
202-
}
203-
204-
if sh == nil {
205-
sh, err = client.TrustedLightBlock(0)
206-
if err != nil {
196+
var sh *types.LightBlock
197+
if height == 0 {
198+
if sh, err = client.Update(context.Background(), time.Now()); err != nil {
199+
return nil, lightError(err)
200+
} else if sh == nil {
201+
sh, err = client.TrustedLightBlock(0)
202+
if err != nil {
203+
return nil, lightError(err)
204+
}
205+
}
206+
} else {
207+
if sh, err = client.VerifyLightBlockAtHeight(context.Background(), height, time.Now()); err != nil {
207208
return nil, lightError(err)
208209
}
209210
}

chains/tendermint/query.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ func (c *Chain) QueryUnfinalizedRelayPackets(ctx core.QueryContext, counterparty
209209
}
210210

211211
var counterpartyCtx core.QueryContext
212-
if counterpartyH, err := counterparty.GetLatestFinalizedHeader(); err != nil {
212+
if counterpartyH, err := counterparty.GetFinalizedHeader(0); err != nil {
213213
return nil, err
214214
} else {
215215
counterpartyCtx = core.NewQueryContext(context.TODO(), counterpartyH.GetHeight())
@@ -262,7 +262,7 @@ func (c *Chain) QueryUnfinalizedRelayAcknowledgements(ctx core.QueryContext, cou
262262
}
263263

264264
var counterpartyCtx core.QueryContext
265-
if counterpartyH, err := counterparty.GetLatestFinalizedHeader(); err != nil {
265+
if counterpartyH, err := counterparty.GetFinalizedHeader(0); err != nil {
266266
return nil, err
267267
} else {
268268
counterpartyCtx = core.NewQueryContext(context.TODO(), counterpartyH.GetHeight())

cmd/tx.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ func transactionCmd(ctx *config.Context) *cobra.Command {
3838
}
3939

4040
func createClientsCmd(ctx *config.Context) *cobra.Command {
41+
const (
42+
flagSrcHeight = "src-height"
43+
flagDstHeight = "dst-height"
44+
)
45+
const (
46+
defaultSrcHeight = 0
47+
defaultDstHeight = 0
48+
)
4149
cmd := &cobra.Command{
4250
Use: "clients [path-name]",
4351
Short: "create a clients between two configured chains with a configured path",
@@ -58,9 +66,21 @@ func createClientsCmd(ctx *config.Context) *cobra.Command {
5866
return err
5967
}
6068

61-
return core.CreateClients(c[src], c[dst])
69+
srcHeight, err := cmd.Flags().GetUint64(flagSrcHeight)
70+
if err != nil {
71+
return err
72+
}
73+
74+
dstHeight, err := cmd.Flags().GetUint64(flagDstHeight)
75+
if err != nil {
76+
return err
77+
}
78+
79+
return core.CreateClients(c[src], c[dst], srcHeight, dstHeight)
6280
},
6381
}
82+
cmd.Flags().Uint64(flagSrcHeight, defaultSrcHeight, "src header at this height is submitted to dst chain")
83+
cmd.Flags().Uint64(flagDstHeight, defaultDstHeight, "dst header at this height is submitted to src chain")
6484
return cmd
6585
}
6686

core/client.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ import (
88
"golang.org/x/sync/errgroup"
99
)
1010

11-
func CreateClients(src, dst *ProvableChain) error {
11+
func CreateClients(src, dst *ProvableChain, srcHeight, dstHeight uint64) error {
1212
logger := GetChainPairLogger(src, dst)
1313
defer logger.TimeTrack(time.Now(), "CreateClients")
1414
var (
1515
clients = &RelayMsgs{Src: []sdk.Msg{}, Dst: []sdk.Msg{}}
1616
)
1717

18-
srcH, dstH, err := getHeadersForCreateClient(src, dst)
18+
srcH, dstH, err := getHeadersForCreateClient(src, dst, srcHeight, dstHeight)
1919
if err != nil {
2020
logger.Error(
2121
"failed to get headers for create client",
@@ -118,14 +118,14 @@ func UpdateClients(src, dst *ProvableChain) error {
118118
}
119119

120120
// getHeadersForCreateClient calls UpdateLightWithHeader on the passed chains concurrently
121-
func getHeadersForCreateClient(src, dst LightClient) (srch, dsth Header, err error) {
121+
func getHeadersForCreateClient(src, dst LightClient, srcHeight, dstHeight uint64) (srch, dsth Header, err error) {
122122
var eg = new(errgroup.Group)
123123
eg.Go(func() error {
124-
srch, err = src.GetLatestFinalizedHeader()
124+
srch, err = src.GetFinalizedHeader(srcHeight)
125125
return err
126126
})
127127
eg.Go(func() error {
128-
dsth, err = dst.GetLatestFinalizedHeader()
128+
dsth, err = dst.GetFinalizedHeader(dstHeight)
129129
return err
130130
})
131131
if err := eg.Wait(); err != nil {

core/headers.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,12 @@ func (sh *syncHeaders) Updates(src, dst ChainInfoLightClient) error {
7777
return err
7878
}
7979

80-
srcHeader, err := src.GetLatestFinalizedHeader()
80+
srcHeader, err := src.GetFinalizedHeader(0)
8181
if err != nil {
8282
logger.Error("error getting latest finalized header of src", err)
8383
return err
8484
}
85-
dstHeader, err := dst.GetLatestFinalizedHeader()
85+
dstHeader, err := dst.GetFinalizedHeader(0)
8686
if err != nil {
8787
logger.Error("error getting latest finalized header of dst", err)
8888
return err

core/provers.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,10 @@ type LightClient interface {
4848

4949
// FinalityAware provides the capability to determine the finality of the chain
5050
type FinalityAware interface {
51-
// GetLatestFinalizedHeader returns the latest finalized header on this chain
52-
// The returned header is expected to be the latest one of headers that can be verified by the light client
53-
GetLatestFinalizedHeader() (latestFinalizedHeader Header, err error)
51+
// GetFinalizedHeader returns the finalized header on this chain corresponding to `height`.
52+
// If `height` is zero, this function returns the latest finalized header.
53+
// If the header at `height` isn't finalized yet, this function returns an error.
54+
GetFinalizedHeader(height uint64) (Header, error)
5455
}
5556

5657
// FinalityAwareChain is FinalityAware + Chain

core/send.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func GetFinalizedMsgResult(chain ProvableChain, msgID MsgID) (MsgResult, error)
2828

2929
if err := retry.Do(func() error {
3030
// query LFH for each retry because it can proceed.
31-
lfHeader, err := chain.GetLatestFinalizedHeader()
31+
lfHeader, err := chain.GetFinalizedHeader(0)
3232
if err != nil {
3333
return fmt.Errorf("failed to get latest finalized header: %v", err)
3434
}

provers/mock/prover.go

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ package mock
33
import (
44
"context"
55
"crypto/sha256"
6+
fmt "fmt"
67
"time"
78

89
"github.com/cosmos/cosmos-sdk/codec"
910
sdk "github.com/cosmos/cosmos-sdk/types"
1011
clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"
12+
"github.com/cosmos/ibc-go/v7/modules/core/exported"
1113

1214
mocktypes "github.com/datachainlab/ibc-mock-client/modules/light-clients/xx-mock/types"
1315
"github.com/hyperledger-labs/yui-relayer/core"
@@ -58,30 +60,47 @@ func (pr *Prover) SetupHeadersForUpdate(_ core.FinalityAwareChain, latestFinaliz
5860
return []core.Header{latestFinalizedHeader.(*mocktypes.Header)}, nil
5961
}
6062

61-
// GetLatestFinalizedHeader returns the latest finalized header
62-
func (pr *Prover) GetLatestFinalizedHeader() (latestFinalizedHeader core.Header, err error) {
63-
chainLatestHeight, err := pr.chain.LatestHeight()
63+
func (pr *Prover) createMockHeader(height exported.Height) (core.Header, error) {
64+
timestamp, err := pr.chain.Timestamp(height)
6465
if err != nil {
65-
return nil, err
66+
return nil, fmt.Errorf("failed to get block timestamp at height:%v", height)
67+
}
68+
return &mocktypes.Header{
69+
Height: clienttypes.Height{
70+
RevisionNumber: height.GetRevisionNumber(),
71+
RevisionHeight: height.GetRevisionHeight(),
72+
},
73+
Timestamp: uint64(timestamp.UnixNano()),
74+
}, nil
75+
}
76+
77+
func (pr *Prover) getDelayedLatestFinalizedHeight() (exported.Height, error) {
78+
height, err := pr.chain.LatestHeight()
79+
if err != nil {
80+
return nil, fmt.Errorf("failed to get latest height: %v", err)
6681
}
6782
for i := uint64(0); i < pr.config.FinalityDelay; i++ {
68-
if prevHeight, success := chainLatestHeight.Decrement(); success {
69-
chainLatestHeight = prevHeight
83+
if h, ok := height.Decrement(); ok {
84+
height = h
7085
} else {
7186
break
7287
}
7388
}
74-
timestamp, err := pr.chain.Timestamp(chainLatestHeight)
75-
if err != nil {
89+
return height, nil
90+
}
91+
92+
// GetFinalizedHeader returns the finalized header at `height`
93+
func (pr *Prover) GetFinalizedHeader(height uint64) (core.Header, error) {
94+
if latestFinalizedHeight, err := pr.getDelayedLatestFinalizedHeight(); err != nil {
7695
return nil, err
96+
} else if height == 0 {
97+
return pr.createMockHeader(latestFinalizedHeight)
98+
} else if height > latestFinalizedHeight.GetRevisionHeight() {
99+
return nil, fmt.Errorf("the requested height is greater than the latest finalized height: %v > %v", height, latestFinalizedHeight)
100+
} else {
101+
ics02Height := clienttypes.NewHeight(latestFinalizedHeight.GetRevisionNumber(), height)
102+
return pr.createMockHeader(ics02Height)
77103
}
78-
return &mocktypes.Header{
79-
Height: clienttypes.Height{
80-
RevisionNumber: chainLatestHeight.GetRevisionNumber(),
81-
RevisionHeight: chainLatestHeight.GetRevisionHeight(),
82-
},
83-
Timestamp: uint64(timestamp.UnixNano()),
84-
}, nil
85104
}
86105

87106
// CheckRefreshRequired always returns false because mock clients don't need refresh.

tests/cases/tm2tm/scripts/handshake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ retry 5 $RLY tendermint light init $CHAINID_TWO -f
2727
# add a path between chain0 and chain1
2828
$RLY paths add $CHAINID_ONE $CHAINID_TWO $PATH_NAME --file=./configs/path.json
2929

30-
retry 5 $RLY tx clients $PATH_NAME
30+
retry 5 $RLY tx clients --src-height 2 $PATH_NAME
3131
retry 5 $RLY tx connection $PATH_NAME
3232
retry 5 $RLY tx channel $PATH_NAME

0 commit comments

Comments
 (0)