Skip to content

Commit

Permalink
fix light client
Browse files Browse the repository at this point in the history
- fix absence proof verification
- fix querying against the latest state
  • Loading branch information
ashcherbakov committed Jan 19, 2022
1 parent 85870de commit fe2f0b0
Showing 1 changed file with 24 additions and 11 deletions.
35 changes: 24 additions & 11 deletions light/rpc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,24 @@ func (c *Client) ABCIQuery(ctx context.Context, path string, data tmbytes.HexByt
}

// ABCIQueryWithOptions returns an error if opts.Prove is false.
// ABCIQueryWithOptions returns the result for the given height (opts.Height).
// If no height is provided, the results of the block preceding the latest are returned.
func (c *Client) ABCIQueryWithOptions(ctx context.Context, path string, data tmbytes.HexBytes,
opts rpcclient.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) {

// always request the proof
opts.Prove = true

if opts.Height == 0 {
res, err := c.next.Status(ctx)
if err != nil {
return nil, fmt.Errorf("can't get latest height: %w", err)
}
// Can't return the latest block results here because we won't be able to
// prove them. Return the results for the previous block instead.
opts.Height = res.SyncInfo.LatestBlockHeight - 1
}

res, err := c.next.ABCIQueryWithOptions(ctx, path, data, opts)
if err != nil {
return nil, err
Expand Down Expand Up @@ -164,24 +176,25 @@ func (c *Client) ABCIQueryWithOptions(ctx context.Context, path string, data tmb
}

// Validate the value proof against the trusted header.
if resp.Value != nil {
// 1) build a Merkle key path from path and resp.Key
if c.keyPathFn == nil {
return nil, errors.New("please configure Client with KeyPathFn option")
}

kp, err := c.keyPathFn(path, resp.Key)
if err != nil {
return nil, fmt.Errorf("can't build merkle key path: %w", err)
}
// build a Merkle key path from path and resp.Key
if c.keyPathFn == nil {
return nil, errors.New("please configure Client with KeyPathFn option")
}

// 2) verify value
kp, err := c.keyPathFn(path, resp.Key)
if err != nil {
return nil, fmt.Errorf("can't build merkle key path: %w", err)
}

// verify value
if resp.Value != nil {
err = c.prt.VerifyValue(resp.ProofOps, l.AppHash, kp.String(), resp.Value)
if err != nil {
return nil, fmt.Errorf("verify value proof: %w", err)
}
} else { // OR validate the absence proof against the trusted header.
err = c.prt.VerifyAbsence(resp.ProofOps, l.AppHash, string(resp.Key))
err = c.prt.VerifyAbsence(resp.ProofOps, l.AppHash, kp.String())
if err != nil {
return nil, fmt.Errorf("verify absence proof: %w", err)
}
Expand Down

0 comments on commit fe2f0b0

Please sign in to comment.