-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add minimal ChainReader interface & types (#196)
Co-authored-by: Jordan Krage <[email protected]> Co-authored-by: Ryan Tinianov <[email protected]> Co-authored-by: ilija42 <[email protected]>
- Loading branch information
Showing
40 changed files
with
1,439 additions
and
145 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
golang 1.21.1 | ||
golang 1.21.4 | ||
golangci-lint 1.55.2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,7 @@ godoc: | |
|
||
PHONY: install-protoc | ||
install-protoc: | ||
script/install-protoc.sh 24.2 / | ||
script/install-protoc.sh 25.1 / | ||
go install google.golang.org/protobuf/cmd/[email protected]; go install google.golang.org/grpc/cmd/[email protected] | ||
|
||
.PHONY: mockery | ||
|
@@ -26,4 +26,4 @@ generate: mockery install-protoc | |
.PHONY: golangci-lint | ||
golangci-lint: ## Run golangci-lint for all issues. | ||
[ -d "./golangci-lint" ] || mkdir ./golangci-lint && \ | ||
docker run --rm -v $(shell pwd):/app -w /app golangci/golangci-lint:v1.55.2 golangci-lint run --max-issues-per-linter 0 --max-same-issues 0 > ./golangci-lint/$(shell date +%Y-%m-%d_%H:%M:%S).txt | ||
docker run --rm -v $(shell pwd):/app -w /app golangci/golangci-lint:v1.55.2 golangci-lint run --max-issues-per-linter 0 --max-same-issues 0 > ./golangci-lint/$(shell date +%Y-%m-%d_%H:%M:%S).txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
package internal | ||
|
||
import ( | ||
"context" | ||
jsonv1 "encoding/json" | ||
"fmt" | ||
|
||
"github.com/fxamacker/cbor/v2" | ||
jsonv2 "github.com/go-json-experiment/json" | ||
|
||
"github.com/smartcontractkit/chainlink-common/pkg/loop/internal/pb" | ||
"github.com/smartcontractkit/chainlink-common/pkg/types" | ||
) | ||
|
||
var _ types.ChainReader = (*chainReaderClient)(nil) | ||
|
||
type chainReaderClient struct { | ||
*brokerExt | ||
grpc pb.ChainReaderClient | ||
} | ||
|
||
// enum of all known encoding formats for versioned data | ||
const ( | ||
JSONEncodingVersion1 = iota | ||
JSONEncodingVersion2 | ||
CBOREncodingVersion | ||
) | ||
|
||
// Version to be used for encoding (version used for decoding is determined by data received) | ||
const CurrentEncodingVersion = CBOREncodingVersion | ||
|
||
func encodeVersionedBytes(data any, version int32) (*pb.VersionedBytes, error) { | ||
var bytes []byte | ||
var err error | ||
|
||
switch version { | ||
case JSONEncodingVersion1: | ||
bytes, err = jsonv1.Marshal(data) | ||
if err != nil { | ||
return nil, fmt.Errorf("%w: %w", types.ErrInvalidType, err) | ||
} | ||
case JSONEncodingVersion2: | ||
bytes, err = jsonv2.Marshal(data) | ||
if err != nil { | ||
return nil, fmt.Errorf("%w: %w", types.ErrInvalidType, err) | ||
} | ||
case CBOREncodingVersion: | ||
enco := cbor.CoreDetEncOptions() | ||
enco.Time = cbor.TimeRFC3339Nano | ||
var enc cbor.EncMode | ||
enc, err = enco.EncMode() | ||
if err != nil { | ||
return nil, err | ||
} | ||
bytes, err = enc.Marshal(data) | ||
if err != nil { | ||
return nil, fmt.Errorf("%w: %w", types.ErrInvalidType, err) | ||
} | ||
default: | ||
return nil, fmt.Errorf("unsupported encoding version %d for data %v", version, data) | ||
} | ||
|
||
return &pb.VersionedBytes{Version: uint32(version), Data: bytes}, nil | ||
} | ||
|
||
func decodeVersionedBytes(res any, vData *pb.VersionedBytes) error { | ||
var err error | ||
switch vData.Version { | ||
case JSONEncodingVersion1: | ||
err = jsonv1.Unmarshal(vData.Data, res) | ||
case JSONEncodingVersion2: | ||
err = jsonv2.Unmarshal(vData.Data, res) | ||
case CBOREncodingVersion: | ||
err = cbor.Unmarshal(vData.Data, res) | ||
default: | ||
return fmt.Errorf("unsupported encoding version %d for versionedData %v", vData.Version, vData.Data) | ||
} | ||
|
||
if err != nil { | ||
return fmt.Errorf("%w: %w", types.ErrInvalidType, err) | ||
} | ||
return nil | ||
} | ||
|
||
func (c *chainReaderClient) GetLatestValue(ctx context.Context, bc types.BoundContract, method string, params, retVal any) error { | ||
versionedParams, err := encodeVersionedBytes(params, CurrentEncodingVersion) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
boundContract := pb.BoundContract{Name: bc.Name, Address: bc.Address, Pending: bc.Pending} | ||
|
||
reply, err := c.grpc.GetLatestValue(ctx, &pb.GetLatestValueRequest{Bc: &boundContract, Method: method, Params: versionedParams}) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return decodeVersionedBytes(retVal, reply.RetVal) | ||
} | ||
|
||
var _ pb.ChainReaderServer = (*chainReaderServer)(nil) | ||
|
||
type chainReaderServer struct { | ||
pb.UnimplementedChainReaderServer | ||
impl types.ChainReader | ||
} | ||
|
||
func (c *chainReaderServer) GetLatestValue(ctx context.Context, request *pb.GetLatestValueRequest) (*pb.GetLatestValueReply, error) { | ||
var bc types.BoundContract | ||
bc.Name = request.Bc.Name[:] | ||
bc.Address = request.Bc.Address[:] | ||
bc.Pending = request.Bc.Pending | ||
|
||
params := &map[string]any{} | ||
|
||
if err := decodeVersionedBytes(params, request.Params); err != nil { | ||
return nil, err | ||
} | ||
|
||
retVal := &map[string]any{} | ||
err := c.impl.GetLatestValue(ctx, bc, request.Method, params, retVal) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
encodedRetVal, err := encodeVersionedBytes(retVal, CurrentEncodingVersion) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &pb.GetLatestValueReply{RetVal: encodedRetVal}, nil | ||
} |
Oops, something went wrong.