Update rpc client header

(cherry picked from commit 091fa517c9)
This commit is contained in:
Sam Ricotta
2022-08-02 00:23:55 +02:00
parent eb762cf5d7
commit 91b2a73833
16 changed files with 230 additions and 24 deletions
+18
View File
@@ -25,6 +25,8 @@ func RPCRoutes(c *lrpc.Client) map[string]*rpcserver.RPCFunc {
"genesis": rpcserver.NewRPCFunc(makeGenesisFunc(c), ""),
"genesis_chunked": rpcserver.NewRPCFunc(makeGenesisChunkedFunc(c), ""),
"block": rpcserver.NewRPCFunc(makeBlockFunc(c), "height"),
"header": rpcserver.NewRPCFunc(makeHeaderFunc(c), "height"),
"header_by_hash": rpcserver.NewRPCFunc(makeHeaderByHashFunc(c), "hash"),
"block_by_hash": rpcserver.NewRPCFunc(makeBlockByHashFunc(c), "hash"),
"block_results": rpcserver.NewRPCFunc(makeBlockResultsFunc(c), "height"),
"commit": rpcserver.NewRPCFunc(makeCommitFunc(c), "height"),
@@ -109,6 +111,22 @@ func makeBlockFunc(c *lrpc.Client) rpcBlockFunc {
}
}
type rpcHeaderFunc func(ctx *rpctypes.Context, height *int64) (*ctypes.ResultHeader, error)
func makeHeaderFunc(c *lrpc.Client) rpcHeaderFunc {
return func(ctx *rpctypes.Context, height *int64) (*ctypes.ResultHeader, error) {
return c.Header(ctx.Context(), height)
}
}
type rpcHeaderByHashFunc func(ctx *rpctypes.Context, hash []byte) (*ctypes.ResultHeader, error)
func makeHeaderByHashFunc(c *lrpc.Client) rpcHeaderByHashFunc {
return func(ctx *rpctypes.Context, hash []byte) (*ctypes.ResultHeader, error) {
return c.HeaderByHash(ctx.Context(), hash)
}
}
type rpcBlockByHashFunc func(ctx *rpctypes.Context, hash []byte) (*ctypes.ResultBlock, error)
func makeBlockByHashFunc(c *lrpc.Client) rpcBlockByHashFunc {
+34
View File
@@ -440,6 +440,40 @@ func (c *Client) BlockResults(ctx context.Context, height *int64) (*ctypes.Resul
return res, nil
}
// Header fetches and verifies the header directly via the light client
func (c *Client) Header(ctx context.Context, height *int64) (*ctypes.ResultHeader, error) {
lb, err := c.updateLightClientIfNeededTo(ctx, height)
if err != nil {
return nil, err
}
return &ctypes.ResultHeader{Header: lb.Header}, nil
}
// HeaderByHash calls rpcclient#HeaderByHash and updates the client if it's falling behind.
func (c *Client) HeaderByHash(ctx context.Context, hash tmbytes.HexBytes) (*ctypes.ResultHeader, error) {
res, err := c.next.HeaderByHash(ctx, hash)
if err != nil {
return nil, err
}
if err := res.Header.ValidateBasic(); err != nil {
return nil, err
}
lb, err := c.updateLightClientIfNeededTo(ctx, &res.Header.Height)
if err != nil {
return nil, err
}
if !bytes.Equal(lb.Header.Hash(), res.Header.Hash()) {
return nil, fmt.Errorf("primary header hash does not match trusted header hash. (%X != %X)",
lb.Header.Hash(), res.Header.Hash())
}
return res, nil
}
func (c *Client) Commit(ctx context.Context, height *int64) (*ctypes.ResultCommit, error) {
// Update the light client if we're behind and retrieve the light block at the requested height
// or at the latest height if no height is provided.