Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BCF-3247] - Remove pending from boundContract and use confidence instead for CR #573

Merged
merged 6 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
447 changes: 225 additions & 222 deletions pkg/loop/internal/pb/chain_reader.pb.go

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions pkg/loop/internal/pb/chain_reader.proto
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ service ChainReader {
message GetLatestValueRequest {
string contract_name = 1;
string method = 2;
VersionedBytes params = 3;
Confidence confidence = 3;
VersionedBytes params = 4;
}

// QueryKeyRequest has arguments for [github.com/smartcontractkit/chainlink-common/pkg/types.ChainReader.QueryKey].
Expand Down Expand Up @@ -60,7 +61,6 @@ message Sequence {
message BoundContract {
string address = 1;
string name = 2;
bool pending = 3;
}

enum ComparisonOperator {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,18 +130,23 @@ func DecodeVersionedBytes(res any, vData *pb.VersionedBytes) error {
return nil
}

func (c *Client) GetLatestValue(ctx context.Context, contractName, method string, params, retVal any) error {
func (c *Client) GetLatestValue(ctx context.Context, contractName, method string, confidenceLevel primitives.ConfidenceLevel, params, returnVal any) error {
jmank88 marked this conversation as resolved.
Show resolved Hide resolved
versionedParams, err := EncodeVersionedBytes(params, c.encodeWith)
if err != nil {
return err
}

reply, err := c.grpc.GetLatestValue(ctx, &pb.GetLatestValueRequest{ContractName: contractName, Method: method, Params: versionedParams})
pbConfidence, err := confidenceToProto(confidenceLevel)
if err != nil {
return err
}

reply, err := c.grpc.GetLatestValue(ctx, &pb.GetLatestValueRequest{ContractName: contractName, Method: method, Params: versionedParams, Confidence: pbConfidence})
if err != nil {
return net.WrapRPCErr(err)
}

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

func (c *Client) QueryKey(ctx context.Context, contractName string, filter query.KeyFilter, limitAndSort query.LimitAndSort, sequenceDataType any) ([]types.Sequence, error) {
Expand All @@ -166,7 +171,7 @@ func (c *Client) QueryKey(ctx context.Context, contractName string, filter query
func (c *Client) Bind(ctx context.Context, bindings []types.BoundContract) error {
pbBindings := make([]*pb.BoundContract, len(bindings))
for i, b := range bindings {
pbBindings[i] = &pb.BoundContract{Address: b.Address, Name: b.Name, Pending: b.Pending}
pbBindings[i] = &pb.BoundContract{Address: b.Address, Name: b.Name}
}
_, err := c.grpc.Bind(ctx, &pb.BindRequest{Bindings: pbBindings})
return net.WrapRPCErr(err)
Expand Down Expand Up @@ -211,16 +216,22 @@ func (c *Server) GetLatestValue(ctx context.Context, request *pb.GetLatestValueR
return nil, err
}

retVal, err := getContractEncodedType(request.ContractName, request.Method, c.impl, false)
returnVal, err := getContractEncodedType(request.ContractName, request.Method, c.impl, false)
if err != nil {
return nil, err
}
err = c.impl.GetLatestValue(ctx, request.ContractName, request.Method, params, retVal)

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

encodedRetVal, err := EncodeVersionedBytes(retVal, EncodingVersion(request.Params.Version))
err = c.impl.GetLatestValue(ctx, request.ContractName, request.Method, confidenceLevel, params, returnVal)
if err != nil {
return nil, err
}

encodedRetVal, err := EncodeVersionedBytes(returnVal, EncodingVersion(request.Params.Version))
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -260,7 +271,7 @@ func (c *Server) QueryKey(ctx context.Context, request *pb.QueryKeyRequest) (*pb
func (c *Server) Bind(ctx context.Context, bindings *pb.BindRequest) (*emptypb.Empty, error) {
tBindings := make([]types.BoundContract, len(bindings.Bindings))
for i, b := range bindings.Bindings {
tBindings[i] = types.BoundContract{Address: b.Address, Name: b.Name, Pending: b.Pending}
tBindings[i] = types.BoundContract{Address: b.Address, Name: b.Name}
}

return &emptypb.Empty{}, c.impl.Bind(ctx, tBindings)
Expand Down Expand Up @@ -310,8 +321,12 @@ func convertExpressionToProto(expression query.Expression) (*pb.Expression, erro
Operator: pb.ComparisonOperator(primitive.Operator),
}}
case *primitives.Confidence:
pbConfidence, err := confidenceToProto(primitive.ConfidenceLevel)
if err != nil {
return nil, err
}
pbExpression.GetPrimitive().Primitive = &pb.Primitive_Confidence{
Confidence: confidenceToProto(primitive.ConfidenceLevel),
Confidence: pbConfidence,
}
case *primitives.Timestamp:
pbExpression.GetPrimitive().Primitive = &pb.Primitive_Timestamp{
Expand Down Expand Up @@ -348,14 +363,14 @@ func convertExpressionToProto(expression query.Expression) (*pb.Expression, erro
return pbExpression, nil
}

func confidenceToProto(level primitives.ConfidenceLevel) pb.Confidence {
switch level {
func confidenceToProto(confidenceLevel primitives.ConfidenceLevel) (pb.Confidence, error) {
switch confidenceLevel {
case primitives.Finalized:
return pb.Confidence_Finalized
return pb.Confidence_Finalized, nil
case primitives.Unconfirmed:
return pb.Confidence_Unconfirmed
return pb.Confidence_Unconfirmed, nil
default:
panic("invalid confidence level")
return -1, fmt.Errorf("invalid confidence level %s", confidenceLevel)
}
}

Expand Down Expand Up @@ -457,7 +472,8 @@ func convertExpressionFromProto(pbExpression *pb.Expression) (query.Expression,
}
return query.Comparator(primitive.Comparator.Name, valueComparators...), nil
case *pb.Primitive_Confidence:
return query.Confidence(confidenceFromProto(primitive.Confidence)), nil
confidence, err := confidenceFromProto(primitive.Confidence)
return query.Confidence(confidence), err
case *pb.Primitive_Block:
return query.Block(primitive.Block.BlockNumber, primitives.ComparisonOperator(primitive.Block.Operator)), nil
case *pb.Primitive_TxHash:
Expand All @@ -472,14 +488,14 @@ func convertExpressionFromProto(pbExpression *pb.Expression) (query.Expression,
}
}

func confidenceFromProto(conf pb.Confidence) primitives.ConfidenceLevel {
switch conf {
func confidenceFromProto(pbConfidence pb.Confidence) (primitives.ConfidenceLevel, error) {
switch pbConfidence {
case pb.Confidence_Finalized:
return primitives.Finalized
return primitives.Finalized, nil
case pb.Confidence_Unconfirmed:
return primitives.Unconfirmed
return primitives.Unconfirmed, nil
default:
panic("invalid confidence level")
return "", fmt.Errorf("invalid pb confidence level: %d", pbConfidence)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
chainreadertest "github.com/smartcontractkit/chainlink-common/pkg/loop/internal/relayer/pluginprovider/chainreader/test"
"github.com/smartcontractkit/chainlink-common/pkg/types"
"github.com/smartcontractkit/chainlink-common/pkg/types/query"
"github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives"
"github.com/smartcontractkit/chainlink-common/pkg/utils/tests"

. "github.com/smartcontractkit/chainlink-common/pkg/types/interfacetests" //nolint
Expand Down Expand Up @@ -136,15 +137,15 @@ func TestGetLatestValue(t *testing.T) {
nilTester.Setup(t)
nilCr := nilTester.GetChainReader(t)

err := nilCr.GetLatestValue(ctx, "", "method", "anything", "anything")
err := nilCr.GetLatestValue(ctx, "", "method", primitives.Unconfirmed, "anything", "anything")
assert.Equal(t, codes.Unimplemented, status.Convert(err).Code())
})

for _, errorType := range errorTypes {
es.err = errorType
t.Run("GetLatestValue unwraps errors from server "+errorType.Error(), func(t *testing.T) {
ctx := tests.Context(t)
err := chainReader.GetLatestValue(ctx, "", "method", nil, "anything")
err := chainReader.GetLatestValue(ctx, "", "method", primitives.Unconfirmed, nil, "anything")
assert.True(t, errors.Is(err, errorType))
})
}
Expand All @@ -153,7 +154,7 @@ func TestGetLatestValue(t *testing.T) {
es.err = nil
t.Run("GetLatestValue returns error if type cannot be encoded in the wire format", func(t *testing.T) {
ctx := tests.Context(t)
err := chainReader.GetLatestValue(ctx, "", "method", &cannotEncode{}, &TestStruct{})
err := chainReader.GetLatestValue(ctx, "", "method", primitives.Unconfirmed, &cannotEncode{}, &TestStruct{})
assert.True(t, errors.Is(err, types.ErrInvalidType))
})
}
Expand Down Expand Up @@ -227,8 +228,9 @@ type fakeChainReaderInterfaceTester struct {
func (it *fakeChainReaderInterfaceTester) Setup(_ *testing.T) {
fake, ok := it.impl.(*fakeChainReader)
if ok {
fake.vals = []valConfidencePair{}
fake.triggers = []eventConfidencePair{}
fake.stored = []TestStruct{}
fake.triggers = []TestStruct{}
}
}

Expand All @@ -243,10 +245,22 @@ func (it *fakeChainReaderInterfaceTester) GetBindings(_ *testing.T) []types.Boun
}
}

func (it *fakeChainReaderInterfaceTester) SetLatestValue(t *testing.T, testStruct *TestStruct) {
func (it *fakeChainReaderInterfaceTester) SetTestStructLatestValue(t *testing.T, testStruct *TestStruct) {
fake, ok := it.impl.(*fakeChainReader)
assert.True(t, ok)
fake.SetLatestValue(testStruct)
fake.SetTestStructLatestValue(testStruct)
}

func (it *fakeChainReaderInterfaceTester) SetUintLatestValue(t *testing.T, val uint64, forCall ExpectedGetLatestValueArgs) {
fake, ok := it.impl.(*fakeChainReader)
assert.True(t, ok)
fake.SetUintLatestValue(val, forCall)
}

func (it *fakeChainReaderInterfaceTester) GenerateBlocksTillConfidenceLevel(t *testing.T, contractName, readName string, confidenceLevel primitives.ConfidenceLevel) {
fake, ok := it.impl.(*fakeChainReader)
assert.True(t, ok)
fake.GenerateBlocksTillConfidenceLevel(t, contractName, readName, confidenceLevel)
}

func (it *fakeChainReaderInterfaceTester) TriggerEvent(t *testing.T, testStruct *TestStruct) {
Expand All @@ -259,11 +273,22 @@ func (it *fakeChainReaderInterfaceTester) MaxWaitTimeForEvents() time.Duration {
return time.Millisecond * 100
}

type valConfidencePair struct {
val uint64
confidenceLevel primitives.ConfidenceLevel
}

type eventConfidencePair struct {
testStruct TestStruct
confidenceLevel primitives.ConfidenceLevel
}

type fakeChainReader struct {
fakeTypeProvider
vals []valConfidencePair
triggers []eventConfidencePair
stored []TestStruct
lock sync.Mutex
triggers []TestStruct
}

func (f *fakeChainReader) Start(_ context.Context) error { return nil }
Expand All @@ -280,14 +305,29 @@ func (f *fakeChainReader) Bind(_ context.Context, _ []types.BoundContract) error
return nil
}

func (f *fakeChainReader) SetLatestValue(ts *TestStruct) {
func (f *fakeChainReader) SetTestStructLatestValue(ts *TestStruct) {
f.lock.Lock()
defer f.lock.Unlock()
f.stored = append(f.stored, *ts)
}

func (f *fakeChainReader) GetLatestValue(_ context.Context, contractName, method string, params, returnVal any) error {
if method == MethodReturningUint64 {
func (f *fakeChainReader) SetUintLatestValue(val uint64, _ ExpectedGetLatestValueArgs) {
f.lock.Lock()
defer f.lock.Unlock()
f.vals = append(f.vals, valConfidencePair{val: val, confidenceLevel: primitives.Unconfirmed})
}

func (f *fakeChainReader) GetLatestValue(_ context.Context, contractName, method string, confidenceLevel primitives.ConfidenceLevel, params, returnVal any) error {
if method == MethodReturningAlterableUint64 {
r := returnVal.(*uint64)
for i := len(f.vals) - 1; i >= 0; i-- {
if f.vals[i].confidenceLevel == confidenceLevel {
*r = f.vals[i].val
return nil
}
}
return fmt.Errorf("%w: no val with %s confidence was found ", types.ErrNotFound, confidenceLevel)
} else if method == MethodReturningUint64 {
r := returnVal.(*uint64)
if contractName == AnyContractName {
*r = AnyValueToReadWithoutAnArgument
Expand All @@ -314,23 +354,26 @@ func (f *fakeChainReader) GetLatestValue(_ context.Context, contractName, method
if len(f.triggers) == 0 {
return types.ErrNotFound
}
*returnVal.(*TestStruct) = f.triggers[len(f.triggers)-1]
return nil

for i := len(f.triggers) - 1; i >= 0; i-- {
if f.triggers[i].confidenceLevel == confidenceLevel {
*returnVal.(*TestStruct) = f.triggers[i].testStruct
return nil
}
}

return fmt.Errorf("%w: no event with %s confidence was found ", types.ErrNotFound, confidenceLevel)
} else if method == EventWithFilterName {
f.lock.Lock()
defer f.lock.Unlock()
param := params.(*FilterEventParams)
for i := len(f.triggers) - 1; i >= 0; i-- {
if *f.triggers[i].Field == param.Field {
*returnVal.(*TestStruct) = f.triggers[i]
if *f.triggers[i].testStruct.Field == param.Field {
*returnVal.(*TestStruct) = f.triggers[i].testStruct
return nil
}
}
return types.ErrNotFound
} else if method == DifferentMethodReturningUint64 {
r := returnVal.(*uint64)
*r = AnyDifferentValueToReadWithoutAnArgument
return nil
} else if method != MethodTakingLatestParamsReturningTestStruct {
return errors.New("unknown method " + method)
}
Expand All @@ -339,6 +382,9 @@ func (f *fakeChainReader) GetLatestValue(_ context.Context, contractName, method
defer f.lock.Unlock()
lp := params.(*LatestParams)
rv := returnVal.(*TestStruct)
if lp.I-1 >= len(f.stored) {
return errors.New("latest params index out of bounds for stored test structs")
}
*rv = f.stored[lp.I-1]
return nil
}
Expand All @@ -353,7 +399,7 @@ func (f *fakeChainReader) QueryKey(_ context.Context, _ string, filter query.Key

var sequences []types.Sequence
for _, trigger := range f.triggers {
sequences = append(sequences, types.Sequence{Data: trigger})
sequences = append(sequences, types.Sequence{Data: trigger.testStruct})
}

if !limitAndSort.HasSequenceSort() {
Expand All @@ -373,7 +419,20 @@ func (f *fakeChainReader) QueryKey(_ context.Context, _ string, filter query.Key
func (f *fakeChainReader) SetTrigger(testStruct *TestStruct) {
f.lock.Lock()
defer f.lock.Unlock()
f.triggers = append(f.triggers, *testStruct)
f.triggers = append(f.triggers, eventConfidencePair{testStruct: *testStruct, confidenceLevel: primitives.Unconfirmed})
}

func (f *fakeChainReader) GenerateBlocksTillConfidenceLevel(_ *testing.T, _, _ string, confidenceLevel primitives.ConfidenceLevel) {
f.lock.Lock()
defer f.lock.Unlock()
for i, val := range f.vals {
f.vals[i] = valConfidencePair{val: val.val, confidenceLevel: confidenceLevel}
}

for i, trigger := range f.triggers {
f.triggers[i] = eventConfidencePair{testStruct: trigger.testStruct, confidenceLevel: confidenceLevel}
}
return
}

type errChainReader struct {
Expand All @@ -390,7 +449,7 @@ func (e *errChainReader) Name() string { panic("unimplemented") }

func (e *errChainReader) HealthReport() map[string]error { panic("unimplemented") }

func (e *errChainReader) GetLatestValue(_ context.Context, _, _ string, _, _ any) error {
func (e *errChainReader) GetLatestValue(_ context.Context, _, _ string, _ primitives.ConfidenceLevel, _, _ any) error {
return e.err
}

Expand Down Expand Up @@ -418,7 +477,7 @@ func (pc *protoConversionTestChainReader) Name() string { panic("unimplemented")

func (pc *protoConversionTestChainReader) HealthReport() map[string]error { panic("unimplemented") }

func (pc *protoConversionTestChainReader) GetLatestValue(_ context.Context, _, _ string, _, _ any) error {
func (pc *protoConversionTestChainReader) GetLatestValue(_ context.Context, _, _ string, _ primitives.ConfidenceLevel, _, _ any) error {
return nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func (fakeTypeProvider) CreateContractType(_, itemType string, isEncode bool) (a
return &LatestParams{}, nil
}
return &TestStruct{}, nil
case MethodReturningUint64, DifferentMethodReturningUint64:
case MethodReturningUint64, MethodReturningAlterableUint64:
tmp := uint64(0)
return &tmp, nil
case MethodReturningUint64Slice:
Expand Down
Loading
Loading