From 18174edc1546ad5cb8f7a819efc77296b0c4cf17 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Sun, 10 Mar 2024 15:23:38 -0500 Subject: [PATCH] bump libocr; add context --- go.mod | 52 ++++++++++------ go.sum | 105 +++++++++++++++++++++------------ llo/json_report_codec.go | 3 +- llo/json_report_codec_test.go | 4 +- llo/plugin.go | 20 ++++--- llo/plugin_outcome_test.go | 21 ++++--- llo/plugin_reports.go | 40 ++++++++----- llo/plugin_reports_test.go | 48 +++++++++------ llo/plugin_test.go | 7 ++- mercury/onchain_config.go | 5 +- mercury/onchain_config_test.go | 8 ++- mercury/v1/mercury.go | 16 ++--- mercury/v1/mercury_test.go | 35 +++++------ mercury/v2/mercury.go | 16 ++--- mercury/v2/mercury_test.go | 35 +++++------ mercury/v3/mercury.go | 16 ++--- mercury/v3/mercury_test.go | 35 +++++------ mercury/v4/mercury.go | 23 ++++---- mercury/v4/mercury_test.go | 61 ++++++++++++------- 19 files changed, 327 insertions(+), 223 deletions(-) diff --git a/go.mod b/go.mod index e30a106..661b221 100644 --- a/go.mod +++ b/go.mod @@ -1,16 +1,16 @@ module github.com/smartcontractkit/chainlink-data-streams -go 1.22 +go 1.22.0 toolchain go1.22.5 require ( github.com/hashicorp/go-plugin v1.6.2-0.20240829161738-06afb6d7ae99 github.com/shopspring/decimal v1.4.0 - github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 - github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c + github.com/smartcontractkit/chainlink-common v0.3.0 + github.com/smartcontractkit/libocr v0.0.0-20241007185508-adbe57025f12 github.com/stretchr/testify v1.9.0 - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa + golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 google.golang.org/protobuf v1.34.2 ) @@ -21,11 +21,15 @@ require ( github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/fatih/color v1.16.0 // indirect - github.com/fxamacker/cbor/v2 v2.5.0 // indirect + github.com/fatih/color v1.17.0 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/go-json-experiment/json v0.0.0-20231102232822-2e55bd4e08b0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.22.0 // indirect github.com/go-viper/mapstructure/v2 v2.1.0 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/go-cmp v0.6.0 // indirect @@ -37,37 +41,47 @@ require ( github.com/hashicorp/yamux v0.1.1 // indirect github.com/invopop/jsonschema v0.12.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect + github.com/klauspost/compress v1.17.9 // indirect + github.com/leodido/go-urn v1.4.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mr-tron/base58 v1.2.0 // indirect - github.com/oklog/run v1.0.0 // indirect - github.com/pelletier/go-toml/v2 v2.2.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/oklog/run v1.1.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.17.0 // indirect - github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect - github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.11.1 // indirect - github.com/santhosh-tekuri/jsonschema/v5 v5.2.0 // indirect + github.com/prometheus/client_golang v1.20.0 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/procfs v0.15.1 // indirect + github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/x448/float16 v0.8.4 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240823153156-2a54df7bffb9 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 // indirect + go.opentelemetry.io/otel/log v0.4.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/sdk v1.28.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.4.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.26.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/crypto v0.27.0 // indirect + golang.org/x/net v0.29.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.18.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect google.golang.org/grpc v1.65.0 // indirect diff --git a/go.sum b/go.sum index 75a792e..6bdf393 100644 --- a/go.sum +++ b/go.sum @@ -24,10 +24,12 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADivE= -github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/go-json-experiment/json v0.0.0-20231102232822-2e55bd4e08b0 h1:ymLjT4f35nQbASLnvxEde4XOBL+Sn7rFuV+FOJqkljg= github.com/go-json-experiment/json v0.0.0-20231102232822-2e55bd4e08b0/go.mod h1:6daplAwHHGbUGib4990V3Il26O0OC4aRyvewaaAihaA= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -35,6 +37,14 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= +github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-viper/mapstructure/v2 v2.1.0 h1:gHnMa2Y/pIxElCH2GlZZ1lZSsn6XMtufpGyP1XxdC/w= github.com/go-viper/mapstructure/v2 v2.1.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -86,10 +96,16 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -101,40 +117,40 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo= -github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= +github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= -github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= +github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI= +github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 h1:v7DLqVdK4VrYkVD5diGdl4sxJurKJEMnODWRJlxV9oM= -github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= -github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= -github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= +github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/santhosh-tekuri/jsonschema/v5 v5.2.0 h1:WCcC4vZDS1tYNxjWlwRJZQy28r8CMoggKnxNzxsVDMQ= -github.com/santhosh-tekuri/jsonschema/v5 v5.2.0/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0= +github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= +github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3 h1:fkfOoAPviqO2rN8ngvejsDa7WKcw4paGEFA4/Znu0L0= -github.com/smartcontractkit/chainlink-common v0.2.2-0.20240903184200-6488292a85e3/go.mod h1:D/qaCoq0SxXzg5NRN5FtBRv98VBf+D2NOC++RbvvuOc= +github.com/smartcontractkit/chainlink-common v0.3.0 h1:mUXHBzzw2qPKyw6gPAC8JhO+ryT8maY+rBi9NFtqEy0= +github.com/smartcontractkit/chainlink-common v0.3.0/go.mod h1:tsGgeEJc5SUSlfVGSX0wR0EkRU3pM58D6SKF97V68ko= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7/go.mod h1:FX7/bVdoep147QQhsOPkYsPEXhGZjeYx6lBSaSXtZOA= -github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c h1:lIyMbTaF2H0Q71vkwZHX/Ew4KF2BxiKhqEXwF8rn+KI= -github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= +github.com/smartcontractkit/libocr v0.0.0-20241007185508-adbe57025f12 h1:NzZGjaqez21I3DU7objl3xExTH4fxYvzTqar8DC6360= +github.com/smartcontractkit/libocr v0.0.0-20241007185508-adbe57025f12/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -153,18 +169,34 @@ github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+x github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 h1:vS1Ao/R55RNV4O7TA2Qopok8yN+X0LIP6RVWLFkprck= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0/go.mod h1:BMsdeOxN04K0L5FNUBfjFdvwWGNe/rkmSwH4Aelu/X0= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240823153156-2a54df7bffb9 h1:UiRNKd1OgqsLbFwE+wkAWTdiAxXtCBqKIHeBIse4FUA= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240823153156-2a54df7bffb9/go.mod h1:eqZlW3pJWhjyexnDPrdQxix1pn0wwhI4AO4GKpP/bMI= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 h1:U2guen0GhqH8o/G2un8f/aG/y++OuW6MyCo6hT9prXk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0/go.mod h1:yeGZANgEcpdx/WK0IvvRFC+2oLiMS2u4L/0Rj2M2Qr0= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0 h1:0MH3f8lZrflbUWXVxyBg/zviDFdGE062uKh5+fu8Vv0= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0/go.mod h1:Vh68vYiHY5mPdekTr0ox0sALsqjoVy0w3Os278yX5SQ= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0 h1:BJee2iLkfRfl9lc7aFmBwkWxY/RI1RDdXepSF6y8TPE= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0/go.mod h1:DIzlHs3DRscCIBU3Y9YSzPfScwnYnzfnCd4g8zA7bZc= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 h1:EVSnY9JbEEW92bEkIYOVMw4q1WJxIAGoFTrtYOzWuRQ= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0/go.mod h1:Ea1N1QQryNXpCD0I1fdLibBAIpQuBkznMmkdKrapk1Y= +go.opentelemetry.io/otel/log v0.4.0 h1:/vZ+3Utqh18e8TPjuc3ecg284078KWrR8BRz+PQAj3o= +go.opentelemetry.io/otel/log v0.4.0/go.mod h1:DhGnQvky7pHy82MIRV43iXh3FlKN8UUKftn0KbLOq6I= go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/sdk/log v0.4.0 h1:1mMI22L82zLqf6KtkjrRy5BbagOTWdJsqMY/HSqILAA= +go.opentelemetry.io/otel/sdk/log v0.4.0/go.mod h1:AYJ9FVF0hNOgAVzUG/ybg/QttnXhUePWAupmCqtdESo= +go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= +go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -178,11 +210,11 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -198,12 +230,11 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -226,15 +257,15 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= diff --git a/llo/json_report_codec.go b/llo/json_report_codec.go index 7b59347..ff621a3 100644 --- a/llo/json_report_codec.go +++ b/llo/json_report_codec.go @@ -1,6 +1,7 @@ package llo import ( + "context" "encoding/hex" "encoding/json" "fmt" @@ -43,7 +44,7 @@ func UnmarshalJSONStreamValue(enc *JSONStreamValue) (StreamValue, error) { type JSONReportCodec struct{} -func (cdc JSONReportCodec) Encode(r Report, _ llotypes.ChannelDefinition) ([]byte, error) { +func (cdc JSONReportCodec) Encode(ctx context.Context, r Report, _ llotypes.ChannelDefinition) ([]byte, error) { type encode struct { ConfigDigest types.ConfigDigest SeqNr uint64 diff --git a/llo/json_report_codec_test.go b/llo/json_report_codec_test.go index 9f42a5e..a4e06c7 100644 --- a/llo/json_report_codec_test.go +++ b/llo/json_report_codec_test.go @@ -9,6 +9,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/types/llo" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -16,6 +17,7 @@ import ( func Test_JSONCodec(t *testing.T) { t.Run("Encode=>Decode", func(t *testing.T) { + ctx := tests.Context(t) r := Report{ ConfigDigest: types.ConfigDigest([32]byte{1, 2, 3}), SeqNr: 43, @@ -28,7 +30,7 @@ func Test_JSONCodec(t *testing.T) { cdc := JSONReportCodec{} - encoded, err := cdc.Encode(r, llo.ChannelDefinition{}) + encoded, err := cdc.Encode(ctx, r, llo.ChannelDefinition{}) require.NoError(t, err) fmt.Println("encoded", string(encoded)) diff --git a/llo/plugin.go b/llo/plugin.go index 19449ad..b38c590 100644 --- a/llo/plugin.go +++ b/llo/plugin.go @@ -4,6 +4,8 @@ import ( "context" "fmt" + "github.com/smartcontractkit/libocr/quorumhelper" + "github.com/smartcontractkit/chainlink-common/pkg/logger" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" @@ -194,7 +196,7 @@ type PluginFactory struct { Codecs map[llotypes.ReportFormat]ReportCodec } -func (f *PluginFactory) NewReportingPlugin(cfg ocr3types.ReportingPluginConfig) (ocr3types.ReportingPlugin[llotypes.ReportInfo], ocr3types.ReportingPluginInfo, error) { +func (f *PluginFactory) NewReportingPlugin(ctx context.Context, cfg ocr3types.ReportingPluginConfig) (ocr3types.ReportingPlugin[llotypes.ReportInfo], ocr3types.ReportingPluginInfo, error) { offchainCfg, err := DecodeOffchainConfig(cfg.OffchainConfig) if err != nil { return nil, ocr3types.ReportingPluginInfo{}, fmt.Errorf("NewReportingPlugin failed to decode offchain config; got: 0x%x (len: %d); %w", cfg.OffchainConfig, len(cfg.OffchainConfig), err) @@ -209,6 +211,7 @@ func (f *PluginFactory) NewReportingPlugin(cfg ocr3types.ReportingPluginConfig) f.ChannelDefinitionCache, f.DataSource, f.Logger, + cfg.N, cfg.F, protoObservationCodec{}, protoOutcomeCodec{}, @@ -231,7 +234,7 @@ type ReportCodec interface { // Encode may be lossy, so no Decode function is expected // Encode should handle nil stream aggregate values without panicking (it // may return error instead) - Encode(Report, llotypes.ChannelDefinition) ([]byte, error) + Encode(context.Context, Report, llotypes.ChannelDefinition) ([]byte, error) } type Plugin struct { @@ -243,6 +246,7 @@ type Plugin struct { ChannelDefinitionCache ChannelDefinitionCache DataSource DataSource Logger logger.Logger + N int F int ObservationCodec ObservationCodec OutcomeCodec OutcomeCodec @@ -287,7 +291,7 @@ func (p *Plugin) Observation(ctx context.Context, outctx ocr3types.OutcomeContex // *not* strictly) across the lifetime of a protocol instance and that // outctx.previousOutcome contains the consensus outcome with sequence // number (outctx.SeqNr-1). -func (p *Plugin) ValidateObservation(outctx ocr3types.OutcomeContext, query types.Query, ao types.AttributedObservation) error { +func (p *Plugin) ValidateObservation(ctx context.Context, outctx ocr3types.OutcomeContext, query types.Query, ao types.AttributedObservation) error { if outctx.SeqNr < 1 { return fmt.Errorf("Invalid SeqNr: %d", outctx.SeqNr) } else if outctx.SeqNr == 1 { @@ -340,7 +344,7 @@ func (p *Plugin) ValidateObservation(outctx ocr3types.OutcomeContext, query type // // libocr guarantees that this will always be called with at least 2f+1 // AttributedObservations -func (p *Plugin) Outcome(outctx ocr3types.OutcomeContext, query types.Query, aos []types.AttributedObservation) (ocr3types.Outcome, error) { +func (p *Plugin) Outcome(ctx context.Context, outctx ocr3types.OutcomeContext, query types.Query, aos []types.AttributedObservation) (ocr3types.Outcome, error) { return p.outcome(outctx, query, aos) } @@ -357,8 +361,8 @@ func (p *Plugin) Outcome(outctx ocr3types.OutcomeContext, query types.Query, aos // *not* strictly) across the lifetime of a protocol instance and that // outctx.previousOutcome contains the consensus outcome with sequence // number (outctx.SeqNr-1). -func (p *Plugin) Reports(seqNr uint64, rawOutcome ocr3types.Outcome) ([]ocr3types.ReportWithInfo[llotypes.ReportInfo], error) { - return p.reports(seqNr, rawOutcome) +func (p *Plugin) Reports(ctx context.Context, seqNr uint64, rawOutcome ocr3types.Outcome) ([]ocr3types.ReportPlus[llotypes.ReportInfo], error) { + return p.reports(ctx, seqNr, rawOutcome) } func (p *Plugin) ShouldAcceptAttestedReport(context.Context, uint64, ocr3types.ReportWithInfo[llotypes.ReportInfo]) (bool, error) { @@ -379,8 +383,8 @@ func (p *Plugin) ShouldTransmitAcceptedReport(context.Context, uint64, ocr3types // This is an advanced feature. The "default" approach (what OCR1 & OCR2 // did) is to have an empty ValidateObservation function and return // QuorumTwoFPlusOne from this function. -func (p *Plugin) ObservationQuorum(outctx ocr3types.OutcomeContext, query types.Query) (ocr3types.Quorum, error) { - return ocr3types.QuorumTwoFPlusOne, nil +func (p *Plugin) ObservationQuorum(ctx context.Context, outctx ocr3types.OutcomeContext, query types.Query, aos []types.AttributedObservation) (bool, error) { + return quorumhelper.ObservationCountReachesObservationQuorum(quorumhelper.QuorumTwoFPlusOne, p.N, p.F, aos), nil } func (p *Plugin) Close() error { diff --git a/llo/plugin_outcome_test.go b/llo/plugin_outcome_test.go index 609fc05..35d0b15 100644 --- a/llo/plugin_outcome_test.go +++ b/llo/plugin_outcome_test.go @@ -15,6 +15,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" ) func Test_Outcome(t *testing.T) { @@ -26,15 +27,17 @@ func Test_Outcome(t *testing.T) { } t.Run("if number of observers < 2f+1, errors", func(t *testing.T) { - _, err := p.Outcome(ocr3types.OutcomeContext{SeqNr: 1}, types.Query{}, []types.AttributedObservation{}) + ctx := tests.Context(t) + _, err := p.Outcome(ctx, ocr3types.OutcomeContext{SeqNr: 1}, types.Query{}, []types.AttributedObservation{}) assert.EqualError(t, err, "invariant violation: expected at least 2f+1 attributed observations, got 0 (f: 0)") p.F = 1 - _, err = p.Outcome(ocr3types.OutcomeContext{SeqNr: 1}, types.Query{}, []types.AttributedObservation{{}, {}}) + _, err = p.Outcome(ctx, ocr3types.OutcomeContext{SeqNr: 1}, types.Query{}, []types.AttributedObservation{{}, {}}) assert.EqualError(t, err, "invariant violation: expected at least 2f+1 attributed observations, got 2 (f: 1)") }) t.Run("if seqnr == 1, and has enough observers, emits initial outcome with 'production' LifeCycleStage", func(t *testing.T) { - outcome, err := p.Outcome(ocr3types.OutcomeContext{SeqNr: 1}, types.Query{}, []types.AttributedObservation{ + ctx := tests.Context(t) + outcome, err := p.Outcome(ctx, ocr3types.OutcomeContext{SeqNr: 1}, types.Query{}, []types.AttributedObservation{ { Observation: []byte{}, Observer: commontypes.OracleID(0), @@ -64,6 +67,7 @@ func Test_Outcome(t *testing.T) { t.Run("channel definitions", func(t *testing.T) { t.Run("adds a new channel definition if there are enough votes", func(t *testing.T) { + ctx := tests.Context(t) newCd := llotypes.ChannelDefinition{ ReportFormat: llotypes.ReportFormat(2), Streams: []llotypes.Stream{{StreamID: 1, Aggregator: llotypes.AggregatorMedian}, {StreamID: 2, Aggregator: llotypes.AggregatorMedian}, {StreamID: 3, Aggregator: llotypes.AggregatorMedian}}, @@ -82,7 +86,7 @@ func Test_Outcome(t *testing.T) { Observer: commontypes.OracleID(i), }) } - outcome, err := p.Outcome(ocr3types.OutcomeContext{SeqNr: 2}, types.Query{}, aos) + outcome, err := p.Outcome(ctx, ocr3types.OutcomeContext{SeqNr: 2}, types.Query{}, aos) require.NoError(t, err) decoded, err := p.OutcomeCodec.Decode(outcome) @@ -92,6 +96,7 @@ func Test_Outcome(t *testing.T) { }) t.Run("replaces an existing channel definition if there are enough votes", func(t *testing.T) { + ctx := tests.Context(t) newCd := llotypes.ChannelDefinition{ ReportFormat: llotypes.ReportFormat(2), Streams: []llotypes.Stream{{StreamID: 1, Aggregator: llotypes.AggregatorQuote}, {StreamID: 2, Aggregator: llotypes.AggregatorMedian}, {StreamID: 3, Aggregator: llotypes.AggregatorMedian}}, @@ -121,7 +126,7 @@ func Test_Outcome(t *testing.T) { }) require.NoError(t, err) - outcome, err := p.Outcome(ocr3types.OutcomeContext{PreviousOutcome: previousOutcome, SeqNr: 2}, types.Query{}, aos) + outcome, err := p.Outcome(ctx, ocr3types.OutcomeContext{PreviousOutcome: previousOutcome, SeqNr: 2}, types.Query{}, aos) require.NoError(t, err) decoded, err := p.OutcomeCodec.Decode(outcome) @@ -131,6 +136,7 @@ func Test_Outcome(t *testing.T) { }) t.Run("does not add channels beyond MaxOutcomeChannelDefinitionsLength", func(t *testing.T) { + ctx := tests.Context(t) newCd := llotypes.ChannelDefinition{ ReportFormat: llotypes.ReportFormat(2), Streams: []llotypes.Stream{{StreamID: 1, Aggregator: llotypes.AggregatorMedian}, {StreamID: 2, Aggregator: llotypes.AggregatorMedian}, {StreamID: 3, Aggregator: llotypes.AggregatorMedian}}, @@ -149,7 +155,7 @@ func Test_Outcome(t *testing.T) { Observer: commontypes.OracleID(i), }) } - outcome, err := p.Outcome(ocr3types.OutcomeContext{SeqNr: 2}, types.Query{}, aos) + outcome, err := p.Outcome(ctx, ocr3types.OutcomeContext{SeqNr: 2}, types.Query{}, aos) require.NoError(t, err) decoded, err := p.OutcomeCodec.Decode(outcome) @@ -180,6 +186,7 @@ func Test_Outcome(t *testing.T) { cdc := &mockChannelDefinitionCache{definitions: smallDefinitions} t.Run("aggregates values when all stream values are present from all observers", func(t *testing.T) { + ctx := tests.Context(t) previousOutcome := Outcome{ LifeCycleStage: llotypes.LifeCycleStage("test"), ObservationsTimestampNanoseconds: testStartTS.UnixNano(), @@ -207,7 +214,7 @@ func Test_Outcome(t *testing.T) { Observer: commontypes.OracleID(i), }) } - outcome, err := p.Outcome(outctx, types.Query{}, aos) + outcome, err := p.Outcome(ctx, outctx, types.Query{}, aos) require.NoError(t, err) decoded, err := p.OutcomeCodec.Decode(outcome) diff --git a/llo/plugin_reports.go b/llo/plugin_reports.go index 3f53536..bdc7e5f 100644 --- a/llo/plugin_reports.go +++ b/llo/plugin_reports.go @@ -1,6 +1,7 @@ package llo import ( + "context" "encoding/json" "fmt" @@ -10,7 +11,7 @@ import ( llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" ) -func (p *Plugin) reports(seqNr uint64, rawOutcome ocr3types.Outcome) ([]ocr3types.ReportWithInfo[llotypes.ReportInfo], error) { +func (p *Plugin) reports(ctx context.Context, seqNr uint64, rawOutcome ocr3types.Outcome) ([]ocr3types.ReportPlus[llotypes.ReportInfo], error) { if seqNr <= 1 { // no reports for initial round return nil, nil @@ -26,7 +27,7 @@ func (p *Plugin) reports(seqNr uint64, rawOutcome ocr3types.Outcome) ([]ocr3type return nil, fmt.Errorf("error getting observations timestamp: %w", err) } - rwis := []ocr3types.ReportWithInfo[llotypes.ReportInfo]{} + rwis := []ocr3types.ReportPlus[llotypes.ReportInfo]{} if outcome.LifeCycleStage == LifeCycleStageRetired { // if we're retired, emit special retirement report to transfer @@ -36,12 +37,14 @@ func (p *Plugin) reports(seqNr uint64, rawOutcome ocr3types.Outcome) ([]ocr3type outcome.ValidAfterSeconds, } - rwis = append(rwis, ocr3types.ReportWithInfo[llotypes.ReportInfo]{ - // TODO: Needs retirement report codec - Report: must(json.Marshal(retirementReport)), - Info: llotypes.ReportInfo{ - LifeCycleStage: outcome.LifeCycleStage, - ReportFormat: llotypes.ReportFormatJSON, + rwis = append(rwis, ocr3types.ReportPlus[llotypes.ReportInfo]{ + ReportWithInfo: ocr3types.ReportWithInfo[llotypes.ReportInfo]{ + // TODO: Needs retirement report codec + Report: must(json.Marshal(retirementReport)), + Info: llotypes.ReportInfo{ + LifeCycleStage: outcome.LifeCycleStage, + ReportFormat: llotypes.ReportFormatJSON, + }, }, }) } @@ -68,16 +71,21 @@ func (p *Plugin) reports(seqNr uint64, rawOutcome ocr3types.Outcome) ([]ocr3type outcome.LifeCycleStage != LifeCycleStageProduction, } - encoded, err := p.encodeReport(report, cd) + encoded, err := p.encodeReport(ctx, report, cd) if err != nil { + if ctx.Err() != nil { + return nil, context.Cause(ctx) + } p.Logger.Warnw("Error encoding report", "reportFormat", cd.ReportFormat, "err", err, "channelID", cid, "stage", "Report", "seqNr", seqNr) continue } - rwis = append(rwis, ocr3types.ReportWithInfo[llotypes.ReportInfo]{ - Report: encoded, - Info: llotypes.ReportInfo{ - LifeCycleStage: outcome.LifeCycleStage, - ReportFormat: cd.ReportFormat, + rwis = append(rwis, ocr3types.ReportPlus[llotypes.ReportInfo]{ + ReportWithInfo: ocr3types.ReportWithInfo[llotypes.ReportInfo]{ + Report: encoded, + Info: llotypes.ReportInfo{ + LifeCycleStage: outcome.LifeCycleStage, + ReportFormat: cd.ReportFormat, + }, }, }) } @@ -89,12 +97,12 @@ func (p *Plugin) reports(seqNr uint64, rawOutcome ocr3types.Outcome) ([]ocr3type return rwis, nil } -func (p *Plugin) encodeReport(r Report, cd llotypes.ChannelDefinition) (types.Report, error) { +func (p *Plugin) encodeReport(ctx context.Context, r Report, cd llotypes.ChannelDefinition) (types.Report, error) { codec, exists := p.Codecs[cd.ReportFormat] if !exists { return nil, fmt.Errorf("codec missing for ReportFormat=%q", cd.ReportFormat) } - return codec.Encode(r, cd) + return codec.Encode(ctx, r, cd) } type Report struct { diff --git a/llo/plugin_reports_test.go b/llo/plugin_reports_test.go index acb7f24..280a9d0 100644 --- a/llo/plugin_reports_test.go +++ b/llo/plugin_reports_test.go @@ -10,6 +10,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/types/llo" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -26,19 +27,22 @@ func Test_Reports(t *testing.T) { } t.Run("ignores seqnr=0", func(t *testing.T) { - rwi, err := p.Reports(0, ocr3types.Outcome{}) + ctx := tests.Context(t) + rwi, err := p.Reports(ctx, 0, ocr3types.Outcome{}) assert.NoError(t, err) assert.Nil(t, rwi) }) t.Run("does not return reports for initial round", func(t *testing.T) { - rwi, err := p.Reports(1, ocr3types.Outcome{}) + ctx := tests.Context(t) + rwi, err := p.Reports(ctx, 1, ocr3types.Outcome{}) assert.NoError(t, err) assert.Nil(t, rwi) }) t.Run("returns error if unmarshalling outcome fails", func(t *testing.T) { - rwi, err := p.Reports(2, []byte("invalid")) + ctx := tests.Context(t) + rwi, err := p.Reports(ctx, 2, []byte("invalid")) require.Error(t, err) assert.Contains(t, err.Error(), "failed to decode outcome: expected protobuf") assert.Nil(t, rwi) @@ -46,16 +50,17 @@ func Test_Reports(t *testing.T) { t.Run("emits 'retirement report' if lifecycle state is retired", func(t *testing.T) { t.Run("with null ValidAfterSeconds", func(t *testing.T) { + ctx := tests.Context(t) outcome := Outcome{ LifeCycleStage: LifeCycleStageRetired, } encoded, err := p.OutcomeCodec.Encode(outcome) require.NoError(t, err) - rwis, err := p.Reports(2, encoded) + rwis, err := p.Reports(ctx, 2, encoded) require.NoError(t, err) require.Len(t, rwis, 1) - assert.Equal(t, llo.ReportInfo{LifeCycleStage: LifeCycleStageRetired, ReportFormat: llotypes.ReportFormatJSON}, rwis[0].Info) - assert.Equal(t, "{\"ValidAfterSeconds\":null}", string(rwis[0].Report)) + assert.Equal(t, llo.ReportInfo{LifeCycleStage: LifeCycleStageRetired, ReportFormat: llotypes.ReportFormatJSON}, rwis[0].ReportWithInfo.Info) + assert.Equal(t, "{\"ValidAfterSeconds\":null}", string(rwis[0].ReportWithInfo.Report)) }) }) @@ -71,6 +76,7 @@ func Test_Reports(t *testing.T) { } t.Run("does not report if observations are not valid yet", func(t *testing.T) { + ctx := tests.Context(t) outcome := Outcome{ ObservationsTimestampNanoseconds: 0, ValidAfterSeconds: map[llotypes.ChannelID]uint32{ @@ -91,12 +97,13 @@ func Test_Reports(t *testing.T) { } encoded, err := p.OutcomeCodec.Encode(outcome) require.NoError(t, err) - rwis, err := p.Reports(2, encoded) + rwis, err := p.Reports(ctx, 2, encoded) require.NoError(t, err) require.Len(t, rwis, 0) }) t.Run("does not produce report if an aggregate is missing", func(t *testing.T) { + ctx := tests.Context(t) outcome := Outcome{ ObservationsTimestampNanoseconds: int64(200 * time.Second), ValidAfterSeconds: map[llotypes.ChannelID]uint32{ @@ -117,12 +124,13 @@ func Test_Reports(t *testing.T) { } encoded, err := p.OutcomeCodec.Encode(outcome) require.NoError(t, err) - rwis, err := p.Reports(2, encoded) + rwis, err := p.Reports(ctx, 2, encoded) require.NoError(t, err) require.Len(t, rwis, 0) }) t.Run("skips reports if codec is missing", func(t *testing.T) { + ctx := tests.Context(t) dfns := map[llotypes.ChannelID]llotypes.ChannelDefinition{ 1: { ReportFormat: llotypes.ReportFormatEVMPremiumLegacy, @@ -150,12 +158,13 @@ func Test_Reports(t *testing.T) { } encoded, err := p.OutcomeCodec.Encode(outcome) require.NoError(t, err) - rwis, err := p.Reports(2, encoded) + rwis, err := p.Reports(ctx, 2, encoded) require.NoError(t, err) require.Len(t, rwis, 0) }) t.Run("generates specimen report for non-production LifeCycleStage", func(t *testing.T) { + ctx := tests.Context(t) outcome := Outcome{ LifeCycleStage: LifeCycleStageStaging, ObservationsTimestampNanoseconds: int64(200 * time.Second), @@ -181,16 +190,17 @@ func Test_Reports(t *testing.T) { } encoded, err := p.OutcomeCodec.Encode(outcome) require.NoError(t, err) - rwis, err := p.Reports(2, encoded) + rwis, err := p.Reports(ctx, 2, encoded) require.NoError(t, err) require.Len(t, rwis, 2) - assert.Equal(t, `{"ConfigDigest":"0000000000000000000000000000000000000000000000000000000000000000","SeqNr":2,"ChannelID":1,"ValidAfterSeconds":100,"ObservationTimestampSeconds":200,"Values":[{"Type":0,"Value":"1.1"},{"Type":0,"Value":"2.2"},{"Type":1,"Value":"Q{Bid: 5.5, Benchmark: 4.4, Ask: 3.3}"}],"Specimen":true}`, string(rwis[0].Report)) - assert.Equal(t, llo.ReportInfo{LifeCycleStage: "staging", ReportFormat: llotypes.ReportFormatJSON}, rwis[0].Info) - assert.Equal(t, `{"ConfigDigest":"0000000000000000000000000000000000000000000000000000000000000000","SeqNr":2,"ChannelID":2,"ValidAfterSeconds":100,"ObservationTimestampSeconds":200,"Values":[{"Type":0,"Value":"1.1"},{"Type":0,"Value":"2.2"},{"Type":1,"Value":"Q{Bid: 8.8, Benchmark: 7.7, Ask: 6.6}"}],"Specimen":true}`, string(rwis[1].Report)) - assert.Equal(t, llo.ReportInfo{LifeCycleStage: "staging", ReportFormat: llotypes.ReportFormatJSON}, rwis[1].Info) + assert.Equal(t, `{"ConfigDigest":"0000000000000000000000000000000000000000000000000000000000000000","SeqNr":2,"ChannelID":1,"ValidAfterSeconds":100,"ObservationTimestampSeconds":200,"Values":[{"Type":0,"Value":"1.1"},{"Type":0,"Value":"2.2"},{"Type":1,"Value":"Q{Bid: 5.5, Benchmark: 4.4, Ask: 3.3}"}],"Specimen":true}`, string(rwis[0].ReportWithInfo.Report)) + assert.Equal(t, llo.ReportInfo{LifeCycleStage: "staging", ReportFormat: llotypes.ReportFormatJSON}, rwis[0].ReportWithInfo.Info) + assert.Equal(t, `{"ConfigDigest":"0000000000000000000000000000000000000000000000000000000000000000","SeqNr":2,"ChannelID":2,"ValidAfterSeconds":100,"ObservationTimestampSeconds":200,"Values":[{"Type":0,"Value":"1.1"},{"Type":0,"Value":"2.2"},{"Type":1,"Value":"Q{Bid: 8.8, Benchmark: 7.7, Ask: 6.6}"}],"Specimen":true}`, string(rwis[1].ReportWithInfo.Report)) + assert.Equal(t, llo.ReportInfo{LifeCycleStage: "staging", ReportFormat: llotypes.ReportFormatJSON}, rwis[1].ReportWithInfo.Info) }) t.Run("generates non-specimen reports for production", func(t *testing.T) { + ctx := tests.Context(t) outcome := Outcome{ LifeCycleStage: LifeCycleStageProduction, ObservationsTimestampNanoseconds: int64(200 * time.Second), @@ -216,12 +226,12 @@ func Test_Reports(t *testing.T) { } encoded, err := p.OutcomeCodec.Encode(outcome) require.NoError(t, err) - rwis, err := p.Reports(2, encoded) + rwis, err := p.Reports(ctx, 2, encoded) require.NoError(t, err) require.Len(t, rwis, 2) - assert.Equal(t, `{"ConfigDigest":"0000000000000000000000000000000000000000000000000000000000000000","SeqNr":2,"ChannelID":1,"ValidAfterSeconds":100,"ObservationTimestampSeconds":200,"Values":[{"Type":0,"Value":"1.1"},{"Type":0,"Value":"2.2"},{"Type":1,"Value":"Q{Bid: 5.5, Benchmark: 4.4, Ask: 3.3}"}],"Specimen":false}`, string(rwis[0].Report)) - assert.Equal(t, llo.ReportInfo{LifeCycleStage: "production", ReportFormat: llotypes.ReportFormatJSON}, rwis[0].Info) - assert.Equal(t, `{"ConfigDigest":"0000000000000000000000000000000000000000000000000000000000000000","SeqNr":2,"ChannelID":2,"ValidAfterSeconds":100,"ObservationTimestampSeconds":200,"Values":[{"Type":0,"Value":"1.1"},{"Type":0,"Value":"2.2"},{"Type":1,"Value":"Q{Bid: 8.8, Benchmark: 7.7, Ask: 6.6}"}],"Specimen":false}`, string(rwis[1].Report)) - assert.Equal(t, llo.ReportInfo{LifeCycleStage: "production", ReportFormat: llotypes.ReportFormatJSON}, rwis[1].Info) + assert.Equal(t, `{"ConfigDigest":"0000000000000000000000000000000000000000000000000000000000000000","SeqNr":2,"ChannelID":1,"ValidAfterSeconds":100,"ObservationTimestampSeconds":200,"Values":[{"Type":0,"Value":"1.1"},{"Type":0,"Value":"2.2"},{"Type":1,"Value":"Q{Bid: 5.5, Benchmark: 4.4, Ask: 3.3}"}],"Specimen":false}`, string(rwis[0].ReportWithInfo.Report)) + assert.Equal(t, llo.ReportInfo{LifeCycleStage: "production", ReportFormat: llotypes.ReportFormatJSON}, rwis[0].ReportWithInfo.Info) + assert.Equal(t, `{"ConfigDigest":"0000000000000000000000000000000000000000000000000000000000000000","SeqNr":2,"ChannelID":2,"ValidAfterSeconds":100,"ObservationTimestampSeconds":200,"Values":[{"Type":0,"Value":"1.1"},{"Type":0,"Value":"2.2"},{"Type":1,"Value":"Q{Bid: 8.8, Benchmark: 7.7, Ask: 6.6}"}],"Specimen":false}`, string(rwis[1].ReportWithInfo.Report)) + assert.Equal(t, llo.ReportInfo{LifeCycleStage: "production", ReportFormat: llotypes.ReportFormatJSON}, rwis[1].ReportWithInfo.Info) }) } diff --git a/llo/plugin_test.go b/llo/plugin_test.go index ed5415a..efe552b 100644 --- a/llo/plugin_test.go +++ b/llo/plugin_test.go @@ -8,6 +8,7 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/stretchr/testify/assert" ) @@ -47,11 +48,13 @@ func Test_ValidateObservation(t *testing.T) { } t.Run("SeqNr < 1 is not valid", func(t *testing.T) { - err := p.ValidateObservation(ocr3types.OutcomeContext{}, types.Query{}, types.AttributedObservation{}) + ctx := tests.Context(t) + err := p.ValidateObservation(ctx, ocr3types.OutcomeContext{}, types.Query{}, types.AttributedObservation{}) assert.EqualError(t, err, "Invalid SeqNr: 0") }) t.Run("SeqNr == 1 enforces empty observation", func(t *testing.T) { - err := p.ValidateObservation(ocr3types.OutcomeContext{SeqNr: 1}, types.Query{}, types.AttributedObservation{Observation: []byte{1}}) + ctx := tests.Context(t) + err := p.ValidateObservation(ctx, ocr3types.OutcomeContext{SeqNr: 1}, types.Query{}, types.AttributedObservation{Observation: []byte{1}}) assert.EqualError(t, err, "Expected empty observation for first round, got: 0x01") }) } diff --git a/mercury/onchain_config.go b/mercury/onchain_config.go index 6632b5d..d52ff5a 100644 --- a/mercury/onchain_config.go +++ b/mercury/onchain_config.go @@ -1,6 +1,7 @@ package mercury import ( + "context" "fmt" "math/big" @@ -26,7 +27,7 @@ var _ mercury.OnchainConfigCodec = StandardOnchainConfigCodec{} // returned by EncodeValueInt192. type StandardOnchainConfigCodec struct{} -func (StandardOnchainConfigCodec) Decode(b []byte) (mercury.OnchainConfig, error) { +func (StandardOnchainConfigCodec) Decode(ctx context.Context, b []byte) (mercury.OnchainConfig, error) { if len(b) != onchainConfigEncodedLength { return mercury.OnchainConfig{}, fmt.Errorf("unexpected length of OnchainConfig, expected %v, got %v", onchainConfigEncodedLength, len(b)) } @@ -55,7 +56,7 @@ func (StandardOnchainConfigCodec) Decode(b []byte) (mercury.OnchainConfig, error return mercury.OnchainConfig{Min: min, Max: max}, nil } -func (StandardOnchainConfigCodec) Encode(c mercury.OnchainConfig) ([]byte, error) { +func (StandardOnchainConfigCodec) Encode(ctx context.Context, c mercury.OnchainConfig) ([]byte, error) { verBytes, err := bigbigendian.SerializeSigned(32, onchainConfigVersionBig) if err != nil { return nil, err diff --git a/mercury/onchain_config_test.go b/mercury/onchain_config_test.go index bee9f9e..6f11cc0 100644 --- a/mercury/onchain_config_test.go +++ b/mercury/onchain_config_test.go @@ -6,10 +6,11 @@ import ( "testing" "github.com/smartcontractkit/chainlink-common/pkg/types/mercury" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" ) func FuzzDecodeOnchainConfig(f *testing.F) { - valid, err := StandardOnchainConfigCodec{}.Encode(mercury.OnchainConfig{Min: big.NewInt(1), Max: big.NewInt(1000)}) + valid, err := StandardOnchainConfigCodec{}.Encode(tests.Context(f), mercury.OnchainConfig{Min: big.NewInt(1), Max: big.NewInt(1000)}) if err != nil { f.Fatalf("failed to construct valid OnchainConfig: %s", err) } @@ -17,12 +18,13 @@ func FuzzDecodeOnchainConfig(f *testing.F) { f.Add([]byte{}) f.Add(valid) f.Fuzz(func(t *testing.T, encoded []byte) { - decoded, err := StandardOnchainConfigCodec{}.Decode(encoded) + ctx := tests.Context(t) + decoded, err := StandardOnchainConfigCodec{}.Decode(ctx, encoded) if err != nil { return } - encoded2, err := StandardOnchainConfigCodec{}.Encode(decoded) + encoded2, err := StandardOnchainConfigCodec{}.Encode(ctx, decoded) if err != nil { t.Fatalf("failed to re-encode decoded input: %s", err) } diff --git a/mercury/v1/mercury.go b/mercury/v1/mercury.go index c0d257a..433869c 100644 --- a/mercury/v1/mercury.go +++ b/mercury/v1/mercury.go @@ -77,18 +77,18 @@ func NewFactory(ds DataSource, lggr logger.Logger, occ mercurytypes.OnchainConfi return Factory{ds, lggr, occ, rc} } -func (fac Factory) NewMercuryPlugin(configuration ocr3types.MercuryPluginConfig) (ocr3types.MercuryPlugin, ocr3types.MercuryPluginInfo, error) { +func (fac Factory) NewMercuryPlugin(ctx context.Context, configuration ocr3types.MercuryPluginConfig) (ocr3types.MercuryPlugin, ocr3types.MercuryPluginInfo, error) { offchainConfig, err := mercury.DecodeOffchainConfig(configuration.OffchainConfig) if err != nil { return nil, ocr3types.MercuryPluginInfo{}, err } - onchainConfig, err := fac.onchainConfigCodec.Decode(configuration.OnchainConfig) + onchainConfig, err := fac.onchainConfigCodec.Decode(ctx, configuration.OnchainConfig) if err != nil { return nil, ocr3types.MercuryPluginInfo{}, err } - maxReportLength, err := fac.reportCodec.MaxReportLength(configuration.N) + maxReportLength, err := fac.reportCodec.MaxReportLength(ctx, configuration.N) if err != nil { return nil, ocr3types.MercuryPluginInfo{}, err } @@ -327,7 +327,7 @@ func parseAttributedObservations(lggr logger.Logger, aos []types.AttributedObser return paos } -func (rp *reportingPlugin) Report(repts types.ReportTimestamp, previousReport types.Report, aos []types.AttributedObservation) (shouldReport bool, report types.Report, err error) { +func (rp *reportingPlugin) Report(ctx context.Context, repts types.ReportTimestamp, previousReport types.Report, aos []types.AttributedObservation) (shouldReport bool, report types.Report, err error) { paos := parseAttributedObservations(rp.logger, aos) if len(paos) == 0 { @@ -339,7 +339,7 @@ func (rp *reportingPlugin) Report(repts types.ReportTimestamp, previousReport ty return false, nil, fmt.Errorf("only received %v valid attributed observations, but need at least f+1 (%v)", len(paos), rp.f+1) } - rf, err := rp.buildReportFields(previousReport, paos) + rf, err := rp.buildReportFields(ctx, previousReport, paos) if err != nil { rp.logger.Errorw("failed to build report fields", "paos", paos, "f", rp.f, "reportFields", rf, "repts", repts, "err", err) return false, nil, err @@ -358,7 +358,7 @@ func (rp *reportingPlugin) Report(repts types.ReportTimestamp, previousReport ty "timestamp", repts, ) - report, err = rp.reportCodec.BuildReport(rf) + report, err = rp.reportCodec.BuildReport(ctx, rf) if err != nil { rp.logger.Debugw("failed to BuildReport", "paos", paos, "f", rp.f, "reportFields", rf, "repts", repts) return false, nil, err @@ -372,11 +372,11 @@ func (rp *reportingPlugin) Report(repts types.ReportTimestamp, previousReport ty return true, report, nil } -func (rp *reportingPlugin) buildReportFields(previousReport types.Report, paos []PAO) (rf v1.ReportFields, merr error) { +func (rp *reportingPlugin) buildReportFields(ctx context.Context, previousReport types.Report, paos []PAO) (rf v1.ReportFields, merr error) { var err error if previousReport != nil { var maxFinalizedBlockNumber int64 - maxFinalizedBlockNumber, err = rp.reportCodec.CurrentBlockNumFromReport(previousReport) + maxFinalizedBlockNumber, err = rp.reportCodec.CurrentBlockNumFromReport(ctx, previousReport) if err != nil { merr = errors.Join(merr, err) } else { diff --git a/mercury/v1/mercury_test.go b/mercury/v1/mercury_test.go index 798fee5..3dcb714 100644 --- a/mercury/v1/mercury_test.go +++ b/mercury/v1/mercury_test.go @@ -23,6 +23,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" mercurytypes "github.com/smartcontractkit/chainlink-common/pkg/types/mercury" v1 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v1" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink-data-streams/mercury" ) @@ -42,7 +43,7 @@ func (trc *testReportCodec) reset() { trc.builtReportFields = nil } -func (trc *testReportCodec) BuildReport(rf v1.ReportFields) (types.Report, error) { +func (trc *testReportCodec) BuildReport(ctx context.Context, rf v1.ReportFields) (types.Report, error) { if trc.buildReportShouldFail { return nil, errors.New("buildReportShouldFail=true") } @@ -50,7 +51,7 @@ func (trc *testReportCodec) BuildReport(rf v1.ReportFields) (types.Report, error return trc.builtReport, nil } -func (trc *testReportCodec) MaxReportLength(n int) (int, error) { +func (trc *testReportCodec) MaxReportLength(ctx context.Context, n int) (int, error) { return 8*32 + // feed ID 32 + // timestamp 192 + // benchmarkPrice @@ -62,12 +63,12 @@ func (trc *testReportCodec) MaxReportLength(n int) (int, error) { nil } -func (trc *testReportCodec) CurrentBlockNumFromReport(types.Report) (int64, error) { +func (trc *testReportCodec) CurrentBlockNumFromReport(context.Context, types.Report) (int64, error) { return trc.currentBlock, trc.currentBlockErr } func newReportingPlugin(t *testing.T, codec *testReportCodec) *reportingPlugin { - maxReportLength, err := codec.MaxReportLength(4) + maxReportLength, err := codec.MaxReportLength(tests.Context(t), 4) require.NoError(t, err) return &reportingPlugin{ f: 1, @@ -711,7 +712,7 @@ func Test_Plugin_Report(t *testing.T) { rp := newReportingPlugin(t, codec) t.Run("errors if not enough attributed observations", func(t *testing.T) { - _, _, err := rp.Report(repts, nil, []types.AttributedObservation{}) + _, _, err := rp.Report(tests.Context(t), repts, nil, []types.AttributedObservation{}) assert.EqualError(t, err, "got zero valid attributed observations") }) t.Run("succeeds, ignoring unparseable attributed observations", func(t *testing.T) { @@ -721,7 +722,7 @@ func Test_Plugin_Report(t *testing.T) { newAttributedObservation(t, newValidMercuryObservationProto()), newUnparseableAttributedObservation(), } - should, report, err := rp.Report(repts, nil, aos) + should, report, err := rp.Report(tests.Context(t), repts, nil, aos) assert.NoError(t, err) assert.True(t, should) @@ -736,7 +737,7 @@ func Test_Plugin_Report(t *testing.T) { newAttributedObservation(t, newValidMercuryObservationProto()), newAttributedObservation(t, newValidMercuryObservationProto()), } - should, report, err := rp.Report(repts, nil, aos) + should, report, err := rp.Report(tests.Context(t), repts, nil, aos) assert.True(t, should) assert.Equal(t, codec.builtReport, report) @@ -761,7 +762,7 @@ func Test_Plugin_Report(t *testing.T) { newAttributedObservation(t, obs[2]), newAttributedObservation(t, obs[3]), } - _, _, err := rp.Report(repts, nil, aos) + _, _, err := rp.Report(tests.Context(t), repts, nil, aos) assert.EqualError(t, err, "no valid maxFinalizedBlockNumber with at least f+1 votes (got counts: map[0:1 1:1 2:1 3:1], f=1)") }) @@ -782,7 +783,7 @@ func Test_Plugin_Report(t *testing.T) { newAttributedObservation(t, obs[2]), newAttributedObservation(t, obs[3]), } - _, _, err := rp.Report(repts, nil, aos) + _, _, err := rp.Report(tests.Context(t), repts, nil, aos) require.Error(t, err) assert.Contains(t, err.Error(), "GetConsensusCurrentBlock failed: cannot come to consensus on latest block number") @@ -805,7 +806,7 @@ func Test_Plugin_Report(t *testing.T) { newAttributedObservation(t, obs[2]), newAttributedObservation(t, obs[3]), } - _, _, err := rp.Report(repts, nil, aos) + _, _, err := rp.Report(tests.Context(t), repts, nil, aos) require.Error(t, err) assert.Contains(t, err.Error(), "GetConsensusCurrentBlock failed: cannot come to consensus on latest block number") @@ -826,7 +827,7 @@ func Test_Plugin_Report(t *testing.T) { newAttributedObservation(t, obs[2]), newAttributedObservation(t, obs[3]), } - should, report, err := rp.Report(repts, nil, aos) + should, report, err := rp.Report(tests.Context(t), repts, nil, aos) assert.False(t, should) assert.Nil(t, report) @@ -843,7 +844,7 @@ func Test_Plugin_Report(t *testing.T) { newAttributedObservation(t, newValidMercuryObservationProto()), newUnparseableAttributedObservation(), } - _, _, err := rp.Report(repts, nil, aos) + _, _, err := rp.Report(tests.Context(t), repts, nil, aos) assert.EqualError(t, err, "buildReportShouldFail=true") }) @@ -855,7 +856,7 @@ func Test_Plugin_Report(t *testing.T) { newAttributedObservation(t, newValidMercuryObservationProto()), newUnparseableAttributedObservation(), } - _, _, err := rp.Report(repts, nil, aos) + _, _, err := rp.Report(tests.Context(t), repts, nil, aos) assert.EqualError(t, err, "report with len 9999 violates MaxReportLength limit set by ReportCodec (1248)") }) @@ -867,7 +868,7 @@ func Test_Plugin_Report(t *testing.T) { newAttributedObservation(t, newValidMercuryObservationProto()), newUnparseableAttributedObservation(), } - _, _, err := rp.Report(repts, nil, aos) + _, _, err := rp.Report(tests.Context(t), repts, nil, aos) assert.EqualError(t, err, "report may not have zero length (invariant violation)") }) @@ -891,7 +892,7 @@ func Test_Plugin_Report(t *testing.T) { newAttributedObservation(t, newValidMercuryObservationProto()), newAttributedObservation(t, newValidMercuryObservationProto()), } - should, report, err := rp.Report(repts, previousReport, aos) + should, report, err := rp.Report(tests.Context(t), repts, previousReport, aos) assert.True(t, should) assert.Equal(t, codec.builtReport, report) @@ -910,7 +911,7 @@ func Test_Plugin_Report(t *testing.T) { newAttributedObservation(t, newValidMercuryObservationProto()), newAttributedObservation(t, newValidMercuryObservationProto()), } - should, _, err := rp.Report(repts, previousReport, aos) + should, _, err := rp.Report(tests.Context(t), repts, previousReport, aos) assert.False(t, should) assert.EqualError(t, err, "test error current block fail") @@ -925,7 +926,7 @@ func Test_Plugin_Report(t *testing.T) { newAttributedObservation(t, newValidMercuryObservationProto()), newAttributedObservation(t, newValidMercuryObservationProto()), } - should, _, err := rp.Report(repts, previousReport, aos) + should, _, err := rp.Report(tests.Context(t), repts, previousReport, aos) assert.False(t, should) assert.NoError(t, err) diff --git a/mercury/v2/mercury.go b/mercury/v2/mercury.go index 87a4f50..8eb2e1e 100644 --- a/mercury/v2/mercury.go +++ b/mercury/v2/mercury.go @@ -63,18 +63,18 @@ func NewFactory(ds DataSource, lggr logger.Logger, occ mercurytypes.OnchainConfi return Factory{ds, lggr, occ, rc} } -func (fac Factory) NewMercuryPlugin(configuration ocr3types.MercuryPluginConfig) (ocr3types.MercuryPlugin, ocr3types.MercuryPluginInfo, error) { +func (fac Factory) NewMercuryPlugin(ctx context.Context, configuration ocr3types.MercuryPluginConfig) (ocr3types.MercuryPlugin, ocr3types.MercuryPluginInfo, error) { offchainConfig, err := mercury.DecodeOffchainConfig(configuration.OffchainConfig) if err != nil { return nil, ocr3types.MercuryPluginInfo{}, err } - onchainConfig, err := fac.onchainConfigCodec.Decode(configuration.OnchainConfig) + onchainConfig, err := fac.onchainConfigCodec.Decode(ctx, configuration.OnchainConfig) if err != nil { return nil, ocr3types.MercuryPluginInfo{}, err } - maxReportLength, err := fac.reportCodec.MaxReportLength(configuration.N) + maxReportLength, err := fac.reportCodec.MaxReportLength(ctx, configuration.N) if err != nil { return nil, ocr3types.MercuryPluginInfo{}, err } @@ -261,7 +261,7 @@ func parseAttributedObservations(lggr logger.Logger, aos []types.AttributedObser return paos } -func (rp *reportingPlugin) Report(repts types.ReportTimestamp, previousReport types.Report, aos []types.AttributedObservation) (shouldReport bool, report types.Report, err error) { +func (rp *reportingPlugin) Report(ctx context.Context, repts types.ReportTimestamp, previousReport types.Report, aos []types.AttributedObservation) (shouldReport bool, report types.Report, err error) { paos := parseAttributedObservations(rp.logger, aos) if len(paos) == 0 { @@ -273,7 +273,7 @@ func (rp *reportingPlugin) Report(repts types.ReportTimestamp, previousReport ty return false, nil, fmt.Errorf("only received %v valid attributed observations, but need at least f+1 (%v)", len(paos), rp.f+1) } - rf, err := rp.buildReportFields(previousReport, paos) + rf, err := rp.buildReportFields(ctx, previousReport, paos) if err != nil { rp.logger.Errorw("failed to build report fields", "paos", paos, "f", rp.f, "reportFields", rf, "repts", repts, "err", err) return false, nil, err @@ -290,7 +290,7 @@ func (rp *reportingPlugin) Report(repts types.ReportTimestamp, previousReport ty } rp.logger.Debugw("shouldReport: yes", "repts", repts) - report, err = rp.reportCodec.BuildReport(rf) + report, err = rp.reportCodec.BuildReport(ctx, rf) if err != nil { rp.logger.Debugw("failed to BuildReport", "paos", paos, "f", rp.f, "reportFields", rf, "repts", repts) return false, nil, err @@ -305,14 +305,14 @@ func (rp *reportingPlugin) Report(repts types.ReportTimestamp, previousReport ty return true, report, nil } -func (rp *reportingPlugin) buildReportFields(previousReport types.Report, paos []PAO) (rf v2.ReportFields, merr error) { +func (rp *reportingPlugin) buildReportFields(ctx context.Context, previousReport types.Report, paos []PAO) (rf v2.ReportFields, merr error) { mPaos := convert(paos) rf.Timestamp = mercury.GetConsensusTimestamp(mPaos) var err error if previousReport != nil { var maxFinalizedTimestamp uint32 - maxFinalizedTimestamp, err = rp.reportCodec.ObservationTimestampFromReport(previousReport) + maxFinalizedTimestamp, err = rp.reportCodec.ObservationTimestampFromReport(ctx, previousReport) merr = errors.Join(merr, err) rf.ValidFromTimestamp = maxFinalizedTimestamp + 1 } else { diff --git a/mercury/v2/mercury_test.go b/mercury/v2/mercury_test.go index 4f87408..60271af 100644 --- a/mercury/v2/mercury_test.go +++ b/mercury/v2/mercury_test.go @@ -21,6 +21,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" mercurytypes "github.com/smartcontractkit/chainlink-common/pkg/types/mercury" v2 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v2" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink-data-streams/mercury" ) @@ -41,17 +42,17 @@ type testReportCodec struct { err error } -func (rc *testReportCodec) BuildReport(rf v2.ReportFields) (types.Report, error) { +func (rc *testReportCodec) BuildReport(ctx context.Context, rf v2.ReportFields) (types.Report, error) { rc.builtReportFields = &rf return rc.builtReport, nil } -func (rc testReportCodec) MaxReportLength(n int) (int, error) { +func (rc testReportCodec) MaxReportLength(ctx context.Context, n int) (int, error) { return 123, nil } -func (rc testReportCodec) ObservationTimestampFromReport(types.Report) (uint32, error) { +func (rc testReportCodec) ObservationTimestampFromReport(context.Context, types.Report) (uint32, error) { return rc.observationTimestamp, rc.err } @@ -64,7 +65,7 @@ func newTestReportPlugin(t *testing.T, codec *testReportCodec, ds *testDataSourc Min: big.NewInt(1), Max: big.NewInt(1000), } - maxReportLength, _ := codec.MaxReportLength(4) + maxReportLength, _ := codec.MaxReportLength(tests.Context(t), 4) return &reportingPlugin{ offchainConfig: offchainConfig, onchainConfig: onchainConfig, @@ -166,7 +167,7 @@ func Test_Plugin_Report(t *testing.T) { t.Run("when previous report is nil", func(t *testing.T) { t.Run("errors if not enough attributed observations", func(t *testing.T) { - _, _, err := rp.Report(repts, nil, newValidAos(t)[0:1]) + _, _, err := rp.Report(tests.Context(t), repts, nil, newValidAos(t)[0:1]) assert.EqualError(t, err, "only received 1 valid attributed observations, but need at least f+1 (2)") }) t.Run("errors if too many maxFinalizedTimestamp observations are invalid", func(t *testing.T) { @@ -176,7 +177,7 @@ func Test_Plugin_Report(t *testing.T) { ps[2].MaxFinalizedTimestampValid = false aos := newValidAos(t, ps...) - should, _, err := rp.Report(types.ReportTimestamp{}, nil, aos) + should, _, err := rp.Report(tests.Context(t), types.ReportTimestamp{}, nil, aos) assert.False(t, should) assert.EqualError(t, err, "fewer than f+1 observations have a valid maxFinalizedTimestamp (got: 1/4)") }) @@ -188,7 +189,7 @@ func Test_Plugin_Report(t *testing.T) { ps[3].MaxFinalizedTimestamp = math.MaxUint32 aos := newValidAos(t, ps...) - should, _, err := rp.Report(types.ReportTimestamp{}, nil, aos) + should, _, err := rp.Report(tests.Context(t), types.ReportTimestamp{}, nil, aos) assert.False(t, should) assert.EqualError(t, err, "maxFinalizedTimestamp is too large, got: 4294967295") }) @@ -196,7 +197,7 @@ func Test_Plugin_Report(t *testing.T) { t.Run("succeeds and generates validFromTimestamp from maxFinalizedTimestamp when maxFinalizedTimestamp is positive", func(t *testing.T) { aos := newValidAos(t) - should, report, err := rp.Report(types.ReportTimestamp{}, nil, aos) + should, report, err := rp.Report(tests.Context(t), types.ReportTimestamp{}, nil, aos) assert.True(t, should) assert.NoError(t, err) assert.Equal(t, codec.builtReport, report) @@ -217,7 +218,7 @@ func Test_Plugin_Report(t *testing.T) { } aos := newValidAos(t, protos...) - should, report, err := rp.Report(types.ReportTimestamp{}, nil, aos) + should, report, err := rp.Report(tests.Context(t), types.ReportTimestamp{}, nil, aos) assert.True(t, should) assert.NoError(t, err) assert.Equal(t, codec.builtReport, report) @@ -238,7 +239,7 @@ func Test_Plugin_Report(t *testing.T) { } aos := newValidAos(t, protos...) - should, report, err := rp.Report(types.ReportTimestamp{}, nil, aos) + should, report, err := rp.Report(tests.Context(t), types.ReportTimestamp{}, nil, aos) assert.True(t, should) assert.NoError(t, err) assert.Equal(t, codec.builtReport, report) @@ -257,7 +258,7 @@ func Test_Plugin_Report(t *testing.T) { aos := newValidAos(t) aos[0] = newUnparseableAttributedObservation() - should, report, err := rp.Report(repts, nil, aos) + should, report, err := rp.Report(tests.Context(t), repts, nil, aos) require.NoError(t, err) assert.True(t, should) @@ -289,7 +290,7 @@ func Test_Plugin_Report(t *testing.T) { } aos := newValidAos(t, protos...) - should, report, err := rp.Report(repts, previousReport, aos) + should, report, err := rp.Report(tests.Context(t), repts, previousReport, aos) require.NoError(t, err) assert.True(t, should) @@ -308,7 +309,7 @@ func Test_Plugin_Report(t *testing.T) { codec.err = errors.New("something exploded trying to extract timestamp") aos := newValidAos(t) - should, _, err := rp.Report(types.ReportTimestamp{}, previousReport, aos) + should, _, err := rp.Report(tests.Context(t), types.ReportTimestamp{}, previousReport, aos) assert.False(t, should) assert.EqualError(t, err, "something exploded trying to extract timestamp") }) @@ -322,7 +323,7 @@ func Test_Plugin_Report(t *testing.T) { } aos := newValidAos(t, protos...) - should, _, err := rp.Report(types.ReportTimestamp{}, previousReport, aos) + should, _, err := rp.Report(tests.Context(t), types.ReportTimestamp{}, previousReport, aos) assert.False(t, should) assert.NoError(t, err) }) @@ -337,7 +338,7 @@ func Test_Plugin_Report(t *testing.T) { } aos := newValidAos(t, protos...) - should, report, err := rp.Report(types.ReportTimestamp{}, previousReport, aos) + should, report, err := rp.Report(tests.Context(t), types.ReportTimestamp{}, previousReport, aos) assert.True(t, should) assert.NoError(t, err) @@ -354,7 +355,7 @@ func Test_Plugin_Report(t *testing.T) { aos := newValidAos(t) codec.builtReport = make([]byte, 1<<16) - _, _, err := rp.Report(types.ReportTimestamp{}, nil, aos) + _, _, err := rp.Report(tests.Context(t), types.ReportTimestamp{}, nil, aos) assert.EqualError(t, err, "report with len 65536 violates MaxReportLength limit set by ReportCodec (123)") }) @@ -362,7 +363,7 @@ func Test_Plugin_Report(t *testing.T) { t.Run("Report errors when the report length is 0", func(t *testing.T) { aos := newValidAos(t) codec.builtReport = []byte{} - _, _, err := rp.Report(types.ReportTimestamp{}, nil, aos) + _, _, err := rp.Report(tests.Context(t), types.ReportTimestamp{}, nil, aos) assert.EqualError(t, err, "report may not have zero length (invariant violation)") }) diff --git a/mercury/v3/mercury.go b/mercury/v3/mercury.go index 20f801f..29279f2 100644 --- a/mercury/v3/mercury.go +++ b/mercury/v3/mercury.go @@ -65,18 +65,18 @@ func NewFactory(ds DataSource, lggr logger.Logger, occ mercurytypes.OnchainConfi return Factory{ds, lggr, occ, rc} } -func (fac Factory) NewMercuryPlugin(configuration ocr3types.MercuryPluginConfig) (ocr3types.MercuryPlugin, ocr3types.MercuryPluginInfo, error) { +func (fac Factory) NewMercuryPlugin(ctx context.Context, configuration ocr3types.MercuryPluginConfig) (ocr3types.MercuryPlugin, ocr3types.MercuryPluginInfo, error) { offchainConfig, err := mercury.DecodeOffchainConfig(configuration.OffchainConfig) if err != nil { return nil, ocr3types.MercuryPluginInfo{}, err } - onchainConfig, err := fac.onchainConfigCodec.Decode(configuration.OnchainConfig) + onchainConfig, err := fac.onchainConfigCodec.Decode(ctx, configuration.OnchainConfig) if err != nil { return nil, ocr3types.MercuryPluginInfo{}, err } - maxReportLength, err := fac.reportCodec.MaxReportLength(configuration.N) + maxReportLength, err := fac.reportCodec.MaxReportLength(ctx, configuration.N) if err != nil { return nil, ocr3types.MercuryPluginInfo{}, err } @@ -313,7 +313,7 @@ func parseAttributedObservations(lggr logger.Logger, aos []types.AttributedObser return paos } -func (rp *reportingPlugin) Report(repts types.ReportTimestamp, previousReport types.Report, aos []types.AttributedObservation) (shouldReport bool, report types.Report, err error) { +func (rp *reportingPlugin) Report(ctx context.Context, repts types.ReportTimestamp, previousReport types.Report, aos []types.AttributedObservation) (shouldReport bool, report types.Report, err error) { paos := parseAttributedObservations(rp.logger, aos) if len(paos) == 0 { @@ -325,7 +325,7 @@ func (rp *reportingPlugin) Report(repts types.ReportTimestamp, previousReport ty return false, nil, fmt.Errorf("only received %v valid attributed observations, but need at least f+1 (%v)", len(paos), rp.f+1) } - rf, err := rp.buildReportFields(previousReport, paos) + rf, err := rp.buildReportFields(ctx, previousReport, paos) if err != nil { rp.logger.Errorw("failed to build report fields", "paos", paos, "f", rp.f, "reportFields", rf, "repts", repts, "err", err) return false, nil, err @@ -342,7 +342,7 @@ func (rp *reportingPlugin) Report(repts types.ReportTimestamp, previousReport ty } rp.logger.Debugw("shouldReport: yes", "repts", repts) - report, err = rp.reportCodec.BuildReport(rf) + report, err = rp.reportCodec.BuildReport(ctx, rf) if err != nil { rp.logger.Debugw("failed to BuildReport", "paos", paos, "f", rp.f, "reportFields", rf, "repts", repts) return false, nil, err @@ -357,14 +357,14 @@ func (rp *reportingPlugin) Report(repts types.ReportTimestamp, previousReport ty return true, report, nil } -func (rp *reportingPlugin) buildReportFields(previousReport types.Report, paos []PAO) (rf v3.ReportFields, merr error) { +func (rp *reportingPlugin) buildReportFields(ctx context.Context, previousReport types.Report, paos []PAO) (rf v3.ReportFields, merr error) { mPaos := convert(paos) rf.Timestamp = mercury.GetConsensusTimestamp(mPaos) var err error if previousReport != nil { var maxFinalizedTimestamp uint32 - maxFinalizedTimestamp, err = rp.reportCodec.ObservationTimestampFromReport(previousReport) + maxFinalizedTimestamp, err = rp.reportCodec.ObservationTimestampFromReport(ctx, previousReport) merr = errors.Join(merr, err) rf.ValidFromTimestamp = maxFinalizedTimestamp + 1 } else { diff --git a/mercury/v3/mercury_test.go b/mercury/v3/mercury_test.go index 21c4ad4..87be4ac 100644 --- a/mercury/v3/mercury_test.go +++ b/mercury/v3/mercury_test.go @@ -21,6 +21,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" mercurytypes "github.com/smartcontractkit/chainlink-common/pkg/types/mercury" v3 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v3" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink-data-streams/mercury" ) @@ -41,17 +42,17 @@ type testReportCodec struct { err error } -func (rc *testReportCodec) BuildReport(rf v3.ReportFields) (types.Report, error) { +func (rc *testReportCodec) BuildReport(ctx context.Context, rf v3.ReportFields) (types.Report, error) { rc.builtReportFields = &rf return rc.builtReport, nil } -func (rc testReportCodec) MaxReportLength(n int) (int, error) { +func (rc testReportCodec) MaxReportLength(ctx context.Context, n int) (int, error) { return 123, nil } -func (rc testReportCodec) ObservationTimestampFromReport(types.Report) (uint32, error) { +func (rc testReportCodec) ObservationTimestampFromReport(context.Context, types.Report) (uint32, error) { return rc.observationTimestamp, rc.err } @@ -64,7 +65,7 @@ func newTestReportPlugin(t *testing.T, codec *testReportCodec, ds *testDataSourc Min: big.NewInt(1), Max: big.NewInt(1000), } - maxReportLength, _ := codec.MaxReportLength(4) + maxReportLength, _ := codec.MaxReportLength(tests.Context(t), 4) return &reportingPlugin{ offchainConfig: offchainConfig, onchainConfig: onchainConfig, @@ -202,7 +203,7 @@ func Test_Plugin_Report(t *testing.T) { t.Run("when previous report is nil", func(t *testing.T) { t.Run("errors if not enough attributed observations", func(t *testing.T) { - _, _, err := rp.Report(repts, nil, newValidAos(t)[0:1]) + _, _, err := rp.Report(tests.Context(t), repts, nil, newValidAos(t)[0:1]) assert.EqualError(t, err, "only received 1 valid attributed observations, but need at least f+1 (2)") }) @@ -213,7 +214,7 @@ func Test_Plugin_Report(t *testing.T) { ps[2].MaxFinalizedTimestampValid = false aos := newValidAos(t, ps...) - should, _, err := rp.Report(types.ReportTimestamp{}, nil, aos) + should, _, err := rp.Report(tests.Context(t), types.ReportTimestamp{}, nil, aos) assert.False(t, should) assert.EqualError(t, err, "fewer than f+1 observations have a valid maxFinalizedTimestamp (got: 1/4)") }) @@ -225,7 +226,7 @@ func Test_Plugin_Report(t *testing.T) { ps[3].MaxFinalizedTimestamp = math.MaxUint32 aos := newValidAos(t, ps...) - should, _, err := rp.Report(types.ReportTimestamp{}, nil, aos) + should, _, err := rp.Report(tests.Context(t), types.ReportTimestamp{}, nil, aos) assert.False(t, should) assert.EqualError(t, err, "maxFinalizedTimestamp is too large, got: 4294967295") }) @@ -233,7 +234,7 @@ func Test_Plugin_Report(t *testing.T) { t.Run("succeeds and generates validFromTimestamp from maxFinalizedTimestamp when maxFinalizedTimestamp is positive", func(t *testing.T) { aos := newValidAos(t) - should, report, err := rp.Report(types.ReportTimestamp{}, nil, aos) + should, report, err := rp.Report(tests.Context(t), types.ReportTimestamp{}, nil, aos) assert.True(t, should) assert.NoError(t, err) assert.Equal(t, codec.builtReport, report) @@ -256,7 +257,7 @@ func Test_Plugin_Report(t *testing.T) { } aos := newValidAos(t, protos...) - should, report, err := rp.Report(types.ReportTimestamp{}, nil, aos) + should, report, err := rp.Report(tests.Context(t), types.ReportTimestamp{}, nil, aos) assert.True(t, should) assert.NoError(t, err) assert.Equal(t, codec.builtReport, report) @@ -279,7 +280,7 @@ func Test_Plugin_Report(t *testing.T) { } aos := newValidAos(t, protos...) - should, report, err := rp.Report(types.ReportTimestamp{}, nil, aos) + should, report, err := rp.Report(tests.Context(t), types.ReportTimestamp{}, nil, aos) assert.True(t, should) assert.NoError(t, err) assert.Equal(t, codec.builtReport, report) @@ -300,7 +301,7 @@ func Test_Plugin_Report(t *testing.T) { aos := newValidAos(t) aos[0] = newUnparseableAttributedObservation() - should, report, err := rp.Report(repts, nil, aos) + should, report, err := rp.Report(tests.Context(t), repts, nil, aos) require.NoError(t, err) assert.True(t, should) @@ -334,7 +335,7 @@ func Test_Plugin_Report(t *testing.T) { } aos := newValidAos(t, protos...) - should, report, err := rp.Report(repts, previousReport, aos) + should, report, err := rp.Report(tests.Context(t), repts, previousReport, aos) require.NoError(t, err) assert.True(t, should) @@ -355,7 +356,7 @@ func Test_Plugin_Report(t *testing.T) { codec.err = errors.New("something exploded trying to extract timestamp") aos := newValidAos(t) - should, _, err := rp.Report(types.ReportTimestamp{}, previousReport, aos) + should, _, err := rp.Report(tests.Context(t), types.ReportTimestamp{}, previousReport, aos) assert.False(t, should) assert.EqualError(t, err, "something exploded trying to extract timestamp") }) @@ -369,7 +370,7 @@ func Test_Plugin_Report(t *testing.T) { } aos := newValidAos(t, protos...) - should, _, err := rp.Report(types.ReportTimestamp{}, previousReport, aos) + should, _, err := rp.Report(tests.Context(t), types.ReportTimestamp{}, previousReport, aos) assert.False(t, should) assert.NoError(t, err) }) @@ -384,7 +385,7 @@ func Test_Plugin_Report(t *testing.T) { } aos := newValidAos(t, protos...) - should, report, err := rp.Report(types.ReportTimestamp{}, previousReport, aos) + should, report, err := rp.Report(tests.Context(t), types.ReportTimestamp{}, previousReport, aos) assert.True(t, should) assert.NoError(t, err) @@ -401,7 +402,7 @@ func Test_Plugin_Report(t *testing.T) { aos := newValidAos(t) codec.builtReport = make([]byte, 1<<16) - _, _, err := rp.Report(types.ReportTimestamp{}, nil, aos) + _, _, err := rp.Report(tests.Context(t), types.ReportTimestamp{}, nil, aos) assert.EqualError(t, err, "report with len 65536 violates MaxReportLength limit set by ReportCodec (123)") }) @@ -409,7 +410,7 @@ func Test_Plugin_Report(t *testing.T) { t.Run("Report errors when the report length is 0", func(t *testing.T) { aos := newValidAos(t) codec.builtReport = []byte{} - _, _, err := rp.Report(types.ReportTimestamp{}, nil, aos) + _, _, err := rp.Report(tests.Context(t), types.ReportTimestamp{}, nil, aos) assert.EqualError(t, err, "report may not have zero length (invariant violation)") }) diff --git a/mercury/v4/mercury.go b/mercury/v4/mercury.go index 299ee8d..e396886 100644 --- a/mercury/v4/mercury.go +++ b/mercury/v4/mercury.go @@ -8,13 +8,14 @@ import ( "math/big" "time" - "github.com/smartcontractkit/chainlink-common/pkg/logger" - mercurytypes "github.com/smartcontractkit/chainlink-common/pkg/types/mercury" - v4 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v4" "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "google.golang.org/protobuf/proto" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + mercurytypes "github.com/smartcontractkit/chainlink-common/pkg/types/mercury" + v4 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v4" + "github.com/smartcontractkit/chainlink-data-streams/mercury" ) @@ -66,18 +67,18 @@ func NewFactory(ds DataSource, lggr logger.Logger, occ mercurytypes.OnchainConfi return Factory{ds, lggr, occ, rc} } -func (fac Factory) NewMercuryPlugin(configuration ocr3types.MercuryPluginConfig) (ocr3types.MercuryPlugin, ocr3types.MercuryPluginInfo, error) { +func (fac Factory) NewMercuryPlugin(ctx context.Context, configuration ocr3types.MercuryPluginConfig) (ocr3types.MercuryPlugin, ocr3types.MercuryPluginInfo, error) { offchainConfig, err := mercury.DecodeOffchainConfig(configuration.OffchainConfig) if err != nil { return nil, ocr3types.MercuryPluginInfo{}, err } - onchainConfig, err := fac.onchainConfigCodec.Decode(configuration.OnchainConfig) + onchainConfig, err := fac.onchainConfigCodec.Decode(ctx, configuration.OnchainConfig) if err != nil { return nil, ocr3types.MercuryPluginInfo{}, err } - maxReportLength, err := fac.reportCodec.MaxReportLength(configuration.N) + maxReportLength, err := fac.reportCodec.MaxReportLength(ctx, configuration.N) if err != nil { return nil, ocr3types.MercuryPluginInfo{}, err } @@ -278,7 +279,7 @@ func parseAttributedObservations(lggr logger.Logger, aos []types.AttributedObser return paos } -func (rp *reportingPlugin) Report(repts types.ReportTimestamp, previousReport types.Report, aos []types.AttributedObservation) (shouldReport bool, report types.Report, err error) { +func (rp *reportingPlugin) Report(ctx context.Context, repts types.ReportTimestamp, previousReport types.Report, aos []types.AttributedObservation) (shouldReport bool, report types.Report, err error) { paos := parseAttributedObservations(rp.logger, aos) if len(paos) == 0 { @@ -290,7 +291,7 @@ func (rp *reportingPlugin) Report(repts types.ReportTimestamp, previousReport ty return false, nil, fmt.Errorf("only received %v valid attributed observations, but need at least f+1 (%v)", len(paos), rp.f+1) } - rf, err := rp.buildReportFields(previousReport, paos) + rf, err := rp.buildReportFields(ctx, previousReport, paos) if err != nil { rp.logger.Errorw("failed to build report fields", "paos", paos, "f", rp.f, "reportFields", rf, "repts", repts, "err", err) return false, nil, err @@ -307,7 +308,7 @@ func (rp *reportingPlugin) Report(repts types.ReportTimestamp, previousReport ty } rp.logger.Debugw("shouldReport: yes", "repts", repts) - report, err = rp.reportCodec.BuildReport(rf) + report, err = rp.reportCodec.BuildReport(ctx, rf) if err != nil { rp.logger.Debugw("failed to BuildReport", "paos", paos, "f", rp.f, "reportFields", rf, "repts", repts) return false, nil, err @@ -322,14 +323,14 @@ func (rp *reportingPlugin) Report(repts types.ReportTimestamp, previousReport ty return true, report, nil } -func (rp *reportingPlugin) buildReportFields(previousReport types.Report, paos []PAO) (rf v4.ReportFields, merr error) { +func (rp *reportingPlugin) buildReportFields(ctx context.Context, previousReport types.Report, paos []PAO) (rf v4.ReportFields, merr error) { mPaos := convert(paos) rf.Timestamp = mercury.GetConsensusTimestamp(mPaos) var err error if previousReport != nil { var maxFinalizedTimestamp uint32 - maxFinalizedTimestamp, err = rp.reportCodec.ObservationTimestampFromReport(previousReport) + maxFinalizedTimestamp, err = rp.reportCodec.ObservationTimestampFromReport(ctx, previousReport) merr = errors.Join(merr, err) rf.ValidFromTimestamp = maxFinalizedTimestamp + 1 } else { diff --git a/mercury/v4/mercury_test.go b/mercury/v4/mercury_test.go index 0a51108..253beab 100644 --- a/mercury/v4/mercury_test.go +++ b/mercury/v4/mercury_test.go @@ -11,15 +11,18 @@ import ( "time" "github.com/shopspring/decimal" - "github.com/smartcontractkit/chainlink-common/pkg/logger" - mercurytypes "github.com/smartcontractkit/chainlink-common/pkg/types/mercury" - v4 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v4" - "github.com/smartcontractkit/libocr/commontypes" - "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" + "github.com/smartcontractkit/libocr/commontypes" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + mercurytypes "github.com/smartcontractkit/chainlink-common/pkg/types/mercury" + v4 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v4" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + "github.com/smartcontractkit/chainlink-data-streams/mercury" ) @@ -39,21 +42,22 @@ type testReportCodec struct { err error } -func (rc *testReportCodec) BuildReport(rf v4.ReportFields) (types.Report, error) { +func (rc *testReportCodec) BuildReport(ctx context.Context, rf v4.ReportFields) (types.Report, error) { rc.builtReportFields = &rf return rc.builtReport, nil } -func (rc testReportCodec) MaxReportLength(n int) (int, error) { +func (rc testReportCodec) MaxReportLength(ctx context.Context, n int) (int, error) { return 123, nil } -func (rc testReportCodec) ObservationTimestampFromReport(types.Report) (uint32, error) { +func (rc testReportCodec) ObservationTimestampFromReport(context.Context, types.Report) (uint32, error) { return rc.observationTimestamp, rc.err } func newTestReportPlugin(t *testing.T, codec *testReportCodec, ds *testDataSource) *reportingPlugin { + ctx := tests.Context(t) offchainConfig := mercury.OffchainConfig{ ExpirationWindow: 1, BaseUSDFee: decimal.NewFromInt32(1), @@ -62,7 +66,7 @@ func newTestReportPlugin(t *testing.T, codec *testReportCodec, ds *testDataSourc Min: big.NewInt(1), Max: big.NewInt(1000), } - maxReportLength, _ := codec.MaxReportLength(4) + maxReportLength, _ := codec.MaxReportLength(ctx, 4) return &reportingPlugin{ offchainConfig: offchainConfig, onchainConfig: onchainConfig, @@ -176,22 +180,25 @@ func Test_Plugin_Report(t *testing.T) { t.Run("when previous report is nil", func(t *testing.T) { t.Run("errors if not enough attributed observations", func(t *testing.T) { - _, _, err := rp.Report(repts, nil, newValidAos(t)[0:1]) + ctx := tests.Context(t) + _, _, err := rp.Report(ctx, repts, nil, newValidAos(t)[0:1]) assert.EqualError(t, err, "only received 1 valid attributed observations, but need at least f+1 (2)") }) t.Run("errors if too many maxFinalizedTimestamp observations are invalid", func(t *testing.T) { + ctx := tests.Context(t) ps := newValidProtos() ps[0].MaxFinalizedTimestampValid = false ps[1].MaxFinalizedTimestampValid = false ps[2].MaxFinalizedTimestampValid = false aos := newValidAos(t, ps...) - should, _, err := rp.Report(types.ReportTimestamp{}, nil, aos) + should, _, err := rp.Report(ctx, types.ReportTimestamp{}, nil, aos) assert.False(t, should) assert.EqualError(t, err, "fewer than f+1 observations have a valid maxFinalizedTimestamp (got: 1/4)") }) t.Run("errors if maxFinalizedTimestamp is too large", func(t *testing.T) { + ctx := tests.Context(t) ps := newValidProtos() ps[0].MaxFinalizedTimestamp = math.MaxUint32 ps[1].MaxFinalizedTimestamp = math.MaxUint32 @@ -199,15 +206,16 @@ func Test_Plugin_Report(t *testing.T) { ps[3].MaxFinalizedTimestamp = math.MaxUint32 aos := newValidAos(t, ps...) - should, _, err := rp.Report(types.ReportTimestamp{}, nil, aos) + should, _, err := rp.Report(ctx, types.ReportTimestamp{}, nil, aos) assert.False(t, should) assert.EqualError(t, err, "maxFinalizedTimestamp is too large, got: 4294967295") }) t.Run("succeeds and generates validFromTimestamp from maxFinalizedTimestamp when maxFinalizedTimestamp is positive", func(t *testing.T) { + ctx := tests.Context(t) aos := newValidAos(t) - should, report, err := rp.Report(types.ReportTimestamp{}, nil, aos) + should, report, err := rp.Report(ctx, types.ReportTimestamp{}, nil, aos) assert.True(t, should) assert.NoError(t, err) assert.Equal(t, codec.builtReport, report) @@ -223,13 +231,14 @@ func Test_Plugin_Report(t *testing.T) { }, *codec.builtReportFields) }) t.Run("succeeds and generates validFromTimestamp from maxFinalizedTimestamp when maxFinalizedTimestamp is zero", func(t *testing.T) { + ctx := tests.Context(t) protos := newValidProtos() for i := range protos { protos[i].MaxFinalizedTimestamp = 0 } aos := newValidAos(t, protos...) - should, report, err := rp.Report(types.ReportTimestamp{}, nil, aos) + should, report, err := rp.Report(ctx, types.ReportTimestamp{}, nil, aos) assert.True(t, should) assert.NoError(t, err) assert.Equal(t, codec.builtReport, report) @@ -245,13 +254,14 @@ func Test_Plugin_Report(t *testing.T) { }, *codec.builtReportFields) }) t.Run("succeeds and generates validFromTimestamp from maxFinalizedTimestamp when maxFinalizedTimestamp is -1 (missing feed)", func(t *testing.T) { + ctx := tests.Context(t) protos := newValidProtos() for i := range protos { protos[i].MaxFinalizedTimestamp = -1 } aos := newValidAos(t, protos...) - should, report, err := rp.Report(types.ReportTimestamp{}, nil, aos) + should, report, err := rp.Report(ctx, types.ReportTimestamp{}, nil, aos) assert.True(t, should) assert.NoError(t, err) assert.Equal(t, codec.builtReport, report) @@ -268,10 +278,11 @@ func Test_Plugin_Report(t *testing.T) { }) t.Run("succeeds, ignoring unparseable attributed observation", func(t *testing.T) { + ctx := tests.Context(t) aos := newValidAos(t) aos[0] = newUnparseableAttributedObservation() - should, report, err := rp.Report(repts, nil, aos) + should, report, err := rp.Report(ctx, repts, nil, aos) require.NoError(t, err) assert.True(t, should) @@ -297,6 +308,7 @@ func Test_Plugin_Report(t *testing.T) { previousReport := types.Report{} t.Run("succeeds and uses timestamp from previous report if valid", func(t *testing.T) { + ctx := tests.Context(t) protos := newValidProtos() ts := codec.observationTimestamp + 1 for i := range protos { @@ -304,7 +316,7 @@ func Test_Plugin_Report(t *testing.T) { } aos := newValidAos(t, protos...) - should, report, err := rp.Report(repts, previousReport, aos) + should, report, err := rp.Report(ctx, repts, previousReport, aos) require.NoError(t, err) assert.True(t, should) @@ -321,14 +333,16 @@ func Test_Plugin_Report(t *testing.T) { }, *codec.builtReportFields) }) t.Run("errors if cannot extract timestamp from previous report", func(t *testing.T) { + ctx := tests.Context(t) codec.err = errors.New("something exploded trying to extract timestamp") aos := newValidAos(t) - should, _, err := rp.Report(types.ReportTimestamp{}, previousReport, aos) + should, _, err := rp.Report(ctx, types.ReportTimestamp{}, previousReport, aos) assert.False(t, should) assert.EqualError(t, err, "something exploded trying to extract timestamp") }) t.Run("does not report if observationTimestamp < validFromTimestamp", func(t *testing.T) { + ctx := tests.Context(t) codec.observationTimestamp = 43 codec.err = nil @@ -338,11 +352,12 @@ func Test_Plugin_Report(t *testing.T) { } aos := newValidAos(t, protos...) - should, _, err := rp.Report(types.ReportTimestamp{}, previousReport, aos) + should, _, err := rp.Report(ctx, types.ReportTimestamp{}, previousReport, aos) assert.False(t, should) assert.NoError(t, err) }) t.Run("uses 0 values for link/native if they are invalid", func(t *testing.T) { + ctx := tests.Context(t) codec.observationTimestamp = 42 codec.err = nil @@ -353,7 +368,7 @@ func Test_Plugin_Report(t *testing.T) { } aos := newValidAos(t, protos...) - should, report, err := rp.Report(types.ReportTimestamp{}, previousReport, aos) + should, report, err := rp.Report(ctx, types.ReportTimestamp{}, previousReport, aos) assert.True(t, should) assert.NoError(t, err) @@ -367,18 +382,20 @@ func Test_Plugin_Report(t *testing.T) { t.Run("buildReport failures", func(t *testing.T) { t.Run("Report errors when the report is too large", func(t *testing.T) { + ctx := tests.Context(t) aos := newValidAos(t) codec.builtReport = make([]byte, 1<<16) - _, _, err := rp.Report(types.ReportTimestamp{}, nil, aos) + _, _, err := rp.Report(ctx, types.ReportTimestamp{}, nil, aos) assert.EqualError(t, err, "report with len 65536 violates MaxReportLength limit set by ReportCodec (123)") }) t.Run("Report errors when the report length is 0", func(t *testing.T) { + ctx := tests.Context(t) aos := newValidAos(t) codec.builtReport = []byte{} - _, _, err := rp.Report(types.ReportTimestamp{}, nil, aos) + _, _, err := rp.Report(ctx, types.ReportTimestamp{}, nil, aos) assert.EqualError(t, err, "report may not have zero length (invariant violation)") })