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-2654 chain reader evm poc get latest value impl #11176

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
d0c6faf
Implement skeleton interfaces, structs, & methods for ChainReader EVM…
reductionista Oct 18, 2023
4a3c12d
Update go.mod with overrides for chainlink-relay and 3 other relay repos
reductionista Oct 18, 2023
a86bfa6
Read ChainReader config in from RelayConfig
reductionista Oct 19, 2023
ddbce91
Use medianProviderWrapper instead of passing medianContract separately
reductionista Oct 20, 2023
c27fe5a
Add chain_reader_test.go stub for relay tests
reductionista Oct 20, 2023
048a1c8
Some minor PR suggestions
reductionista Oct 27, 2023
a54fa2c
Return error messages from newChainReader instead of nil on failure
reductionista Oct 27, 2023
bb35f0a
err.Error() -> err
reductionista Oct 30, 2023
d083ed1
Update cosmos
reductionista Oct 31, 2023
74d3eec
Update chainlink-relay
reductionista Oct 31, 2023
75fe20b
Update relay
reductionista Oct 31, 2023
9ed795f
Update .tool-versions golang 1.21.1 -> 1.21.3
reductionista Oct 31, 2023
7127fa9
Update relay
reductionista Oct 31, 2023
8cdbf9f
Fix "unimplemented method" bug
reductionista Oct 31, 2023
3c27c61
Add chain reader config validation
ilija42 Oct 31, 2023
1a1c799
Add chain reader config validation tests
ilija42 Oct 31, 2023
3871029
minor fix in chain_reader_test.go
ilija42 Oct 31, 2023
12c9904
Fix chainReader = nil bug
reductionista Nov 1, 2023
27464f1
Restore medianContract to evm relay
reductionista Nov 1, 2023
cfefb45
Fix lint errors, re-run go mod tidy
reductionista Nov 2, 2023
49ffeae
Add config for chain reader median contract to cr validation testcases
ilija42 Nov 4, 2023
40d5d6e
Add config to chain reader struct and change its constructor visibility
ilija42 Nov 6, 2023
c9ef1d0
Add parsed ABI to ChainContractReader (chain reader cfg)
ilija42 Nov 6, 2023
4f34d56
Add basic chain reader GetLatest implementation
ilija42 Nov 6, 2023
f528221
minor fix to chain reader test
ilija42 Nov 6, 2023
fbf66f9
Add new method to JSONConfig that properly handles toml json strings
ilija42 Nov 7, 2023
3d49728
Add tests for JSONConfig BytesWithPreservedJson method
ilija42 Nov 7, 2023
eaa9da0
USe JSONConfig BytesWithPreservedJson method for RelayConfig
ilija42 Nov 7, 2023
b6cc7c9
Update ChainContractReader ParsedContractABI json tag to -
ilija42 Nov 7, 2023
78c68b6
unexport validateChainReaderConfig
ilija42 Nov 7, 2023
36c805f
Implement skeleton interfaces, structs, & methods for ChainReader EVM…
reductionista Oct 18, 2023
6d05b9e
Update go.mod with overrides for chainlink-relay and 3 other relay repos
reductionista Nov 7, 2023
2c62c23
Read ChainReader config in from RelayConfig
reductionista Oct 19, 2023
44fa150
Use medianProviderWrapper instead of passing medianContract separately
reductionista Oct 20, 2023
8676c2a
Add chain_reader_test.go stub for relay tests
reductionista Oct 20, 2023
55831b0
Some minor PR suggestions
reductionista Oct 27, 2023
fa97218
Return error messages from newChainReader instead of nil on failure
reductionista Oct 27, 2023
7523578
err.Error() -> err
reductionista Oct 30, 2023
31b0e78
Update cosmos
reductionista Oct 31, 2023
3e1a4ee
Fix "unimplemented method" bug
reductionista Oct 31, 2023
2b6e222
Add chain reader config validation
ilija42 Oct 31, 2023
97f5971
Add chain reader config validation tests
ilija42 Oct 31, 2023
218634a
minor fix in chain_reader_test.go
ilija42 Oct 31, 2023
3b1122d
Fix chainReader = nil bug
reductionista Nov 1, 2023
83da844
Restore medianContract to evm relay
reductionista Nov 1, 2023
513be4f
Fix lint errors, re-run go mod tidy
reductionista Nov 2, 2023
790a5d9
Add config for chain reader median contract to cr validation testcases
ilija42 Nov 4, 2023
cd65698
Add unimplemented Encode(), Decode(), GetMaxEncodingSize(), GetMaxDec…
reductionista Nov 8, 2023
2ab8a42
Update relay refs
reductionista Nov 8, 2023
3e0c16d
goimports -local github.com/smartcontractkit/chainlink ./core/service…
reductionista Nov 8, 2023
808b824
Add ChainReader() method to mock provider for plugin test
reductionista Nov 8, 2023
bc4f33c
go mod tidy
reductionista Nov 8, 2023
b38d0f6
Implement chain reader get latest value for methods
ilija42 Nov 8, 2023
9384bd9
Commit unfinished events handling in chainreader GetLatestValue
ilija42 Nov 8, 2023
8ce9096
Merge remote-tracking branch 'origin/BCF-2612-ChainReader-EVM-POC' in…
ilija42 Nov 8, 2023
1e4af10
Merge remote-tracking branch 'origin/BCF-2612-ChainReader-EVM-POC' in…
ilija42 Nov 9, 2023
aee4d20
Fix chain reader getLatest Value response decoding
ilija42 Nov 13, 2023
4becd20
Initialise log poller filters for chain reader
ilija42 Nov 13, 2023
e6732e1
Add smoke test for ocrv2 basic test with chain reader
ilija42 Nov 13, 2023
08e098f
Fix BytesWithPreservedJson and add more tests for it
ilija42 Nov 13, 2023
ae1c8b5
fix integration-tests go sum
ilija42 Nov 13, 2023
b9f8cb2
Fix linter error in chain_reader_test.go
ilija42 Nov 13, 2023
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
28 changes: 28 additions & 0 deletions core/services/job/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,34 @@ func (r JSONConfig) Bytes() []byte {
return b
}

// BytesWithPreservedJson returns raw bytes and properly marshals any potential json structure strings.
func (r JSONConfig) BytesWithPreservedJson() []byte {
var retCopy = make(JSONConfig, 0)
for key, value := range r {
copiedVal := value
// If the value is a json structure string, unmarshal it to preserve JSON structure
// e.g. instead of this {"key":"{\"nestedKey\":{\"nestedValue\":123}}"}
// we want this {"key":{"nestedKey":{"nestedValue":123}}},
if strValue, ok := copiedVal.(string); ok {
if isValidJSONStruct(strValue) {
var parsedValue interface{}
if err := json.Unmarshal([]byte(strValue), &parsedValue); err == nil {
copiedVal = parsedValue
}
}
}
retCopy[key] = copiedVal
}

b, _ := json.Marshal(retCopy)
return b
}

func isValidJSONStruct(s string) bool {
var js map[string]interface{}
return json.Unmarshal([]byte(s), &js) == nil
}

// Value returns this instance serialized for database storage.
func (r JSONConfig) Value() (driver.Value, error) {
return json.Marshal(r)
Expand Down
66 changes: 66 additions & 0 deletions core/services/job/models_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,69 @@ func TestOCR2OracleSpec_RelayIdentifier(t *testing.T) {
})
}
}

func TestJSONConfig_BytesWithPreservedJson(t *testing.T) {
type testCases struct {
name string
Input JSONConfig
Expected []byte
}
tests := []testCases{
{
name: "json",
Input: JSONConfig{
"key": "{\"nestedKey\": {\"nestedValue\":123}}",
},
// regular Bytes marshals to this: {"key":"{\"nestedKey\": {\"nestedValue\":123}}"}
Expected: []byte(`{"key":{"nestedKey":{"nestedValue":123}}}`),
},
{
name: "broken json gets treated as a regular string",
Input: JSONConfig{
"key": "2324{\"nes4tedKey\":\"nestedValue\"}",
},
Expected: []byte(`{"key":"2324{\"nes4tedKey\":\"nestedValue\"}"}`),
},
{
name: "number",
Input: JSONConfig{
"key": 1,
},
Expected: []byte(`{"key":1}`),
},
{
name: "string",
Input: JSONConfig{
"key": "abc",
},
Expected: []byte(`{"key":"abc"}`),
},
{
name: "string number stays string number",
Input: JSONConfig{
"key1": "1",
},
Expected: []byte(`{"key1":"1"}`),
},
{
name: "all together",
Input: JSONConfig{
"key1": "{\"nestedKey\": {\"nestedValue\":123}}",
"key2": "2324{\"key\":\"value\"}",
"key3": 1,
"key4": "abc",
},
Expected: []byte(`{"key1":{"nestedKey":{"nestedValue":123}},"key2":"2324{\"key\":\"value\"}","key3":1,"key4":"abc"}`),
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
result := tc.Input.BytesWithPreservedJson()
if !reflect.DeepEqual(result, tc.Expected) {
t.Errorf("Input: %v, BytesWithPreservedJson() returned unexpected result. Expected: %s, Got: %s", tc.Input, tc.Expected, result)
}
})

}
}
14 changes: 7 additions & 7 deletions core/services/ocr2/delegate.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ func (d *Delegate) cleanupEVM(jb job.Job, q pg.Queryer, relayID relay.ID) error
JobID: jb.ID,
ContractID: spec.ContractID,
New: false,
RelayConfig: spec.RelayConfig.Bytes(),
RelayConfig: spec.RelayConfig.BytesWithPreservedJson(),
}

relayFilters, err := evmrelay.FilterNamesFromRelayArgs(rargs)
Expand Down Expand Up @@ -552,7 +552,7 @@ func (d *Delegate) newServicesGenericPlugin(
JobID: spec.ID,
ContractID: spec.ContractID,
New: d.isNewlyCreatedJob,
RelayConfig: spec.RelayConfig.Bytes(),
RelayConfig: spec.RelayConfig.BytesWithPreservedJson(),
ProviderType: cconf.ProviderType,
}, types.PluginArgs{
TransmitterID: spec.TransmitterID.String,
Expand Down Expand Up @@ -664,7 +664,7 @@ func (d *Delegate) newServicesMercury(
JobID: jb.ID,
ContractID: spec.ContractID,
New: d.isNewlyCreatedJob,
RelayConfig: spec.RelayConfig.Bytes(),
RelayConfig: spec.RelayConfig.BytesWithPreservedJson(),
ProviderType: string(spec.PluginType),
}, types.PluginArgs{
TransmitterID: transmitterID,
Expand Down Expand Up @@ -785,7 +785,7 @@ func (d *Delegate) newServicesDKG(
JobID: jb.ID,
ContractID: spec.ContractID,
New: d.isNewlyCreatedJob,
RelayConfig: spec.RelayConfig.Bytes(),
RelayConfig: spec.RelayConfig.BytesWithPreservedJson(),
}, types.PluginArgs{
TransmitterID: spec.TransmitterID.String,
PluginConfig: spec.PluginConfig.Bytes(),
Expand Down Expand Up @@ -870,7 +870,7 @@ func (d *Delegate) newServicesOCR2VRF(
JobID: jb.ID,
ContractID: spec.ContractID,
New: d.isNewlyCreatedJob,
RelayConfig: spec.RelayConfig.Bytes(),
RelayConfig: spec.RelayConfig.BytesWithPreservedJson(),
}, types.PluginArgs{
TransmitterID: transmitterID,
PluginConfig: spec.PluginConfig.Bytes(),
Expand All @@ -884,7 +884,7 @@ func (d *Delegate) newServicesOCR2VRF(
ExternalJobID: jb.ExternalJobID,
JobID: jb.ID,
ContractID: cfg.DKGContractAddress,
RelayConfig: spec.RelayConfig.Bytes(),
RelayConfig: spec.RelayConfig.BytesWithPreservedJson(),
}, types.PluginArgs{
TransmitterID: transmitterID,
PluginConfig: spec.PluginConfig.Bytes(),
Expand Down Expand Up @@ -1327,7 +1327,7 @@ func (d *Delegate) newServicesOCR2Functions(
ExternalJobID: jb.ExternalJobID,
JobID: jb.ID,
ContractID: spec.ContractID,
RelayConfig: spec.RelayConfig.Bytes(),
RelayConfig: spec.RelayConfig.BytesWithPreservedJson(),
New: d.isNewlyCreatedJob,
},
types.PluginArgs{
Expand Down
27 changes: 14 additions & 13 deletions core/services/ocr2/plugins/median/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import (
"github.com/smartcontractkit/chainlink/v2/plugins"
)

const ContractName = "offchain_aggregator"

type MedianConfig interface {
JobPipelineMaxSuccessfulRuns() uint64
plugins.RegistrarConfig
Expand Down Expand Up @@ -92,7 +94,7 @@ func NewMedianServices(ctx context.Context,
JobID: jb.ID,
ContractID: spec.ContractID,
New: isNewlyCreatedJob,
RelayConfig: spec.RelayConfig.Bytes(),
RelayConfig: spec.RelayConfig.BytesWithPreservedJson(),
ProviderType: string(spec.PluginType),
}, types.PluginArgs{
TransmitterID: spec.TransmitterID.String,
Expand Down Expand Up @@ -185,17 +187,17 @@ type medianContract struct {
}

type latestTransmissionDetailsResponse struct {
configDigest ocr2types.ConfigDigest
epoch uint32
round uint8
latestAnswer *big.Int
latestTimestamp time.Time
ConfigDigest ocr2types.ConfigDigest
Epoch uint32
Round uint8
LatestAnswer *big.Int
LatestTimestamp uint64
}

type latestRoundRequested struct {
configDigest ocr2types.ConfigDigest
epoch uint32
round uint8
ConfigDigest ocr2types.ConfigDigest
Epoch uint32
Round uint8
}

func (m *medianContract) LatestTransmissionDetails(ctx context.Context) (configDigest ocr2types.ConfigDigest, epoch uint32, round uint8, latestAnswer *big.Int, latestTimestamp time.Time, err error) {
Expand All @@ -205,8 +207,7 @@ func (m *medianContract) LatestTransmissionDetails(ctx context.Context) (configD
if err != nil {
return
}

return resp.configDigest, resp.epoch, resp.round, resp.latestAnswer, resp.latestTimestamp, err
return resp.ConfigDigest, resp.Epoch, resp.Round, resp.LatestAnswer, time.Unix(int64(resp.LatestTimestamp), 0), err
}

func (m *medianContract) LatestRoundRequested(ctx context.Context, lookback time.Duration) (configDigest ocr2types.ConfigDigest, epoch uint32, round uint8, err error) {
Expand All @@ -217,10 +218,10 @@ func (m *medianContract) LatestRoundRequested(ctx context.Context, lookback time
return
}

return resp.configDigest, resp.epoch, resp.round, err
return resp.ConfigDigest, resp.Epoch, resp.Round, err
}

func newMedianContract(chainReader types.ChainReader, address common.Address) *medianContract {
contract := types.BoundContract{Address: address.String(), Name: "median", Pending: true}
contract := types.BoundContract{Address: address.String(), Name: ContractName, Pending: true}
return &medianContract{chainReader, contract}
}
2 changes: 1 addition & 1 deletion core/services/ocr2/plugins/ocr2keeper/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func EVMProvider(db *sqlx.DB, chain evm.Chain, lggr logger.Logger, spec job.Job,
ExternalJobID: spec.ExternalJobID,
JobID: oSpec.ID,
ContractID: oSpec.ContractID,
RelayConfig: oSpec.RelayConfig.Bytes(),
RelayConfig: oSpec.RelayConfig.BytesWithPreservedJson(),
},
types.PluginArgs{
TransmitterID: oSpec.TransmitterID.String,
Expand Down
8 changes: 4 additions & 4 deletions core/services/ocrbootstrap/delegate.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) (services []job.ServiceCtx, err e
ctx := ctxVals.ContextWithValues(context.Background())

var routerFields relayConfigRouterContractFields
if err = json.Unmarshal(spec.RelayConfig.Bytes(), &routerFields); err != nil {
if err = json.Unmarshal(spec.RelayConfig.BytesWithPreservedJson(), &routerFields); err != nil {
return nil, err
}

Expand All @@ -124,12 +124,12 @@ func (d *Delegate) ServicesForSpec(jb job.Job) (services []job.ServiceCtx, err e
ExternalJobID: jb.ExternalJobID,
JobID: jb.ID,
ContractID: spec.ContractID,
RelayConfig: spec.RelayConfig.Bytes(),
RelayConfig: spec.RelayConfig.BytesWithPreservedJson(),
New: d.isNewlyCreatedJob,
ProviderType: string(types.Functions),
},
types.PluginArgs{
PluginConfig: spec.RelayConfig.Bytes(), // contains all necessary fields for config provider
PluginConfig: spec.RelayConfig.BytesWithPreservedJson(), // contains all necessary fields for config provider
},
)
} else {
Expand All @@ -138,7 +138,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) (services []job.ServiceCtx, err e
JobID: jb.ID,
ContractID: spec.ContractID,
New: d.isNewlyCreatedJob,
RelayConfig: spec.RelayConfig.Bytes(),
RelayConfig: spec.RelayConfig.BytesWithPreservedJson(),
})
}

Expand Down
Loading
Loading