Skip to content

Commit

Permalink
add get latest value with head data
Browse files Browse the repository at this point in the history
  • Loading branch information
ettec committed Nov 11, 2024
1 parent d37df61 commit 9e7ea21
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 4 deletions.
8 changes: 8 additions & 0 deletions pkg/loop/internal/pb/contract_reader.proto
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import "google/protobuf/empty.proto";

service ContractReader {
rpc GetLatestValue (GetLatestValueRequest) returns (GetLatestValueReply) {}
rpc GetLatestValueWithHeadData (GetLatestValueRequest) returns (GetLatestValueWithHeadDataReply) {}
rpc BatchGetLatestValues (BatchGetLatestValuesRequest) returns (BatchGetLatestValuesReply) {}
rpc QueryKey(QueryKeyRequest) returns (QueryKeyReply) {}
rpc Bind(BindRequest) returns (google.protobuf.Empty) {}
Expand Down Expand Up @@ -51,6 +52,13 @@ message GetLatestValueReply {
VersionedBytes ret_val = 1;
}


// GetLatestValueWithHeadDataReply has return arguments for [github.com/smartcontractkit/chainlink-common/pkg/types.ContractReader.GetLatestValueWithHeadData].
message GetLatestValueWithHeadDataReply {
VersionedBytes ret_val = 1;
Head head_data = 2;
}

// BatchGetLatestValuesReply has return arguments for [github.com/smartcontractkit/chainlink-common/pkg/types.ContractReader.BatchGetLatestValues].
message BatchGetLatestValuesReply {
repeated ContractBatchResult results = 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,44 @@ func (c *Client) GetLatestValue(ctx context.Context, readIdentifier string, conf
return DecodeVersionedBytes(retVal, reply.RetVal)
}

func (c *Client) GetLatestValueWithHeadData(ctx context.Context, readIdentifier string, confidenceLevel primitives.ConfidenceLevel, params, retVal any) (*types.Head, error) {
_, asValueType := retVal.(*values.Value)

versionedParams, err := EncodeVersionedBytes(params, c.encodeWith)
if err != nil {
return nil, err
}

pbConfidence, err := confidenceToProto(confidenceLevel)
if err != nil {
return nil, err
}

reply, err := c.grpc.GetLatestValueWithHeadData(

Check failure on line 212 in pkg/loop/internal/relayer/pluginprovider/contractreader/contract_reader.go

View workflow job for this annotation

GitHub Actions / build-test

c.grpc.GetLatestValueWithHeadData undefined (type "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/pb".ContractReaderClient has no field or method GetLatestValueWithHeadData)

Check failure on line 212 in pkg/loop/internal/relayer/pluginprovider/contractreader/contract_reader.go

View workflow job for this annotation

GitHub Actions / benchmark

c.grpc.GetLatestValueWithHeadData undefined (type "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/pb".ContractReaderClient has no field or method GetLatestValueWithHeadData)
ctx,
&pb.GetLatestValueRequest{
ReadIdentifier: readIdentifier,
Confidence: pbConfidence,
Params: versionedParams,
AsValueType: asValueType,
},
)
if err != nil {
return nil, net.WrapRPCErr(err)
}

var headData *types.Head
if reply.HeadData != nil {
headData = &types.Head{
Height: reply.HeadData.Height,
Hash: reply.HeadData.Hash,
Timestamp: reply.HeadData.Timestamp,
}
}

return headData, DecodeVersionedBytes(retVal, reply.RetVal)
}

func (c *Client) BatchGetLatestValues(ctx context.Context, request types.BatchGetLatestValuesRequest) (types.BatchGetLatestValuesResult, error) {
pbRequest, err := convertBatchGetLatestValuesRequestToProto(request, c.encodeWith)
if err != nil {
Expand Down Expand Up @@ -360,6 +398,53 @@ func (c *Server) GetLatestValue(ctx context.Context, request *pb.GetLatestValueR
return &pb.GetLatestValueReply{RetVal: versionedBytes}, nil
}

func (c *Server) GetLatestValueWithHeadData(ctx context.Context, request *pb.GetLatestValueRequest) (*pb.GetLatestValueWithHeadDataReply, error) {

Check failure on line 401 in pkg/loop/internal/relayer/pluginprovider/contractreader/contract_reader.go

View workflow job for this annotation

GitHub Actions / build-test

undefined: pb.GetLatestValueWithHeadDataReply

Check failure on line 401 in pkg/loop/internal/relayer/pluginprovider/contractreader/contract_reader.go

View workflow job for this annotation

GitHub Actions / benchmark

undefined: pb.GetLatestValueWithHeadDataReply
params, err := getContractEncodedType(request.ReadIdentifier, c.impl, true)
if err != nil {
return nil, err
}

if err = DecodeVersionedBytes(params, request.Params); err != nil {
return nil, err
}

retVal, err := getContractEncodedType(request.ReadIdentifier, c.impl, false)
if err != nil {
return nil, err
}

confidenceLevel, err := confidenceFromProto(request.Confidence)
if err != nil {
return nil, err
}

headData, err := c.impl.GetLatestValueWithHeadData(ctx, request.ReadIdentifier, confidenceLevel, params, retVal)
if err != nil {
return nil, err
}

encodeWith := EncodingVersion(request.Params.Version)
if request.AsValueType {
encodeWith = ValuesEncodingVersion
}

versionedBytes, err := EncodeVersionedBytes(retVal, encodeWith)
if err != nil {
return nil, err
}

var headDataProto *pb.Head
if headData != nil {
headDataProto = &pb.Head{
Height: headData.Height,
Hash: headData.Hash,
Timestamp: headData.Timestamp,
}
}

return &pb.GetLatestValueWithHeadDataReply{RetVal: versionedBytes, HeadData: headDataProto}, nil

Check failure on line 445 in pkg/loop/internal/relayer/pluginprovider/contractreader/contract_reader.go

View workflow job for this annotation

GitHub Actions / build-test

undefined: pb.GetLatestValueWithHeadDataReply

Check failure on line 445 in pkg/loop/internal/relayer/pluginprovider/contractreader/contract_reader.go

View workflow job for this annotation

GitHub Actions / benchmark

undefined: pb.GetLatestValueWithHeadDataReply
}

func (c *Server) BatchGetLatestValues(ctx context.Context, pbRequest *pb.BatchGetLatestValuesRequest) (*pb.BatchGetLatestValuesReply, error) {
request, err := convertBatchGetLatestValuesRequestFromProto(pbRequest, c.impl)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,15 @@ func (f *fakeContractReader) GetLatestValue(_ context.Context, readIdentifier st
return nil
}

func (f *fakeContractReader) GetLatestValueWithHeadData(_ context.Context, readIdentifier string, confidenceLevel primitives.ConfidenceLevel, params, returnVal any) (*types.Head, error) {
err := f.GetLatestValue(context.Background(), readIdentifier, confidenceLevel, params, returnVal)
if err != nil {
return nil, err
}

return &types.Head{}, nil
}

func (f *fakeContractReader) BatchGetLatestValues(_ context.Context, request types.BatchGetLatestValuesRequest) (types.BatchGetLatestValuesResult, error) {
result := make(types.BatchGetLatestValuesResult)
for requestContract, requestContractBatch := range request {
Expand Down
8 changes: 4 additions & 4 deletions pkg/types/contract_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ type ContractReader interface {
// Passing in a *values.Value as the returnVal will encode the return value as an appropriate value.Value instance.
GetLatestValue(ctx context.Context, readIdentifier string, confidenceLevel primitives.ConfidenceLevel, params, returnVal any) error

// GetLatestValueWithHeadData should be used in the same way as GetLatestValue, but also returns the head data.
GetLatestValueWithHeadData(ctx context.Context, readIdentifier string, confidenceLevel primitives.ConfidenceLevel, params, returnVal any) (Head, error)
// GetLatestValueWithHeadData should be used in the same way as GetLatestValue, but also returns the head data if available.
GetLatestValueWithHeadData(ctx context.Context, readIdentifier string, confidenceLevel primitives.ConfidenceLevel, params, returnVal any) (*Head, error)

// BatchGetLatestValues batches get latest value calls based on request, which is grouped by contract names that each have a slice of BatchRead.
// BatchGetLatestValuesRequest params and returnVal follow same rules as GetLatestValue params and returnVal arguments, with difference in how response is returned.
Expand Down Expand Up @@ -133,8 +133,8 @@ func (UnimplementedContractReader) GetLatestValue(ctx context.Context, readIdent
return UnimplementedError("ContractReader.GetLatestValue unimplemented")
}

func (UnimplementedContractReader) GetLatestValueWithHeadData(ctx context.Context, readIdentifier string, confidenceLevel primitives.ConfidenceLevel, params, returnVal any) (Head, error) {
return Head{}, UnimplementedError("ContractReader.GetLatestValueWithHeadData unimplemented")
func (UnimplementedContractReader) GetLatestValueWithHeadData(ctx context.Context, readIdentifier string, confidenceLevel primitives.ConfidenceLevel, params, returnVal any) (*Head, error) {
return nil, UnimplementedError("ContractReader.GetLatestValueWithHeadData unimplemented")
}

func (UnimplementedContractReader) BatchGetLatestValues(ctx context.Context, request BatchGetLatestValuesRequest) (BatchGetLatestValuesResult, error) {
Expand Down
25 changes: 25 additions & 0 deletions pkg/types/interfacetests/chain_components_interface_tests.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package interfacetests

import (
"context"
"errors"
"fmt"
"reflect"
Expand Down Expand Up @@ -56,8 +57,32 @@ var AnySliceToReadWithoutAnArgument = []uint64{3, 4}

const AnyExtraValue = 3

type withHeadDataTester[T TestingT[T]] struct {
ChainComponentsInterfaceTester[T]
}

func (h *withHeadDataTester[T]) GetContractReader(t T) types.ContractReader {
h.ChainComponentsInterfaceTester.GetContractReader(t)
return &withHeadDataContractReader[T]{h.ChainComponentsInterfaceTester.GetContractReader(t), t}
}

type withHeadDataContractReader[T TestingT[T]] struct {
types.ContractReader
t T
}

func (h *withHeadDataContractReader[T]) GetLatestValue(ctx context.Context, readIdentifier string, confidenceLevel primitives.ConfidenceLevel, params, returnVal any) error {
headData, err := h.GetLatestValueWithHeadData(ctx, readIdentifier, confidenceLevel, params, returnVal)
if err != nil {
return err
}
assert.NotNil(h.t, headData)
return nil
}

func RunContractReaderInterfaceTests[T TestingT[T]](t T, tester ChainComponentsInterfaceTester[T], mockRun bool) {
t.Run("GetLatestValue for "+tester.Name(), func(t T) { runContractReaderGetLatestValueInterfaceTests(t, tester, mockRun) })
t.Run("GetLatestValueWithHeadData for "+tester.Name(), func(t T) { runContractReaderGetLatestValueInterfaceTests(t, &withHeadDataTester[T]{tester}, mockRun) })
t.Run("BatchGetLatestValues for "+tester.Name(), func(t T) { runContractReaderBatchGetLatestValuesInterfaceTests(t, tester, mockRun) })
t.Run("QueryKey for "+tester.Name(), func(t T) { runQueryKeyInterfaceTests(t, tester) })
}
Expand Down

0 comments on commit 9e7ea21

Please sign in to comment.