From fdbdfe52d30a3439ff8a885a67e55b4cc79cb10f Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Fri, 1 Mar 2024 12:51:29 -0300 Subject: [PATCH 01/34] bump Seth version, do not use EIP-1559 for Sepolia, bump gas prices and timeouts for Seth (#12261) --- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- integration-tests/testconfig/default.toml | 20 ++++++++++---------- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/integration-tests/go.mod b/integration-tests/go.mod index a65042b1db5..4d46367ec9f 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -28,7 +28,7 @@ require ( github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240229181116-bfb2432a7a66 - github.com/smartcontractkit/seth v0.1.1 + github.com/smartcontractkit/seth v0.1.2 github.com/smartcontractkit/wasp v0.4.5 github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.8.4 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 0dbb9e8cb86..2626cf0e8b2 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1538,8 +1538,8 @@ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20240229181116-bfb2432a7a66 h1:xsU00JB9GJxEiN6tDbqgN+fT98ySdxkUwTw6CfBXscw= github.com/smartcontractkit/libocr v0.0.0-20240229181116-bfb2432a7a66/go.mod h1:SJEZCHgMCAzzBvo9vMV2DQ9onfEcIJCYSViyP4JI6c4= -github.com/smartcontractkit/seth v0.1.1 h1:Uh7Ldr6N+4HV6YPI/s5s3P8I+UndJXzDSL2VsBsiL/Y= -github.com/smartcontractkit/seth v0.1.1/go.mod h1:aOaGwrIVFG/MYaLSj9UUMyE5QJnYQoAgnxm5cKfT9Ng= +github.com/smartcontractkit/seth v0.1.2 h1:ImXJmniuq6yWB6b3eezjV+lkYb1GfQuaJkwRvrCfTKQ= +github.com/smartcontractkit/seth v0.1.2/go.mod h1:aOaGwrIVFG/MYaLSj9UUMyE5QJnYQoAgnxm5cKfT9Ng= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index a3d3fa093c7..d538469eb66 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -20,7 +20,7 @@ require ( github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 github.com/smartcontractkit/libocr v0.0.0-20240229181116-bfb2432a7a66 - github.com/smartcontractkit/seth v0.1.1 + github.com/smartcontractkit/seth v0.1.2 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 github.com/smartcontractkit/wasp v0.4.5 github.com/stretchr/testify v1.8.4 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 1129211f6c2..9dc04e2567f 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1521,8 +1521,8 @@ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20240229181116-bfb2432a7a66 h1:xsU00JB9GJxEiN6tDbqgN+fT98ySdxkUwTw6CfBXscw= github.com/smartcontractkit/libocr v0.0.0-20240229181116-bfb2432a7a66/go.mod h1:SJEZCHgMCAzzBvo9vMV2DQ9onfEcIJCYSViyP4JI6c4= -github.com/smartcontractkit/seth v0.1.1 h1:Uh7Ldr6N+4HV6YPI/s5s3P8I+UndJXzDSL2VsBsiL/Y= -github.com/smartcontractkit/seth v0.1.1/go.mod h1:aOaGwrIVFG/MYaLSj9UUMyE5QJnYQoAgnxm5cKfT9Ng= +github.com/smartcontractkit/seth v0.1.2 h1:ImXJmniuq6yWB6b3eezjV+lkYb1GfQuaJkwRvrCfTKQ= +github.com/smartcontractkit/seth v0.1.2/go.mod h1:aOaGwrIVFG/MYaLSj9UUMyE5QJnYQoAgnxm5cKfT9Ng= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= diff --git a/integration-tests/testconfig/default.toml b/integration-tests/testconfig/default.toml index b1815b1395b..26b68fd4f1f 100644 --- a/integration-tests/testconfig/default.toml +++ b/integration-tests/testconfig/default.toml @@ -54,7 +54,7 @@ gas_tip_cap = 3_000_000_000 [[Seth.networks]] name = "Fuji" chain_id = "43113" -transaction_timeout = "30s" +transaction_timeout = "3m" transfer_gas_fee = 21_000 # legacy transactions gas_price = 30_000_000_000 @@ -66,20 +66,20 @@ gas_tip_cap = 1_800_000_000 [[Seth.networks]] name = "Sepolia" chain_id = "11155111" -transaction_timeout = "30s" -transfer_gas_fee = 21_000 -gas_limit = 14_000_000 +transaction_timeout = "3m" +transfer_gas_fee = 40_000 +gas_limit = 30_000_000 # legacy transactions -gas_price = 1_000_000_000 +gas_price = 20_000_000_000 # EIP-1559 transactions -eip_1559_dynamic_fees = true -gas_fee_cap = 25_000_000_000 -gas_tip_cap = 5_000_000_000 +# eip_1559_dynamic_fees = true2 +gas_fee_cap = 45_000_000_000 +gas_tip_cap = 10_000_000_000 [[Seth.networks]] name = "Mumbai" chain_id = "80001" -transaction_timeout = "30s" +transaction_timeout = "3m" transfer_gas_fee = 21_000 # legacy transactions #gas_price = 1_800_000_000 @@ -91,7 +91,7 @@ gas_tip_cap = 1_800_000_000 [[Seth.networks]] name = "zkEVM" chain_id = "1442" -transaction_timeout = "30s" +transaction_timeout = "3m" transfer_gas_fee = 21_000 gas_limit = 3_000_000 # legacy transactions From 91a045018f9740b8c9272019a62300860e6f9e4d Mon Sep 17 00:00:00 2001 From: Clement Erena Date: Fri, 1 Mar 2024 17:53:17 +0100 Subject: [PATCH 02/34] feat(dashboard): adapt for chainlink cluster (#12259) * feat(dashboard): adapt for chainlink cluster * fix wasp ds and add README * feat(dashboard): add pod filter * fix(dashboard): kube panels for chainlink cluster * fix(dashboard): instance variable for chainlink cluster --------- Co-authored-by: skudasov --- charts/chainlink-cluster/README.md | 20 +- .../chainlink-cluster/dashboard/dashboard.go | 39 +- charts/chainlink-cluster/dashboard/panels.go | 586 +++++++++--------- 3 files changed, 344 insertions(+), 301 deletions(-) diff --git a/charts/chainlink-cluster/README.md b/charts/chainlink-cluster/README.md index c06107d2669..394e11d2070 100644 --- a/charts/chainlink-cluster/README.md +++ b/charts/chainlink-cluster/README.md @@ -136,15 +136,23 @@ helm uninstall cl-cluster ``` # Grafana dashboard -We are using [Grabana]() lib to create dashboards programmatically +We are using [Grabana](https://github.com/K-Phoen/grabana) lib to create dashboards programmatically + +You can select `PANELS_INCLUDED`, options are `core`, `wasp`, comma separated + +You can also select dashboard platform in `INFRA_PLATFORM` either `kubernetes` or `docker` ``` +export LOKI_TENANT_ID=promtail +export LOKI_URL=... export GRAFANA_URL=... export GRAFANA_TOKEN=... -export LOKI_DATA_SOURCE_NAME=Loki export PROMETHEUS_DATA_SOURCE_NAME=Thanos -export DASHBOARD_FOLDER=CRIB -export DASHBOARD_NAME=ChainlinkCluster +export LOKI_DATA_SOURCE_NAME=Loki +export PANELS_INCLUDED=core,wasp +export INFRA_PLATFORM=kubernetes|docker +export GRAFANA_FOLDER=DashboardCoreDebug +export DASHBOARD_NAME=ChainlinkClusterDebug -cd dashboard/cmd && go run dashboard_deploy.go +go run dashboard/cmd/dashboard_deploy.go ``` -Open Grafana folder `CRIB` and find dashboard `ChainlinkCluster` \ No newline at end of file +Open Grafana folder `DashboardCoreDebug` and find dashboard `ChainlinkClusterDebug` \ No newline at end of file diff --git a/charts/chainlink-cluster/dashboard/dashboard.go b/charts/chainlink-cluster/dashboard/dashboard.go index bc5fa51cc31..ff8b7fa8a0a 100644 --- a/charts/chainlink-cluster/dashboard/dashboard.go +++ b/charts/chainlink-cluster/dashboard/dashboard.go @@ -12,7 +12,10 @@ import ( ) type PanelOption struct { - labelFilter string + labelFilters map[string]string + labelFilter string + legendString string + labelQuery string } type Dashboard struct { @@ -71,8 +74,8 @@ func NewDashboard( "branch": `=~"${branch:pipe}"`, "commit": `=~"${commit:pipe}"`, } - waspPanelsLoadStats := wasp.WASPLoadStatsRow(db.PrometheusDataSourceName, panelQuery) - waspPanelsDebugData := wasp.WASPDebugDataRow(db.PrometheusDataSourceName, panelQuery, false) + waspPanelsLoadStats := wasp.WASPLoadStatsRow(db.LokiDataSourceName, panelQuery) + waspPanelsDebugData := wasp.WASPDebugDataRow(db.LokiDataSourceName, panelQuery, false) db.opts = append(db.opts, waspPanelsLoadStats) db.opts = append(db.opts, waspPanelsDebugData) break @@ -119,15 +122,33 @@ func (m *Dashboard) init() { dashboard.Tags(m.grafanaTags), } + m.panelOption.labelFilters = map[string]string{ + "instance": `=~"${instance}"`, + "commit": `=~"${commit:pipe}"`, + } + switch m.platform { case "kubernetes": + m.panelOption.labelFilters = map[string]string{ + "job": `=~"${instance}"`, + "namespace": `=~"${namespace}"`, + "pod": `=~"${pod}"`, + } m.panelOption.labelFilter = "job" + m.panelOption.legendString = "pod" break case "docker": + m.panelOption.labelFilters = map[string]string{ + "instance": `=~"${instance}"`, + } m.panelOption.labelFilter = "instance" + m.panelOption.legendString = "instance" break } + for key, value := range m.panelOption.labelFilters { + m.panelOption.labelQuery += key + value + ", " + } m.opts = append(m.opts, opts...) } @@ -158,15 +179,23 @@ func (m *Dashboard) addKubernetesVariables() { opts := []dashboard.Option{ dashboard.VariableAsQuery( "namespace", - query.DataSource(m.LokiDataSourceName), + query.DataSource(m.PrometheusDataSourceName), query.Multiple(), query.IncludeAll(), query.Request(fmt.Sprintf("label_values(%s)", "namespace")), query.Sort(query.NumericalAsc), ), + dashboard.VariableAsQuery( + "pod", + query.DataSource(m.PrometheusDataSourceName), + query.Multiple(), + query.IncludeAll(), + query.Request("label_values(kube_pod_container_info{namespace=\"$namespace\"}, pod)"), + query.Sort(query.NumericalAsc), + ), } m.opts = append(m.opts, opts...) - waspVariables := wasp.AddVariables(m.PrometheusDataSourceName) + waspVariables := wasp.AddVariables(m.LokiDataSourceName) m.opts = append(m.opts, waspVariables...) } diff --git a/charts/chainlink-cluster/dashboard/panels.go b/charts/chainlink-cluster/dashboard/panels.go index 597c4faf679..61161a2f7b6 100644 --- a/charts/chainlink-cluster/dashboard/panels.go +++ b/charts/chainlink-cluster/dashboard/panels.go @@ -12,28 +12,21 @@ import ( ) func (m *Dashboard) addMainPanels() { - var balancePanelSpanSize float32 = 4 var panelsIncluded []row.Option var goVersionLegend string = "version" - if m.platform == "kubernetes" { - balancePanelSpanSize = 3 - goVersionLegend = "exported_version" - } - globalInfoPanels := []row.Option{ row.WithStat( "App Version", stat.DataSource(m.PrometheusDataSourceName), stat.Text(stat.TextValueAndName), - stat.Orientation(stat.OrientationVertical), + stat.Orientation(stat.OrientationAuto), stat.TitleFontSize(12), stat.ValueFontSize(20), stat.Span(2), stat.Text("name"), - stat.Height("100px"), stat.WithPrometheusTarget( - `version{`+m.panelOption.labelFilter+`=~"$instance"}`, + `version{`+m.panelOption.labelQuery+`}`, prometheus.Legend("{{version}}"), ), ), @@ -41,14 +34,13 @@ func (m *Dashboard) addMainPanels() { "Go Version", stat.DataSource(m.PrometheusDataSourceName), stat.Text(stat.TextValueAndName), - stat.Orientation(stat.OrientationVertical), + stat.Orientation(stat.OrientationAuto), stat.TitleFontSize(12), stat.ValueFontSize(20), stat.Span(2), stat.Text("name"), - stat.Height("100px"), stat.WithPrometheusTarget( - `go_info{`+m.panelOption.labelFilter+`=~"$instance"}`, + `go_info{`+m.panelOption.labelQuery+`}`, prometheus.Legend("{{"+goVersionLegend+"}}"), ), ), @@ -56,43 +48,40 @@ func (m *Dashboard) addMainPanels() { "Uptime in days", stat.DataSource(m.PrometheusDataSourceName), stat.Text(stat.TextValueAndName), - stat.Orientation(stat.OrientationVertical), + stat.Orientation(stat.OrientationHorizontal), stat.TitleFontSize(12), stat.ValueFontSize(20), - stat.Span(2), - stat.Height("100px"), + stat.Span(8), stat.WithPrometheusTarget( - `uptime_seconds{`+m.panelOption.labelFilter+`=~"$instance"} / 86400`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `uptime_seconds{`+m.panelOption.labelQuery+`} / 86400`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithStat( "ETH Balance", stat.DataSource(m.PrometheusDataSourceName), stat.Text(stat.TextValueAndName), - stat.Orientation(stat.OrientationVertical), + stat.Orientation(stat.OrientationHorizontal), stat.TitleFontSize(12), stat.ValueFontSize(20), - stat.Span(balancePanelSpanSize), - stat.Height("100px"), + stat.Span(6), stat.Decimals(2), stat.WithPrometheusTarget( - `eth_balance{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - {{account}}"), + `eth_balance{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - {{account}}"), ), ), row.WithStat( "Solana Balance", stat.DataSource(m.PrometheusDataSourceName), stat.Text(stat.TextValueAndName), - stat.Orientation(stat.OrientationVertical), + stat.Orientation(stat.OrientationHorizontal), stat.TitleFontSize(12), stat.ValueFontSize(20), - stat.Span(balancePanelSpanSize), - stat.Height("100px"), + stat.Span(6), stat.Decimals(2), stat.WithPrometheusTarget( - `solana_balance{`+m.panelOption.labelFilter+`=~"$instance"}`, + `solana_balance{`+m.panelOption.labelQuery+`}`, prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - {{account}}"), ), ), @@ -105,8 +94,8 @@ func (m *Dashboard) addMainPanels() { timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `health{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - {{service_id}}"), + `health{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - {{service_id}}"), ), ), row.WithTimeSeries( @@ -119,8 +108,8 @@ func (m *Dashboard) addMainPanels() { axis.Decimals(2), ), timeseries.WithPrometheusTarget( - `eth_balance{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - {{account}}"), + `eth_balance{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - {{account}}"), ), ), row.WithTimeSeries( @@ -133,8 +122,8 @@ func (m *Dashboard) addMainPanels() { axis.Decimals(2), ), timeseries.WithPrometheusTarget( - `solana_balance{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - {{account}}"), + `solana_balance{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - {{account}}"), ), ), } @@ -171,36 +160,39 @@ func (m *Dashboard) addKubePanels() { row.WithStat( "Pod Restarts", stat.Span(4), - stat.Height("200px"), + stat.Text(stat.TextValueAndName), + stat.Orientation(stat.OrientationHorizontal), stat.DataSource(m.PrometheusDataSourceName), stat.SparkLine(), stat.SparkLineYMin(0), stat.WithPrometheusTarget( - `sum(increase(kube_pod_container_status_restarts_total{pod=~"$instance.*", namespace=~"${namespace}"}[$__rate_interval])) by (pod)`, + `sum(increase(kube_pod_container_status_restarts_total{pod=~"$pod", namespace=~"${namespace}"}[$__rate_interval])) by (pod)`, prometheus.Legend("{{pod}}"), ), ), row.WithStat( "OOM Events", stat.Span(4), - stat.Height("200px"), + stat.Text(stat.TextValueAndName), + stat.Orientation(stat.OrientationHorizontal), stat.DataSource(m.PrometheusDataSourceName), stat.SparkLine(), stat.SparkLineYMin(0), stat.WithPrometheusTarget( - `sum(container_oom_events_total{pod=~"$instance.*", namespace=~"${namespace}"}) by (pod)`, + `sum(container_oom_events_total{pod=~"$pod", namespace=~"${namespace}"}) by (pod)`, prometheus.Legend("{{pod}}"), ), ), row.WithStat( "OOM Killed", stat.Span(4), - stat.Height("200px"), + stat.Text(stat.TextValueAndName), + stat.Orientation(stat.OrientationHorizontal), stat.DataSource(m.PrometheusDataSourceName), stat.SparkLine(), stat.SparkLineYMin(0), stat.WithPrometheusTarget( - `kube_pod_container_status_last_terminated_reason{reason="OOMKilled", pod=~"$instance.*", namespace=~"${namespace}"}`, + `kube_pod_container_status_last_terminated_reason{reason="OOMKilled", pod=~"$pod", namespace=~"${namespace}"}`, prometheus.Legend("{{pod}}"), ), ), @@ -210,7 +202,7 @@ func (m *Dashboard) addKubePanels() { timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~"$instance.*", namespace=~"${namespace}"}) by (pod)`, + `sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~"$pod", namespace=~"${namespace}"}) by (pod)`, prometheus.Legend("{{pod}}"), ), ), @@ -225,7 +217,7 @@ func (m *Dashboard) addKubePanels() { axis.SoftMin(0), ), timeseries.WithPrometheusTarget( - `sum(container_memory_rss{pod=~"$instance.*", namespace=~"${namespace}", container!=""}) by (pod)`, + `sum(container_memory_rss{pod=~"$pod", namespace=~"${namespace}", container!=""}) by (pod)`, prometheus.Legend("{{pod}}"), ), ), @@ -239,7 +231,7 @@ func (m *Dashboard) addKubePanels() { axis.SoftMin(0), ), timeseries.WithPrometheusTarget( - `sum(irate(container_network_receive_bytes_total{pod=~"$instance.*", namespace=~"${namespace}"}[$__rate_interval])) by (pod)`, + `sum(irate(container_network_receive_bytes_total{pod=~"$pod", namespace=~"${namespace}"}[$__rate_interval])) by (pod)`, prometheus.Legend("{{pod}}"), ), ), @@ -253,7 +245,7 @@ func (m *Dashboard) addKubePanels() { axis.SoftMin(0), ), timeseries.WithPrometheusTarget( - `sum(irate(container_network_transmit_bytes_total{pod=~"$instance.*", namespace=~"${namespace}"}[$__rate_interval])) by (pod)`, + `sum(irate(container_network_transmit_bytes_total{pod=~"$pod", namespace=~"${namespace}"}[$__rate_interval])) by (pod)`, prometheus.Legend("{{pod}}"), ), ), @@ -267,7 +259,7 @@ func (m *Dashboard) addKubePanels() { axis.SoftMin(0), ), timeseries.WithPrometheusTarget( - `avg(irate(container_network_receive_bytes_total{pod=~"$instance.*", namespace=~"${namespace}"}[$__rate_interval])) by (pod)`, + `avg(irate(container_network_receive_bytes_total{pod=~"$pod", namespace=~"${namespace}"}[$__rate_interval])) by (pod)`, prometheus.Legend("{{pod}}"), ), ), @@ -281,7 +273,7 @@ func (m *Dashboard) addKubePanels() { axis.SoftMin(0), ), timeseries.WithPrometheusTarget( - `avg(irate(container_network_transmit_bytes_total{pod=~"$instance.*", namespace=~"${namespace}"}[$__rate_interval])) by (pod)`, + `avg(irate(container_network_transmit_bytes_total{pod=~"$pod", namespace=~"${namespace}"}[$__rate_interval])) by (pod)`, prometheus.Legend("{{pod}}"), ), ), @@ -301,11 +293,11 @@ func (m *Dashboard) addLogPollerPanels() { timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `avg(sum(rate(log_poller_query_duration_count{`+m.panelOption.labelFilter+`=~"$instance", evmChainID=~"$evmChainID"}[$__rate_interval])) by (query, instance)) by (query)`, + `avg(sum(rate(log_poller_query_duration_count{`+m.panelOption.labelQuery+`evmChainID=~"$evmChainID"}[$__rate_interval])) by (query, `+m.panelOption.labelFilter+`)) by (query)`, prometheus.Legend("{{query}}"), ), timeseries.WithPrometheusTarget( - `avg(sum(rate(log_poller_query_duration_count{`+m.panelOption.labelFilter+`=~"$instance", evmChainID=~"$evmChainID"}[$__rate_interval]))) by (instance)`, + `avg(sum(rate(log_poller_query_duration_count{`+m.panelOption.labelFilter+`=~"$instance", evmChainID=~"$evmChainID"}[$__rate_interval]))) by (`+m.panelOption.labelFilter+`)`, prometheus.Legend("Total"), ), ), @@ -315,7 +307,7 @@ func (m *Dashboard) addLogPollerPanels() { timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `log_poller_query_dataset_size{`+m.panelOption.labelFilter+`=~"$instance", evmChainID=~"$evmChainID"}`, + `log_poller_query_dataset_size{`+m.panelOption.labelQuery+`evmChainID=~"$evmChainID"}`, prometheus.Legend("{{query}} : {{type}}"), ), ), @@ -325,7 +317,7 @@ func (m *Dashboard) addLogPollerPanels() { timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `avg(log_poller_query_dataset_size{`+m.panelOption.labelFilter+`=~"$instance", evmChainID=~"$evmChainID"}) by (query)`, + `avg(log_poller_query_dataset_size{`+m.panelOption.labelQuery+`evmChainID=~"$evmChainID"}) by (query)`, prometheus.Legend("{{query}}"), ), ), @@ -335,7 +327,7 @@ func (m *Dashboard) addLogPollerPanels() { timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `max(log_poller_query_dataset_size{`+m.panelOption.labelFilter+`=~"$instance", evmChainID=~"$evmChainID"}) by (query)`, + `max(log_poller_query_dataset_size{`+m.panelOption.labelQuery+`evmChainID=~"$evmChainID"}) by (query)`, prometheus.Legend("{{query}}"), ), ), @@ -345,7 +337,7 @@ func (m *Dashboard) addLogPollerPanels() { timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `max(log_poller_query_dataset_size{`+m.panelOption.labelFilter+`=~"$instance"}) by (evmChainID)`, + `max(log_poller_query_dataset_size{`+m.panelOption.labelQuery+`}) by (evmChainID)`, prometheus.Legend("{{evmChainID}}"), ), ), @@ -355,7 +347,7 @@ func (m *Dashboard) addLogPollerPanels() { timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `(sum(rate(log_poller_query_duration_sum{`+m.panelOption.labelFilter+`=~"$instance", evmChainID=~"$evmChainID"}[$__rate_interval])) by (query) / sum(rate(log_poller_query_duration_count{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval])) by (query)) / 1e6`, + `(sum(rate(log_poller_query_duration_sum{`+m.panelOption.labelQuery+`evmChainID=~"$evmChainID"}[$__rate_interval])) by (query) / sum(rate(log_poller_query_duration_count{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (query)) / 1e6`, prometheus.Legend("{{query}}"), ), ), @@ -365,7 +357,7 @@ func (m *Dashboard) addLogPollerPanels() { timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `histogram_quantile(0.99, sum(rate(log_poller_query_duration_bucket{`+m.panelOption.labelFilter+`=~"$instance", evmChainID=~"$evmChainID"}[$__rate_interval])) by (le, query)) / 1e6`, + `histogram_quantile(0.99, sum(rate(log_poller_query_duration_bucket{`+m.panelOption.labelQuery+`evmChainID=~"$evmChainID"}[$__rate_interval])) by (le, query)) / 1e6`, prometheus.Legend("{{query}}"), ), ), @@ -375,7 +367,7 @@ func (m *Dashboard) addLogPollerPanels() { timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `histogram_quantile(0.95, sum(rate(log_poller_query_duration_bucket{`+m.panelOption.labelFilter+`=~"$instance", evmChainID=~"$evmChainID"}[$__rate_interval])) by (le, query)) / 1e6`, + `histogram_quantile(0.95, sum(rate(log_poller_query_duration_bucket{`+m.panelOption.labelQuery+`evmChainID=~"$evmChainID"}[$__rate_interval])) by (le, query)) / 1e6`, prometheus.Legend("{{query}}"), ), ), @@ -385,7 +377,7 @@ func (m *Dashboard) addLogPollerPanels() { timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `histogram_quantile(0.95, sum(rate(log_poller_query_duration_bucket{`+m.panelOption.labelFilter+`=~"$instance", evmChainID=~"$evmChainID"}[$__rate_interval])) by (le, query)) / 1e6`, + `histogram_quantile(0.95, sum(rate(log_poller_query_duration_bucket{`+m.panelOption.labelQuery+`evmChainID=~"$evmChainID"}[$__rate_interval])) by (le, query)) / 1e6`, prometheus.Legend("{{query}}"), ), ), @@ -395,7 +387,7 @@ func (m *Dashboard) addLogPollerPanels() { timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `histogram_quantile(0.5, sum(rate(log_poller_query_duration_bucket{`+m.panelOption.labelFilter+`=~"$instance", evmChainID=~"$evmChainID"}[$__rate_interval])) by (le, query)) / 1e6`, + `histogram_quantile(0.5, sum(rate(log_poller_query_duration_bucket{`+m.panelOption.labelQuery+`evmChainID=~"$evmChainID"}[$__rate_interval])) by (le, query)) / 1e6`, prometheus.Legend("{{query}}"), ), ), @@ -418,8 +410,8 @@ func (m *Dashboard) addFeedsJobsPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `feeds_job_proposal_requests{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `feeds_job_proposal_requests{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -431,8 +423,8 @@ func (m *Dashboard) addFeedsJobsPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `feeds_job_proposal_count{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `feeds_job_proposal_count{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), ), @@ -454,8 +446,8 @@ func (m *Dashboard) addMailboxPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `mailbox_load_percent{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - {{ name }}"), + `mailbox_load_percent{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - {{ name }}"), ), ), ), @@ -477,8 +469,8 @@ func (m *Dashboard) addPromReporterPanels() { axis.Unit("Tx"), ), timeseries.WithPrometheusTarget( - `unconfirmed_transactions{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `unconfirmed_transactions{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -490,8 +482,8 @@ func (m *Dashboard) addPromReporterPanels() { axis.Unit("Sec"), ), timeseries.WithPrometheusTarget( - `max_unconfirmed_tx_age{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `max_unconfirmed_tx_age{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -503,8 +495,8 @@ func (m *Dashboard) addPromReporterPanels() { axis.Unit("Blocks"), ), timeseries.WithPrometheusTarget( - `max_unconfirmed_blocks{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `max_unconfirmed_blocks{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), ), @@ -526,8 +518,8 @@ func (m *Dashboard) addTxManagerPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `tx_manager_time_until_tx_broadcast{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `tx_manager_time_until_tx_broadcast{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -539,8 +531,8 @@ func (m *Dashboard) addTxManagerPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `tx_manager_num_gas_bumps{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `tx_manager_num_gas_bumps{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -552,8 +544,8 @@ func (m *Dashboard) addTxManagerPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `tx_manager_gas_bump_exceeds_limit{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `tx_manager_gas_bump_exceeds_limit{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -565,8 +557,8 @@ func (m *Dashboard) addTxManagerPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `tx_manager_num_confirmed_transactions{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `tx_manager_num_confirmed_transactions{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -578,8 +570,8 @@ func (m *Dashboard) addTxManagerPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `tx_manager_num_successful_transactions{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `tx_manager_num_successful_transactions{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -591,8 +583,8 @@ func (m *Dashboard) addTxManagerPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `tx_manager_num_tx_reverted{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `tx_manager_num_tx_reverted{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -604,8 +596,8 @@ func (m *Dashboard) addTxManagerPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `tx_manager_fwd_tx_count{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `tx_manager_fwd_tx_count{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -617,8 +609,8 @@ func (m *Dashboard) addTxManagerPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `tx_manager_tx_attempt_count{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `tx_manager_tx_attempt_count{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -630,8 +622,8 @@ func (m *Dashboard) addTxManagerPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `tx_manager_time_until_tx_confirmed{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `tx_manager_time_until_tx_confirmed{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -643,8 +635,8 @@ func (m *Dashboard) addTxManagerPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `tx_manager_blocks_until_tx_confirmed{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `tx_manager_blocks_until_tx_confirmed{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), ), @@ -666,8 +658,8 @@ func (m *Dashboard) addHeadTrackerPanels() { axis.Unit("Block"), ), timeseries.WithPrometheusTarget( - `head_tracker_current_head{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `head_tracker_current_head{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -679,8 +671,8 @@ func (m *Dashboard) addHeadTrackerPanels() { axis.Unit("Block"), ), timeseries.WithPrometheusTarget( - `head_tracker_very_old_head{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `head_tracker_very_old_head{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -692,8 +684,8 @@ func (m *Dashboard) addHeadTrackerPanels() { axis.Unit("Block"), ), timeseries.WithPrometheusTarget( - `head_tracker_heads_received{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `head_tracker_heads_received{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -705,8 +697,8 @@ func (m *Dashboard) addHeadTrackerPanels() { axis.Unit("Block"), ), timeseries.WithPrometheusTarget( - `head_tracker_connection_errors{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `head_tracker_connection_errors{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), ), @@ -729,20 +721,20 @@ func (m *Dashboard) addDatabasePanels() { axis.Unit("Conn"), ), timeseries.WithPrometheusTarget( - `db_conns_max{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - Max"), + `db_conns_max{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - Max"), ), timeseries.WithPrometheusTarget( - `db_conns_open{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - Open"), + `db_conns_open{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - Open"), ), timeseries.WithPrometheusTarget( - `db_conns_used{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - Used"), + `db_conns_used{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - Used"), ), timeseries.WithPrometheusTarget( - `db_conns_wait{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - Wait"), + `db_conns_wait{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - Wait"), ), ), row.WithTimeSeries( @@ -754,8 +746,8 @@ func (m *Dashboard) addDatabasePanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `db_wait_count{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `db_wait_count{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -767,8 +759,8 @@ func (m *Dashboard) addDatabasePanels() { axis.Unit("Sec"), ), timeseries.WithPrometheusTarget( - `db_wait_time_seconds{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `db_wait_time_seconds{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), ), @@ -791,15 +783,15 @@ func (m *Dashboard) addSQLQueryPanels() { axis.Unit("percent"), ), timeseries.WithPrometheusTarget( - `histogram_quantile(0.9, sum(rate(sql_query_timeout_percent_bucket{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval])) by (le))`, + `histogram_quantile(0.9, sum(rate(sql_query_timeout_percent_bucket{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (le))`, prometheus.Legend("p90"), ), timeseries.WithPrometheusTarget( - `histogram_quantile(0.95, sum(rate(sql_query_timeout_percent_bucket{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval])) by (le))`, + `histogram_quantile(0.95, sum(rate(sql_query_timeout_percent_bucket{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (le))`, prometheus.Legend("p95"), ), timeseries.WithPrometheusTarget( - `histogram_quantile(0.99, sum(rate(sql_query_timeout_percent_bucket{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval])) by (le))`, + `histogram_quantile(0.99, sum(rate(sql_query_timeout_percent_bucket{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (le))`, prometheus.Legend("p99"), ), ), @@ -819,24 +811,24 @@ func (m *Dashboard) addLogsPanels() { timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `log_panic_count{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - panic"), + `log_panic_count{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - panic"), ), timeseries.WithPrometheusTarget( - `log_fatal_count{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - fatal"), + `log_fatal_count{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - fatal"), ), timeseries.WithPrometheusTarget( - `log_critical_count{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - critical"), + `log_critical_count{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - critical"), ), timeseries.WithPrometheusTarget( - `log_warn_count{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - warn"), + `log_warn_count{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - warn"), ), timeseries.WithPrometheusTarget( - `log_error_count{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - error"), + `log_error_count{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - error"), ), ), row.WithTimeSeries( @@ -845,24 +837,24 @@ func (m *Dashboard) addLogsPanels() { timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `sum(rate(log_panic_count{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval]))`, - prometheus.Legend("panic"), + `sum(rate(log_panic_count{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`)`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - panic"), ), timeseries.WithPrometheusTarget( - `sum(rate(log_fatal_count{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval]))`, - prometheus.Legend("fatal"), + `sum(rate(log_fatal_count{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`)`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - fatal"), ), timeseries.WithPrometheusTarget( - `sum(rate(log_critical_count{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval]))`, - prometheus.Legend("critical"), + `sum(rate(log_critical_count{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`)`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - critical"), ), timeseries.WithPrometheusTarget( - `sum(rate(log_warn_count{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval]))`, - prometheus.Legend("warn"), + `sum(rate(log_warn_count{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`)`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - warn"), ), timeseries.WithPrometheusTarget( - `sum(rate(log_error_count{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval]))`, - prometheus.Legend("error"), + `sum(rate(log_error_count{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`)`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - error"), ), ), ), @@ -885,8 +877,8 @@ func (m *Dashboard) addEVMPoolLifecyclePanels() { axis.Unit("Block"), ), timeseries.WithPrometheusTarget( - `evm_pool_rpc_node_highest_seen_block{`+m.panelOption.labelFilter+`=~"$instance", evmChainID="${evmChainID}"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `evm_pool_rpc_node_highest_seen_block{`+m.panelOption.labelQuery+`evmChainID="${evmChainID}"}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -898,8 +890,8 @@ func (m *Dashboard) addEVMPoolLifecyclePanels() { axis.Unit("Block"), ), timeseries.WithPrometheusTarget( - `evm_pool_rpc_node_num_seen_blocks{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `evm_pool_rpc_node_num_seen_blocks{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -911,8 +903,8 @@ func (m *Dashboard) addEVMPoolLifecyclePanels() { axis.Unit("Block"), ), timeseries.WithPrometheusTarget( - `evm_pool_rpc_node_polls_total{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `evm_pool_rpc_node_polls_total{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -924,8 +916,8 @@ func (m *Dashboard) addEVMPoolLifecyclePanels() { axis.Unit("Block"), ), timeseries.WithPrometheusTarget( - `evm_pool_rpc_node_polls_failed{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `evm_pool_rpc_node_polls_failed{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -937,8 +929,8 @@ func (m *Dashboard) addEVMPoolLifecyclePanels() { axis.Unit("Block"), ), timeseries.WithPrometheusTarget( - `evm_pool_rpc_node_polls_success{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `evm_pool_rpc_node_polls_success{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), ), @@ -954,7 +946,7 @@ func (m *Dashboard) addEVMPoolRPCNodePanels() { row.Collapse(), row.WithTimeSeries( "EVM Pool RPC Node Calls Success Rate", - timeseries.Span(7), + timeseries.Span(12), timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.Axis( @@ -964,19 +956,19 @@ func (m *Dashboard) addEVMPoolRPCNodePanels() { axis.SoftMax(100), ), timeseries.WithPrometheusTarget( - `sum(increase(evm_pool_rpc_node_calls_success{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval])) by (`+m.panelOption.labelFilter+`, evmChainID, nodeName) / sum(increase(evm_pool_rpc_node_calls_total{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval])) by (`+m.panelOption.labelFilter+`, evmChainID, nodeName) * 100`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - {{evmChainID}} - {{nodeName}}"), + `sum(increase(evm_pool_rpc_node_calls_success{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`, evmChainID, nodeName) / sum(increase(evm_pool_rpc_node_calls_total{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`, evmChainID, nodeName) * 100`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - {{evmChainID}} - {{nodeName}}"), ), ), row.WithGauge( "EVM Pool RPC Node Calls Success Rate", - gauge.Span(5), - gauge.Height("200px"), + gauge.Span(12), + gauge.Orientation(gauge.OrientationVertical), gauge.DataSource(m.PrometheusDataSourceName), gauge.Unit("percentunit"), gauge.WithPrometheusTarget( - `sum(increase(evm_pool_rpc_node_calls_success{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval])) by (`+m.panelOption.labelFilter+`, evmChainID, nodeName) / sum(increase(evm_pool_rpc_node_calls_total{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval])) by (`+m.panelOption.labelFilter+`, evmChainID, nodeName)`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - {{evmChainID}} - {{nodeName}}"), + `sum(increase(evm_pool_rpc_node_calls_success{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`, evmChainID, nodeName) / sum(increase(evm_pool_rpc_node_calls_total{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`, evmChainID, nodeName)`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - {{evmChainID}} - {{nodeName}}"), ), gauge.AbsoluteThresholds([]gauge.ThresholdStep{ {Color: "#ff0000"}, @@ -997,8 +989,8 @@ func (m *Dashboard) addEVMPoolRPCNodePanels() { axis.SoftMax(100), ), timeseries.WithPrometheusTarget( - `sum(increase(evm_pool_rpc_node_dials_success{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval])) by (`+m.panelOption.labelFilter+`, evmChainID, nodeName) / sum(increase(evm_pool_rpc_node_dials_total{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval])) by (`+m.panelOption.labelFilter+`, evmChainID, nodeName) * 100`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - {{evmChainID}} - {{nodeName}}"), + `sum(increase(evm_pool_rpc_node_dials_success{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`, evmChainID, nodeName) / sum(increase(evm_pool_rpc_node_dials_total{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`, evmChainID, nodeName) * 100`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - {{evmChainID}} - {{nodeName}}"), ), ), // issue when value is 0 @@ -1014,8 +1006,8 @@ func (m *Dashboard) addEVMPoolRPCNodePanels() { axis.SoftMax(100), ), timeseries.WithPrometheusTarget( - `sum(increase(evm_pool_rpc_node_dials_failed{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval])) by (`+m.panelOption.labelFilter+`, evmChainID, nodeName) / sum(increase(evm_pool_rpc_node_dials_total{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval])) by (`+m.panelOption.labelFilter+`, evmChainID, nodeName) * 100`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - {{evmChainID}} - {{nodeName}}"), + `sum(increase(evm_pool_rpc_node_dials_failed{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`, evmChainID, nodeName) / sum(increase(evm_pool_rpc_node_dials_total{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`, evmChainID, nodeName) * 100`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - {{evmChainID}} - {{nodeName}}"), ), ), row.WithTimeSeries( @@ -1027,27 +1019,27 @@ func (m *Dashboard) addEVMPoolRPCNodePanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `evm_pool_rpc_node_num_transitions_to_alive{`+m.panelOption.labelFilter+`=~"$instance"}`, + `evm_pool_rpc_node_num_transitions_to_alive{`+m.panelOption.labelQuery+`}`, prometheus.Legend(""), ), timeseries.WithPrometheusTarget( - `evm_pool_rpc_node_num_transitions_to_in_sync{`+m.panelOption.labelFilter+`=~"$instance"}`, + `evm_pool_rpc_node_num_transitions_to_in_sync{`+m.panelOption.labelQuery+`}`, prometheus.Legend(""), ), timeseries.WithPrometheusTarget( - `evm_pool_rpc_node_num_transitions_to_out_of_sync{`+m.panelOption.labelFilter+`=~"$instance"}`, + `evm_pool_rpc_node_num_transitions_to_out_of_sync{`+m.panelOption.labelQuery+`}`, prometheus.Legend(""), ), timeseries.WithPrometheusTarget( - `evm_pool_rpc_node_num_transitions_to_unreachable{`+m.panelOption.labelFilter+`=~"$instance"}`, + `evm_pool_rpc_node_num_transitions_to_unreachable{`+m.panelOption.labelQuery+`}`, prometheus.Legend(""), ), timeseries.WithPrometheusTarget( - `evm_pool_rpc_node_num_transitions_to_invalid_chain_id{`+m.panelOption.labelFilter+`=~"$instance"}`, + `evm_pool_rpc_node_num_transitions_to_invalid_chain_id{`+m.panelOption.labelQuery+`}`, prometheus.Legend(""), ), timeseries.WithPrometheusTarget( - `evm_pool_rpc_node_num_transitions_to_unusable{`+m.panelOption.labelFilter+`=~"$instance"}`, + `evm_pool_rpc_node_num_transitions_to_unusable{`+m.panelOption.labelQuery+`}`, prometheus.Legend(""), ), ), @@ -1060,8 +1052,8 @@ func (m *Dashboard) addEVMPoolRPCNodePanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `evm_pool_rpc_node_states{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - {{evmChainID}} - {{state}}"), + `evm_pool_rpc_node_states{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - {{evmChainID}} - {{state}}"), ), ), row.WithTimeSeries( @@ -1076,8 +1068,8 @@ func (m *Dashboard) addEVMPoolRPCNodePanels() { axis.SoftMax(100), ), timeseries.WithPrometheusTarget( - `sum(increase(evm_pool_rpc_node_verifies_success{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval])) by (`+m.panelOption.labelFilter+`, evmChainID, nodeName) / sum(increase(evm_pool_rpc_node_verifies{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval])) by (`+m.panelOption.labelFilter+`, evmChainID, nodeName) * 100`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - {{evmChainID}} - {{nodeName}}"), + `sum(increase(evm_pool_rpc_node_verifies_success{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`, evmChainID, nodeName) / sum(increase(evm_pool_rpc_node_verifies{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`, evmChainID, nodeName) * 100`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - {{evmChainID}} - {{nodeName}}"), ), ), row.WithTimeSeries( @@ -1092,8 +1084,8 @@ func (m *Dashboard) addEVMPoolRPCNodePanels() { axis.SoftMax(100), ), timeseries.WithPrometheusTarget( - `sum(increase(evm_pool_rpc_node_verifies_failed{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval])) by (`+m.panelOption.labelFilter+`, evmChainID, nodeName) / sum(increase(evm_pool_rpc_node_verifies{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval])) by (`+m.panelOption.labelFilter+`, evmChainID, nodeName) * 100`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - {{evmChainID}} - {{nodeName}}"), + `sum(increase(evm_pool_rpc_node_verifies_failed{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`, evmChainID, nodeName) / sum(increase(evm_pool_rpc_node_verifies{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`, evmChainID, nodeName) * 100`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - {{evmChainID}} - {{nodeName}}"), ), ), ), @@ -1107,17 +1099,43 @@ func (m *Dashboard) addEVMRPCNodeLatenciesPanels() { dashboard.Row( "EVM Pool RPC Node Latencies (App)", row.Collapse(), + row.WithTimeSeries( + "EVM Pool RPC Node Calls Latency 0.90 quantile", + timeseries.Span(12), + timeseries.Height("200px"), + timeseries.DataSource(m.PrometheusDataSourceName), + timeseries.Axis( + axis.Unit("ms"), + ), + timeseries.WithPrometheusTarget( + `histogram_quantile(0.90, sum(rate(evm_pool_rpc_node_rpc_call_time_bucket{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`, le, rpcCallName)) / 1e6`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - {{rpcCallName}}"), + ), + ), row.WithTimeSeries( "EVM Pool RPC Node Calls Latency 0.95 quantile", - timeseries.Span(6), + timeseries.Span(12), timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.Axis( axis.Unit("ms"), ), timeseries.WithPrometheusTarget( - `histogram_quantile(0.95, sum(rate(evm_pool_rpc_node_rpc_call_time_bucket{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval])) by (le, rpcCallName)) / 1e6`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `histogram_quantile(0.95, sum(rate(evm_pool_rpc_node_rpc_call_time_bucket{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`, le, rpcCallName)) / 1e6`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - {{rpcCallName}}"), + ), + ), + row.WithTimeSeries( + "EVM Pool RPC Node Calls Latency 0.99 quantile", + timeseries.Span(12), + timeseries.Height("200px"), + timeseries.DataSource(m.PrometheusDataSourceName), + timeseries.Axis( + axis.Unit("ms"), + ), + timeseries.WithPrometheusTarget( + `histogram_quantile(0.99, sum(rate(evm_pool_rpc_node_rpc_call_time_bucket{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`, le, rpcCallName)) / 1e6`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - {{rpcCallName}}"), ), ), ), @@ -1139,8 +1157,8 @@ func (m *Dashboard) addBlockHistoryEstimatorPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `gas_updater_all_gas_price_percentiles{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - {{ percentile }}"), + `gas_updater_all_gas_price_percentiles{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - {{ percentile }}"), ), ), row.WithTimeSeries( @@ -1152,8 +1170,8 @@ func (m *Dashboard) addBlockHistoryEstimatorPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `gas_updater_all_tip_cap_percentiles{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - {{ percentile }}"), + `gas_updater_all_tip_cap_percentiles{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - {{ percentile }}"), ), ), row.WithTimeSeries( @@ -1165,8 +1183,8 @@ func (m *Dashboard) addBlockHistoryEstimatorPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `gas_updater_set_gas_price{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `gas_updater_set_gas_price{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -1178,8 +1196,8 @@ func (m *Dashboard) addBlockHistoryEstimatorPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `gas_updater_set_tip_cap{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `gas_updater_set_tip_cap{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -1191,8 +1209,8 @@ func (m *Dashboard) addBlockHistoryEstimatorPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `gas_updater_current_base_fee{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `gas_updater_current_base_fee{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -1204,8 +1222,8 @@ func (m *Dashboard) addBlockHistoryEstimatorPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `block_history_estimator_connectivity_failure_count{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `block_history_estimator_connectivity_failure_count{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), ), @@ -1227,8 +1245,8 @@ func (m *Dashboard) addPipelinePanels() { axis.Unit("Sec"), ), timeseries.WithPrometheusTarget( - `pipeline_task_execution_time{`+m.panelOption.labelFilter+`=~"$instance"} / 1e6`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} JobID: {{ job_id }}"), + `pipeline_task_execution_time{`+m.panelOption.labelQuery+`} / 1e6`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} JobID: {{ job_id }}"), ), ), row.WithTimeSeries( @@ -1240,8 +1258,8 @@ func (m *Dashboard) addPipelinePanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `pipeline_run_errors{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} JobID: {{ job_id }}"), + `pipeline_run_errors{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} JobID: {{ job_id }}"), ), ), row.WithTimeSeries( @@ -1253,8 +1271,8 @@ func (m *Dashboard) addPipelinePanels() { axis.Unit("Sec"), ), timeseries.WithPrometheusTarget( - `pipeline_run_total_time_to_completion{`+m.panelOption.labelFilter+`=~"$instance"} / 1e6`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} JobID: {{ job_id }}"), + `pipeline_run_total_time_to_completion{`+m.panelOption.labelQuery+`} / 1e6`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} JobID: {{ job_id }}"), ), ), row.WithTimeSeries( @@ -1266,8 +1284,8 @@ func (m *Dashboard) addPipelinePanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `pipeline_tasks_total_finished{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} JobID: {{ job_id }}"), + `pipeline_tasks_total_finished{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} JobID: {{ job_id }}"), ), ), ), @@ -1283,8 +1301,8 @@ func (m *Dashboard) addPipelinePanels() { axis.Unit("Sec"), ), timeseries.WithPrometheusTarget( - `pipeline_task_eth_call_execution_time{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `pipeline_task_eth_call_execution_time{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), ), @@ -1300,8 +1318,8 @@ func (m *Dashboard) addPipelinePanels() { axis.Unit("Sec"), ), timeseries.WithPrometheusTarget( - `pipeline_task_http_fetch_time{`+m.panelOption.labelFilter+`=~"$instance"} / 1e6`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `pipeline_task_http_fetch_time{`+m.panelOption.labelQuery+`} / 1e6`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -1313,8 +1331,8 @@ func (m *Dashboard) addPipelinePanels() { axis.Unit("Bytes"), ), timeseries.WithPrometheusTarget( - `pipeline_task_http_response_body_size{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `pipeline_task_http_response_body_size{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), ), @@ -1330,8 +1348,8 @@ func (m *Dashboard) addPipelinePanels() { axis.Unit("Sec"), ), timeseries.WithPrometheusTarget( - `bridge_latency_seconds{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `bridge_latency_seconds{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -1343,8 +1361,8 @@ func (m *Dashboard) addPipelinePanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `bridge_errors_total{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `bridge_errors_total{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -1356,8 +1374,8 @@ func (m *Dashboard) addPipelinePanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `bridge_cache_hits_total{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `bridge_cache_hits_total{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -1369,8 +1387,8 @@ func (m *Dashboard) addPipelinePanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `bridge_cache_errors_total{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `bridge_cache_errors_total{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), ), @@ -1386,8 +1404,8 @@ func (m *Dashboard) addPipelinePanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `pipeline_runs_queued{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `pipeline_runs_queued{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -1399,8 +1417,8 @@ func (m *Dashboard) addPipelinePanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `pipeline_task_runs_queued{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `pipeline_task_runs_queued{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), ), @@ -1424,8 +1442,8 @@ func (m *Dashboard) addHTTPAPIPanels() { axis.Unit("Sec"), ), timeseries.WithPrometheusTarget( - `histogram_quantile(0.95, sum(rate(service_gonic_request_duration_bucket{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval])) by (le, path, method))`, - prometheus.Legend("{{ method }} {{ path }}"), + `histogram_quantile(0.95, sum(rate(service_gonic_request_duration_bucket{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`, le, path, method))`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - {{ method }} - {{ path }}"), ), ), row.WithTimeSeries( @@ -1437,12 +1455,12 @@ func (m *Dashboard) addHTTPAPIPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `sum(rate(service_gonic_requests_total{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval])) by (path, method, code)`, - prometheus.Legend("{{ method }} {{ path }} {{ code }}"), + `sum(rate(service_gonic_requests_total{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`, path, method, code)`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - {{ method }} - {{ path }} - {{ code }}"), ), ), row.WithTimeSeries( - "Request Size", + "Average Request Size", timeseries.Span(6), timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), @@ -1450,8 +1468,8 @@ func (m *Dashboard) addHTTPAPIPanels() { axis.Unit("Bytes"), ), timeseries.WithPrometheusTarget( - `avg(rate(service_gonic_request_size_bytes_sum{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval]))/avg(rate(service_gonic_request_size_bytes_count{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval]))`, - prometheus.Legend("Average"), + `avg(rate(service_gonic_request_size_bytes_sum{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`)/avg(rate(service_gonic_request_size_bytes_count{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`)`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( @@ -1463,8 +1481,8 @@ func (m *Dashboard) addHTTPAPIPanels() { axis.Unit("Bytes"), ), timeseries.WithPrometheusTarget( - `avg(rate(service_gonic_response_size_bytes_sum{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval]))/avg(rate(service_gonic_response_size_bytes_count{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval]))`, - prometheus.Legend("Average"), + `avg(rate(service_gonic_response_size_bytes_sum{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`)/avg(rate(service_gonic_response_size_bytes_count{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`)`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), ), @@ -1479,25 +1497,25 @@ func (m *Dashboard) addPromHTTPPanels() { "PromHTTP Metrics", row.Collapse(), row.WithGauge("HTTP Request in flight", - gauge.Span(2), - gauge.Height("200px"), + gauge.Span(12), + gauge.Orientation(gauge.OrientationVertical), gauge.DataSource(m.PrometheusDataSourceName), gauge.WithPrometheusTarget( - `promhttp_metric_handler_requests_in_flight`, - prometheus.Legend(""), + `promhttp_metric_handler_requests_in_flight{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), row.WithTimeSeries( "HTTP rate", - timeseries.Span(10), + timeseries.Span(12), timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.Axis( axis.Unit(""), ), timeseries.WithPrometheusTarget( - `sum(rate(promhttp_metric_handler_requests_total{`+m.panelOption.labelFilter+`=~"$instance"}[$__rate_interval])) by (code)`, - prometheus.Legend("{{ code }}"), + `sum(rate(promhttp_metric_handler_requests_total{`+m.panelOption.labelQuery+`}[$__rate_interval])) by (`+m.panelOption.legendString+`, code)`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), ), ), @@ -1517,8 +1535,8 @@ func (m *Dashboard) addGoMetricsPanels() { table.Height("200px"), table.DataSource(m.PrometheusDataSourceName), table.WithPrometheusTarget( - `sum(go_threads{`+m.panelOption.labelFilter+`=~"$instance"}) by (instance)`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}")), + `sum(go_threads{`+m.panelOption.labelQuery+`}) by (`+m.panelOption.legendString+`)`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}")), table.HideColumn("Time"), table.AsTimeSeriesAggregations([]table.Aggregation{ {Label: "AVG", Type: table.AVG}, @@ -1534,18 +1552,29 @@ func (m *Dashboard) addGoMetricsPanels() { axis.Unit(""), ), timeseries.WithPrometheusTarget( - `sum(go_threads{`+m.panelOption.labelFilter+`=~"$instance"}) by (instance)`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `sum(go_threads{`+m.panelOption.labelQuery+`}) by (`+m.panelOption.legendString+`)`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), + ), + ), + row.WithStat( + "Heap Allocations", + stat.Span(12), + stat.Orientation(stat.OrientationVertical), + stat.DataSource(m.PrometheusDataSourceName), + stat.Unit("bytes"), + stat.ColorValue(), + stat.WithPrometheusTarget( + `sum(go_memstats_heap_alloc_bytes{`+m.panelOption.labelQuery+`}) by (`+m.panelOption.legendString+`)`, ), ), row.WithTimeSeries( "Heap allocations", - timeseries.Span(6), + timeseries.Span(12), timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `sum(go_memstats_heap_alloc_bytes{`+m.panelOption.labelFilter+`=~"$instance"}) by (instance)`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `sum(go_memstats_heap_alloc_bytes{`+m.panelOption.labelQuery+`}) by (`+m.panelOption.legendString+`)`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), timeseries.Axis( axis.Unit("bytes"), @@ -1553,29 +1582,6 @@ func (m *Dashboard) addGoMetricsPanels() { axis.SoftMin(0), ), ), - row.WithStat( - "Heap Allocations", - stat.Span(6), - stat.Height("200px"), - stat.DataSource(m.PrometheusDataSourceName), - stat.Unit("bytes"), - stat.ColorValue(), - stat.WithPrometheusTarget(`sum(go_memstats_heap_alloc_bytes{`+m.panelOption.labelFilter+`=~"$instance"})`), - /*stat.AbsoluteThresholds([]stat.ThresholdStep{ - { - Color: "green", - Value: nil, - }, - { - Color: "orange", - Value: float64Ptr(6.711e+7), - }, - { - Color: "red", - Value: float64Ptr(1.342e+8), - }, - }),*/ - ), row.WithTimeSeries( "Memory in Heap", timeseries.Span(6), @@ -1587,24 +1593,24 @@ func (m *Dashboard) addGoMetricsPanels() { axis.SoftMin(0), ), timeseries.WithPrometheusTarget( - `go_memstats_heap_alloc_bytes{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - Alloc"), + `go_memstats_heap_alloc_bytes{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - Alloc"), ), timeseries.WithPrometheusTarget( - `go_memstats_heap_sys_bytes{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - Sys"), + `go_memstats_heap_sys_bytes{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - Sys"), ), timeseries.WithPrometheusTarget( - `go_memstats_heap_idle_bytes{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - Idle"), + `go_memstats_heap_idle_bytes{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - Idle"), ), timeseries.WithPrometheusTarget( - `go_memstats_heap_inuse_bytes{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - InUse"), + `go_memstats_heap_inuse_bytes{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - InUse"), ), timeseries.WithPrometheusTarget( - `go_memstats_heap_released_bytes{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - Released"), + `go_memstats_heap_released_bytes{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - Released"), ), ), row.WithTimeSeries( @@ -1618,36 +1624,36 @@ func (m *Dashboard) addGoMetricsPanels() { axis.SoftMin(0), ), timeseries.WithPrometheusTarget( - `go_memstats_mspan_inuse_bytes{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - Total InUse"), + `go_memstats_mspan_inuse_bytes{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - Total InUse"), ), timeseries.WithPrometheusTarget( - `go_memstats_mspan_sys_bytes{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - Total Sys"), + `go_memstats_mspan_sys_bytes{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - Total Sys"), ), timeseries.WithPrometheusTarget( - `go_memstats_mcache_inuse_bytes{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - Cache InUse"), + `go_memstats_mcache_inuse_bytes{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - Cache InUse"), ), timeseries.WithPrometheusTarget( - `go_memstats_mcache_sys_bytes{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - Cache Sys"), + `go_memstats_mcache_sys_bytes{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - Cache Sys"), ), timeseries.WithPrometheusTarget( - `go_memstats_buck_hash_sys_bytes{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - Hash Sys"), + `go_memstats_buck_hash_sys_bytes{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - Hash Sys"), ), timeseries.WithPrometheusTarget( - `go_memstats_gc_sys_bytes{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - GC Sys"), + `go_memstats_gc_sys_bytes{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - GC Sys"), ), timeseries.WithPrometheusTarget( - `go_memstats_other_sys_bytes{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - bytes of memory are used for other runtime allocations"), + `go_memstats_other_sys_bytes{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - bytes of memory are used for other runtime allocations"), ), timeseries.WithPrometheusTarget( - `go_memstats_next_gc_bytes{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - Next GC"), + `go_memstats_next_gc_bytes{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - Next GC"), ), ), row.WithTimeSeries( @@ -1656,12 +1662,12 @@ func (m *Dashboard) addGoMetricsPanels() { timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `go_memstats_stack_inuse_bytes{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - InUse"), + `go_memstats_stack_inuse_bytes{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - InUse"), ), timeseries.WithPrometheusTarget( - `go_memstats_stack_sys_bytes{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}} - Sys"), + `go_memstats_stack_sys_bytes{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}} - Sys"), ), timeseries.Axis( axis.Unit("bytes"), @@ -1675,8 +1681,8 @@ func (m *Dashboard) addGoMetricsPanels() { timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `go_memstats_sys_bytes{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `go_memstats_sys_bytes{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), timeseries.Axis( axis.Unit("bytes"), @@ -1690,8 +1696,8 @@ func (m *Dashboard) addGoMetricsPanels() { timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `go_memstats_mallocs_total{`+m.panelOption.labelFilter+`=~"$instance"} - go_memstats_frees_total{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `go_memstats_mallocs_total{`+m.panelOption.labelQuery+`} - go_memstats_frees_total{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), timeseries.Axis( axis.SoftMin(0), @@ -1703,8 +1709,8 @@ func (m *Dashboard) addGoMetricsPanels() { timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `rate(go_memstats_mallocs_total{`+m.panelOption.labelFilter+`=~"$instance"}[1m])`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `rate(go_memstats_mallocs_total{`+m.panelOption.labelQuery+`}[1m])`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), timeseries.Axis( axis.SoftMin(0), @@ -1716,8 +1722,8 @@ func (m *Dashboard) addGoMetricsPanels() { timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `rate(go_memstats_lookups_total{`+m.panelOption.labelFilter+`=~"$instance"}[1m])`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `rate(go_memstats_lookups_total{`+m.panelOption.labelQuery+`}[1m])`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), timeseries.Axis( axis.Unit("ops"), @@ -1730,8 +1736,8 @@ func (m *Dashboard) addGoMetricsPanels() { timeseries.Height("200px"), timeseries.DataSource(m.PrometheusDataSourceName), timeseries.WithPrometheusTarget( - `go_goroutines{`+m.panelOption.labelFilter+`=~"$instance"}`, - prometheus.Legend("{{"+m.panelOption.labelFilter+"}}"), + `go_goroutines{`+m.panelOption.labelQuery+`}`, + prometheus.Legend("{{"+m.panelOption.legendString+"}}"), ), timeseries.Axis( axis.SoftMin(0), From 1598a6b31336515a14fa6dfad6369655a5e5b6af Mon Sep 17 00:00:00 2001 From: Damjan Smickovski <32773226+smickovskid@users.noreply.github.com> Date: Fri, 1 Mar 2024 21:54:46 +0100 Subject: [PATCH 03/34] Added Gnosis Chiado to benchmark tests (#11869) * Added Gnosis Chiado to benchmark tests * Added Gnosis Chiado to benchmark tests * Added Gnosis Chiado to benchmark tests * fix * set readOnlyAddress for gnosis * add default network config in benchmark test * clean mode selection * run lint --------- Co-authored-by: anirudhwarrier <12178754+anirudhwarrier@users.noreply.github.com> --- integration-tests/benchmark/keeper_test.go | 13 +++++++++- .../contracts/contract_deployer.go | 25 +++++++++---------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/integration-tests/benchmark/keeper_test.go b/integration-tests/benchmark/keeper_test.go index 5ca52d26a9e..d6c4c6b2587 100644 --- a/integration-tests/benchmark/keeper_test.go +++ b/integration-tests/benchmark/keeper_test.go @@ -120,6 +120,12 @@ type NetworkConfig struct { funding *big.Float } +var defaultNetworkConfig = NetworkConfig{ + upkeepSLA: int64(120), + blockTime: time.Second, + deltaStage: time.Duration(0), +} + func TestAutomationBenchmark(t *testing.T) { l := logging.GetTestLogger(t) testType, err := tc.GetConfigurationNameFromEnv() @@ -237,7 +243,7 @@ func getNetworkConfig(networkName string, config *tc.TestConfig) NetworkConfig { var nc NetworkConfig var ok bool if nc, ok = networkConfig[networkName]; !ok { - return NetworkConfig{} + return defaultNetworkConfig } if networkName == "SimulatedGeth" || networkName == "geth" { @@ -302,6 +308,11 @@ var networkConfig = map[string]NetworkConfig{ blockTime: time.Second, deltaStage: 20 * time.Second, }, + "GnosisChiado": { + upkeepSLA: int64(120), + blockTime: 6 * time.Second, + deltaStage: 20 * time.Second, + }, } func SetupAutomationBenchmarkEnv(t *testing.T, keeperTestConfig types.KeeperBenchmarkTestConfig) (*environment.Environment, blockchain.EVMNetwork) { diff --git a/integration-tests/contracts/contract_deployer.go b/integration-tests/contracts/contract_deployer.go index 78ec0c18c64..1cf2a6bede2 100644 --- a/integration-tests/contracts/contract_deployer.go +++ b/integration-tests/contracts/contract_deployer.go @@ -8,6 +8,8 @@ import ( "strings" "time" + "github.com/smartcontractkit/chainlink-testing-framework/networks" + "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" @@ -956,18 +958,13 @@ func (e *EthereumContractDeployer) DeployKeeperRegistry( var mode uint8 switch e.client.GetChainID().Int64() { //Arbitrum payment model - //Goerli Arbitrum - case 421613: - mode = uint8(1) - //Sepolia Arbitrum - case 421614: + case networks.ArbitrumMainnet.ChainID, networks.ArbitrumSepolia.ChainID: mode = uint8(1) //Optimism payment model - //Goerli Optimism - case 420: + case networks.OptimismMainnet.ChainID, networks.OptimismSepolia.ChainID: mode = uint8(2) - //Goerli Base - case 84531: + //Base + case networks.BaseMainnet.ChainID, networks.BaseSepolia.ChainID: mode = uint8(2) default: mode = uint8(0) @@ -1227,21 +1224,21 @@ func (e *EthereumContractDeployer) DeployKeeperRegistry( var err error chainId := e.client.GetChainID().Int64() - if chainId == 534352 || chainId == 534351 { // Scroll / Scroll Sepolia + if chainId == networks.ScrollMainnet.ChainID || chainId == networks.ScrollSepolia.ChainID { chainModuleAddr, _, _, err = e.client.DeployContract("ScrollModule", func( auth *bind.TransactOpts, backend bind.ContractBackend, ) (common.Address, *types.Transaction, interface{}, error) { return scroll_module.DeployScrollModule(auth, backend) }) - } else if chainId == 42161 || chainId == 421614 || chainId == 421613 { // Arbitrum One / Sepolia / Goerli + } else if chainId == networks.ArbitrumMainnet.ChainID || chainId == networks.ArbitrumSepolia.ChainID { chainModuleAddr, _, _, err = e.client.DeployContract("ArbitrumModule", func( auth *bind.TransactOpts, backend bind.ContractBackend, ) (common.Address, *types.Transaction, interface{}, error) { return arbitrum_module.DeployArbitrumModule(auth, backend) }) - } else if chainId == 10 || chainId == 11155420 { // Optimism / Optimism Sepolia + } else if chainId == networks.OptimismMainnet.ChainID || chainId == networks.OptimismSepolia.ChainID { chainModuleAddr, _, _, err = e.client.DeployContract("OptimismModule", func( auth *bind.TransactOpts, backend bind.ContractBackend, @@ -1269,8 +1266,10 @@ func (e *EthereumContractDeployer) DeployKeeperRegistry( } var allowedReadOnlyAddress common.Address - if chainId == 1101 || chainId == 1442 || chainId == 2442 { + if chainId == networks.PolygonZkEvmMainnet.ChainID || chainId == networks.PolygonZkEvmCardona.ChainID { allowedReadOnlyAddress = common.HexToAddress("0x1111111111111111111111111111111111111111") + } else if chainId == networks.GnosisMainnet.ChainID || chainId == networks.GnosisChiado.ChainID { + allowedReadOnlyAddress = common.HexToAddress("0xfffffffffffffffffffffffffffffffffffffffe") } else { allowedReadOnlyAddress = common.HexToAddress("0x0000000000000000000000000000000000000000") } From c4af75e41a9a21fe5b0090a5552998426a942939 Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Mon, 4 Mar 2024 15:50:10 +0100 Subject: [PATCH 04/34] fix wasp dashboard and bump the dep (#12273) --- .../load/functions/functionscmd/dashboard.go | 4 ++-- integration-tests/load/go.mod | 5 +++-- integration-tests/load/go.sum | 16 +++++++++++----- .../load/vrfv2/vrfv2cmd/dashboard.go | 5 +++-- .../load/vrfv2plus/vrfv2pluscmd/dashboard.go | 5 +++-- .../load/zcluster/cluster_entrypoint_test.go | 8 +++----- 6 files changed, 25 insertions(+), 18 deletions(-) diff --git a/integration-tests/load/functions/functionscmd/dashboard.go b/integration-tests/load/functions/functionscmd/dashboard.go index 6414759e672..ccf56740236 100644 --- a/integration-tests/load/functions/functionscmd/dashboard.go +++ b/integration-tests/load/functions/functionscmd/dashboard.go @@ -4,12 +4,12 @@ import ( "github.com/K-Phoen/grabana/dashboard" "github.com/K-Phoen/grabana/logs" "github.com/K-Phoen/grabana/row" - "github.com/smartcontractkit/wasp" + db "github.com/smartcontractkit/wasp/dashboard" ) func main() { lokiDS := "grafanacloud-logs" - d, err := wasp.NewDashboard(nil, + d, err := db.NewDashboard(nil, []dashboard.Option{ dashboard.Row("DON logs (errors)", row.Collapse(), diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index d538469eb66..6fbcc8ff43b 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -10,7 +10,7 @@ replace github.com/smartcontractkit/chainlink/integration-tests => ../ require ( github.com/K-Phoen/grabana v0.22.1 github.com/ethereum/go-ethereum v1.13.8 - github.com/go-resty/resty/v2 v2.7.0 + github.com/go-resty/resty/v2 v2.11.0 github.com/pelletier/go-toml/v2 v2.1.1 github.com/rs/zerolog v1.30.0 github.com/slack-go/slack v0.12.2 @@ -22,7 +22,7 @@ require ( github.com/smartcontractkit/libocr v0.0.0-20240229181116-bfb2432a7a66 github.com/smartcontractkit/seth v0.1.2 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 - github.com/smartcontractkit/wasp v0.4.5 + github.com/smartcontractkit/wasp v0.4.6 github.com/stretchr/testify v1.8.4 go.uber.org/ratelimit v0.3.0 ) @@ -367,6 +367,7 @@ require ( github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 // indirect + github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240227164431-18a7065e23ea // indirect github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/wsrpc v0.7.2 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 9dc04e2567f..c179a284377 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -632,8 +632,8 @@ github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7N github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= -github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= -github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= +github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8= +github.com/go-resty/resty/v2 v2.11.0/go.mod h1:iiP/OpA0CkcL3IGt1O0+/SIItFUbkkyw5BGXiVdTu+A= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= @@ -1513,6 +1513,8 @@ github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.202402 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0/go.mod h1:SZ899lZYQ0maUulWbZg+SWqabHQ1wTbyk3jT8wJfyo8= github.com/smartcontractkit/chainlink-testing-framework v1.25.0 h1:Thc9TEKH1O6rkHvl2L+Y8s4WuulSfjLsIy0XwaJ6HZE= github.com/smartcontractkit/chainlink-testing-framework v1.25.0/go.mod h1:gkmsafC85u6hIqWbxKjynKf4NuFuFJDRcgxIEFsSq6E= +github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240227164431-18a7065e23ea h1:ZdLmNAfKRjH8AYUvjiiDGUgiWQfq/7iNpxyTkvjx/ko= +github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240227164431-18a7065e23ea/go.mod h1:gCKC9w6XpNk6jm+XIk2psrkkfxhi421N9NSiFceXW88= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs= github.com/smartcontractkit/go-plugin v0.0.0-20231003134350-e49dad63b306 h1:ko88+ZznniNJZbZPWAvHQU8SwKAdHngdDZ+pvVgB5ss= @@ -1527,8 +1529,8 @@ github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235- github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw= -github.com/smartcontractkit/wasp v0.4.5 h1:pgiXwBci2m15eo33AzspzhpNG/gxg+8QGxl+I5LpfsQ= -github.com/smartcontractkit/wasp v0.4.5/go.mod h1:eVhBVLbVv0qORUlN7aR5C4aTN/lTYO3KnN1erO4ROOI= +github.com/smartcontractkit/wasp v0.4.6 h1:s6J8HgpxMHORl19nCpZPxc5jaVUQv8EXB6QjTuLXXnw= +github.com/smartcontractkit/wasp v0.4.6/go.mod h1:+ViWdUf1ap6powiEiwPskpZfH/Q1sG29YoVav7zGOIo= github.com/smartcontractkit/wsrpc v0.7.2 h1:iBXzMeg7vc5YoezIQBq896y25BARw7OKbhrb6vPbtRQ= github.com/smartcontractkit/wsrpc v0.7.2/go.mod h1:sj7QX2NQibhkhxTfs3KOhAj/5xwgqMipTvJVSssT9i0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -1829,6 +1831,7 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1928,7 +1931,6 @@ golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -1937,6 +1939,7 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -2067,6 +2070,7 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= @@ -2079,6 +2083,7 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2101,6 +2106,7 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/integration-tests/load/vrfv2/vrfv2cmd/dashboard.go b/integration-tests/load/vrfv2/vrfv2cmd/dashboard.go index 2536b4caed2..e80d7516fd4 100644 --- a/integration-tests/load/vrfv2/vrfv2cmd/dashboard.go +++ b/integration-tests/load/vrfv2/vrfv2cmd/dashboard.go @@ -3,19 +3,20 @@ package main import ( "os" + db "github.com/smartcontractkit/wasp/dashboard" + "github.com/K-Phoen/grabana/dashboard" "github.com/K-Phoen/grabana/logs" "github.com/K-Phoen/grabana/row" "github.com/K-Phoen/grabana/target/prometheus" "github.com/K-Phoen/grabana/timeseries" "github.com/K-Phoen/grabana/timeseries/axis" - "github.com/smartcontractkit/wasp" ) func main() { //TODO switch to TOML too? lokiDS := os.Getenv("DATA_SOURCE_NAME") - d, err := wasp.NewDashboard(nil, + d, err := db.NewDashboard(nil, []dashboard.Option{ dashboard.Row("LoadContractMetrics", row.WithTimeSeries( diff --git a/integration-tests/load/vrfv2plus/vrfv2pluscmd/dashboard.go b/integration-tests/load/vrfv2plus/vrfv2pluscmd/dashboard.go index 2be0e265041..75853e7e211 100644 --- a/integration-tests/load/vrfv2plus/vrfv2pluscmd/dashboard.go +++ b/integration-tests/load/vrfv2plus/vrfv2pluscmd/dashboard.go @@ -3,19 +3,20 @@ package main import ( "os" + db "github.com/smartcontractkit/wasp/dashboard" + "github.com/K-Phoen/grabana/dashboard" "github.com/K-Phoen/grabana/logs" "github.com/K-Phoen/grabana/row" "github.com/K-Phoen/grabana/target/prometheus" "github.com/K-Phoen/grabana/timeseries" "github.com/K-Phoen/grabana/timeseries/axis" - "github.com/smartcontractkit/wasp" ) func main() { //TODO switch to TOML too? lokiDS := os.Getenv("DATA_SOURCE_NAME") - d, err := wasp.NewDashboard(nil, + d, err := db.NewDashboard(nil, []dashboard.Option{ dashboard.Row("LoadContractMetrics", row.WithTimeSeries( diff --git a/integration-tests/load/zcluster/cluster_entrypoint_test.go b/integration-tests/load/zcluster/cluster_entrypoint_test.go index e5e8496af8b..35b3ee422ca 100644 --- a/integration-tests/load/zcluster/cluster_entrypoint_test.go +++ b/integration-tests/load/zcluster/cluster_entrypoint_test.go @@ -14,15 +14,13 @@ func TestClusterEntrypoint(t *testing.T) { require.NoError(t, err) cfgBase64, err := config.AsBase64() require.NoError(t, err) - p, err := wasp.NewClusterProfile(&wasp.ClusterConfig{ // you set up these only once, no need to configure through TOML DockerCmdExecPath: "../../..", BuildCtxPath: "integration-tests/load", - - Namespace: *config.WaspConfig.Namespace, - KeepJobs: config.WaspConfig.KeepJobs, - UpdateImage: config.WaspConfig.UpdateImage, + Namespace: *config.WaspConfig.Namespace, + KeepJobs: config.WaspConfig.KeepJobs, + UpdateImage: config.WaspConfig.UpdateImage, HelmValues: map[string]string{ "env.loki.url": *config.Logging.Loki.Endpoint, "env.loki.tenant_id": *config.Logging.Loki.TenantId, From d7c05c43405c59c28e3ac18b4e7bcf104d4e0e12 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Mon, 4 Mar 2024 10:44:15 -0500 Subject: [PATCH 05/34] [TT-877] Add Live VRF Tests Workflow (#12263) * Make Live Testnet Tests More Configurable * Cleaner if * Fix typo * Whater, let's try * Scale Back Ambitions * Add new VRF Action --- .github/workflows/live-testnet-tests.yml | 44 +++++- .github/workflows/live-vrf-tests.yml | 191 +++++++++++++++++++++++ 2 files changed, 229 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/live-vrf-tests.yml diff --git a/.github/workflows/live-testnet-tests.yml b/.github/workflows/live-testnet-tests.yml index b5b47382d72..be5944ba1a1 100644 --- a/.github/workflows/live-testnet-tests.yml +++ b/.github/workflows/live-testnet-tests.yml @@ -9,12 +9,34 @@ name: Live Testnet Tests on: - schedule: - - cron: "0 5 * * *" # Run every night at midnight EST - push: - tags: - - "*" + # Disable refular runs for now until we can fix some test client flakiness and improve stability + # schedule: + # - cron: "0 5 * * *" # Run every night at midnight EST + # push: + # tags: + # - "*" workflow_dispatch: + inputs: + slack_user_id: + description: "The Slack member ID to notify" + required: true + type: string + network: + description: "The network to run tests on" + required: true + type: choice + options: + - "All" + - "Sepolia" + - "Optimism Sepolia" + - "Arbitrum Sepolia" + - "Base Sepolia" + - "Polygon Mumbai" + - "Avalanche Fuji" + - "Fantom Testnet" + - "Celo Alfajores" + - "Linea Goerli" + - "BSC Testnet" env: CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink @@ -144,7 +166,7 @@ jobs: "type": "section", "text": { "type": "mrkdwn", - "text": "${{ contains(join(needs.*.result, ','), 'failure') && 'Some tests failed, notifying <@U01Q4N37KFG>' || 'All Good!' }}" + "text": "Notifying <@${{ inputs.slack_user_id }}>" } }, { @@ -200,6 +222,7 @@ jobs: sepolia-smoke-tests: environment: integration + if: ${{ (github.event.inputs.network == 'All' || github.event.inputs.network == 'Sepolia') }} permissions: checks: write pull-requests: write @@ -272,6 +295,7 @@ jobs: bsc-testnet-smoke-tests: environment: integration + if: ${{ github.event.inputs.network == 'All' || github.event.inputs.network == 'BSC Testnet' }} permissions: checks: write pull-requests: write @@ -344,6 +368,7 @@ jobs: optimism-sepolia-smoke-tests: environment: integration + if: ${{ github.event.inputs.network == 'All' || github.event.inputs.network == 'Optimism Sepolia' }} permissions: checks: write pull-requests: write @@ -416,6 +441,7 @@ jobs: arbitrum-sepolia-smoke-tests: environment: integration + if: ${{ github.event.inputs.network == 'All' || github.event.inputs.network == 'Arbitrum Sepolia' }} permissions: checks: write pull-requests: write @@ -488,6 +514,7 @@ jobs: base-sepolia-smoke-tests: environment: integration + if: ${{ github.event.inputs.network == 'All' || github.event.inputs.network == 'Base Sepolia' }} permissions: checks: write pull-requests: write @@ -556,6 +583,7 @@ jobs: polygon-mumbai-smoke-tests: environment: integration + if: ${{ github.event.inputs.network == 'All' || github.event.inputs.network == 'Polygon Mumbai' }} permissions: checks: write pull-requests: write @@ -628,6 +656,7 @@ jobs: avalanche-fuji-smoke-tests: environment: integration + if: ${{ github.event.inputs.network == 'All' || github.event.inputs.network == 'Avalanche Fuji' }} permissions: checks: write pull-requests: write @@ -700,6 +729,7 @@ jobs: fantom-testnet-smoke-tests: environment: integration + if: ${{ github.event.inputs.network == 'All' || github.event.inputs.network == 'Fantom Testnet' }} permissions: checks: write pull-requests: write @@ -772,6 +802,7 @@ jobs: celo-alfajores-smoke-tests: environment: integration + if: ${{ github.event.inputs.network == 'All' || github.event.inputs.network == 'Celo Alfajores' }} permissions: checks: write pull-requests: write @@ -909,6 +940,7 @@ jobs: linea-goerli-smoke-tests: environment: integration + if: ${{ github.event.inputs.network == 'All' || github.event.inputs.network == 'Linea Goerli' }} permissions: checks: write pull-requests: write diff --git a/.github/workflows/live-vrf-tests.yml b/.github/workflows/live-vrf-tests.yml new file mode 100644 index 00000000000..e5b3530820b --- /dev/null +++ b/.github/workflows/live-vrf-tests.yml @@ -0,0 +1,191 @@ +name: Live VRF Tests +on: + workflow_dispatch: + inputs: + slack_user_id: + description: "The Slack member ID to notify" + required: true + type: string + networks: + description: "Remove any networks you don't want to run tests on" + required: true + default: "SEPOLIA,OPTIMISM_SEPOLIA,ARBITRUM_SEPOLIA" + test: + description: "Choose test you want to run" + required: true + type: choice + options: + - "TestVRFBasic" + - "TestVRFv2Basic" + - "TestVRFv2Plus" + +env: + CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink + INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com + MOD_CACHE_VERSION: 2 + CHAINLINK_NODE_FUNDING: .5 + PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + LOKI_TENANT_ID: ${{ vars.LOKI_TENANT_ID }} + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} + LOGSTREAM_LOG_TARGETS: loki + GRAFANA_URL: ${{ vars.GRAFANA_URL }} + RUN_ID: ${{ github.run_id }} + + CHAINLINK_COMMIT_SHA: ${{ github.sha }} + CHAINLINK_ENV_USER: ${{ github.actor }} + TEST_LOG_LEVEL: debug + +jobs: + + # Build Test Dependencies + + build-chainlink: + environment: integration + permissions: + id-token: write + contents: read + name: Build Chainlink Image + runs-on: ubuntu-latest + steps: + - name: Collect Metrics + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@0281b09807758be1dcc41651e44e62b353808c47 # v2.1.0 + with: + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: Build Chainlink Image + continue-on-error: true + - name: Checkout the repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }} + - name: Build Chainlink Image + uses: ./.github/actions/build-chainlink-image + with: + tag_suffix: "" + dockerfile: core/chainlink.Dockerfile + git_commit_sha: ${{ github.sha }} + GRAFANA_CLOUD_BASIC_AUTH: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} + GRAFANA_CLOUD_HOST: ${{ secrets.GRAFANA_CLOUD_HOST }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + + build-tests: + environment: integration + permissions: + id-token: write + contents: read + name: Build Tests Binary + runs-on: ubuntu-latest + steps: + - name: Collect Metrics + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@0281b09807758be1dcc41651e44e62b353808c47 # v2.1.0 + with: + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: Build Tests Binary + continue-on-error: true + - name: Checkout the repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }} + - name: Build Tests + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 + with: + test_download_vendor_packages_command: cd ./integration-tests && go mod download + token: ${{ secrets.GITHUB_TOKEN }} + go_mod_path: ./integration-tests/go.mod + go_tags: embed + cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} + cache_restore_only: "true" + binary_name: tests + + build-matrix: + environment: integration + permissions: + id-token: write + contents: read + name: Build Matrix + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.build-matrix.outputs.matrix }} + steps: + - id: build-matrix + run: | + NETWORKS="[\"${{ github.event.inputs.networks }}\"]" + NETWORKS="${NETWORKS//,/\",\"}" + echo "matrix=${NETWORKS}" + + # End Build Test Dependencies + + live-vrf-tests: + environment: integration + permissions: + checks: write + pull-requests: write + id-token: write + contents: read + needs: [build-chainlink, build-tests, build-matrix] + strategy: + max-parallel: 1 + fail-fast: false + matrix: + network: ${{fromJson(needs.build-matrix.outputs.matrix)}} + name: VRF Tests on ${{ matrix.network }} + runs-on: ubuntu-latest + steps: + - name: Build Secrets Names + id: build-secrets-names + run: | + echo "HTTP_URLS_SECRET_NAME=QA_${{ matrix }}_HTTP_URLS" + echo "URLS_SECRET_NAME=QA_${{ matrix }}_URLS" + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + fetch-depth: 0 + - name: Prepare Base64 TOML override + uses: ./.github/actions/setup-create-base64-config-live-testnets + with: + runId: ${{ github.run_id }} + testLogCollect: ${{ vars.TEST_LOG_COLLECT }} + chainlinkImage: ${{ env.CHAINLINK_IMAGE }} + chainlinkVersion: ${{ github.sha }} + lokiEndpoint: ${{ secrets.LOKI_URL }} + lokiTenantId: ${{ vars.LOKI_TENANT_ID }} + lokiBasicAuth: ${{ secrets.LOKI_BASIC_AUTH }} + logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} + grafanaUrl: ${{ vars.GRAFANA_URL }} + grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" + network: ${{ matrix.network }} + httpEndpoints: ${{ secrets[env.HTTP_URLS_SECRET_NAME] }} + wsEndpoints: ${{ secrets[env.URLS_SECRET_NAME] }} + fundingKeys: ${{ secrets.QA_EVM_KEYS }} + - name: Download Tests Binary + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + with: + name: tests + - name: Run Tests + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests-binary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 + with: + test_command_to_run: ./tests -test.timeout 1h -test.count=1 -test.parallel=1 -test.run ${{ inputs.test }} + binary_name: tests + cl_repo: ${{ env.CHAINLINK_IMAGE }} + cl_image_tag: ${{ github.sha }} + aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + dockerhub_username: ${{ secrets.DOCKERHUB_READONLY_USERNAME }} + dockerhub_password: ${{ secrets.DOCKERHUB_READONLY_PASSWORD }} + artifacts_location: ./logs + token: ${{ secrets.GITHUB_TOKEN }} + cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }} + cache_restore_only: "true" + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + - name: Print failed test summary + if: always() + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 + with: + test_directory: "./" \ No newline at end of file From 2f73d04a9c2cbaaae16b9551e7675f7ec7c918b7 Mon Sep 17 00:00:00 2001 From: HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> Date: Mon, 4 Mar 2024 11:42:00 -0500 Subject: [PATCH 06/34] Get cross platform + goreleaser working for devspace (#12166) * Get cross platform + goreleaser working for devspace * move docker build script under custom image build cmd --------- Co-authored-by: Radek Scheibinger Co-authored-by: Radek Scheibinger --- charts/chainlink-cluster/devspace.yaml | 39 ++++++++++++++++---------- shell.nix | 2 +- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/charts/chainlink-cluster/devspace.yaml b/charts/chainlink-cluster/devspace.yaml index 54ee97db4da..4909d8ffb97 100644 --- a/charts/chainlink-cluster/devspace.yaml +++ b/charts/chainlink-cluster/devspace.yaml @@ -36,20 +36,15 @@ pipelines: run_dependencies --all ensure_pull_secrets --all - build_images ---var DOCKER_DEFAULT_PLATFORM=linux/amd64 --all -t $(git rev-parse --short HEAD) + + build_images --all + kubectl label namespace ${DEVSPACE_NAMESPACE} cleanup.kyverno.io/ttl=${NS_TTL} || true kubectl label namespace/${DEVSPACE_NAMESPACE} network=crib || true - if [ -n "$1" ]; then - echo "Deploying tag $1" - tag=$1 - image=${DEVSPACE_IMAGE}:$tag - else - echo "Deploying current commit tag: $(git rev-parse --short HEAD)" - tag=$(git rev-parse --short HEAD) - image=${DEVSPACE_IMAGE}:$tag - fi - echo "Checking tag: $tag" + tag=$(git rev-parse --short HEAD) + image=${DEVSPACE_IMAGE}:$tag + echo "Checking tag: '$tag'" repository_name="chainlink-devspace" desired_tag=$tag @@ -97,11 +92,25 @@ commands: images: app: image: ${DEVSPACE_IMAGE} - dockerfile: ../../core/chainlink.devspace.Dockerfile - context: ../.. - docker: - disableFallback: true + tags: + - $(git rev-parse --short HEAD) + custom: + skipImageArg: true + command: |- + TOPLEVEL=$(git rev-parse --show-toplevel) + pushd $TOPLEVEL + pwd + goreleaser --version + MACOS_SDK_DIR=$(pwd)/tools/bin/MacOSX12.3.sdk ./tools/bin/goreleaser_wrapper release --snapshot --clean --config .goreleaser.develop.yaml + popd + BUILT_IMAGE=$(cat $TOPLEVEL/dist/artifacts.json | jq -r '.[] | select(.type == "Docker Image" and .goarch == "amd64" and (.name | contains("sha")) and ( .name | contains("root") | not) ) | .name') + echo "Tagging and pushing image" + tag=$(git rev-parse --short HEAD) + TAGGED_IMAGE=${DEVSPACE_IMAGE}:$tag + docker tag $BUILT_IMAGE ${runtime.images.app.image}:${runtime.images.app.tag} + echo "Tagged image: $TAGGED_IMAGE" + docker push $TAGGED_IMAGE hooks: - wait: running: true diff --git a/shell.nix b/shell.nix index 44a6b6ab2c1..bc581f8e85a 100644 --- a/shell.nix +++ b/shell.nix @@ -9,7 +9,7 @@ in mkShell { nativeBuildInputs = [ go - + goreleaser postgresql python3 From 06a42f047836318edd4942f4645900a694fe8a3b Mon Sep 17 00:00:00 2001 From: Sri Kidambi <1702865+kidambisrinivas@users.noreply.github.com> Date: Mon, 4 Mar 2024 17:08:26 +0000 Subject: [PATCH 07/34] Test VRFV2PlusWrapper migrate feature (#12246) * Test VRFV2PlusWrapper migrate feature * Minor fix * Add VRFV2PlusWrapper migrate test into TestVRFv2PlusMigration * Test name change * Remove duplicate code * Fixed lint errors- removed unused variables * Addressed PR comments * Removed unused function * Lint errors --- .../actions/vrf/vrfv2plus/vrfv2plus_steps.go | 140 +++-- .../contracts/contract_vrf_models.go | 2 + .../contracts/ethereum_vrfv2plus_contracts.go | 106 ++-- integration-tests/smoke/vrfv2plus_test.go | 500 +++++++++++++----- 4 files changed, 528 insertions(+), 220 deletions(-) diff --git a/integration-tests/actions/vrf/vrfv2plus/vrfv2plus_steps.go b/integration-tests/actions/vrf/vrfv2plus/vrfv2plus_steps.go index aaacb541c98..e7ec2d15c43 100644 --- a/integration-tests/actions/vrf/vrfv2plus/vrfv2plus_steps.go +++ b/integration-tests/actions/vrf/vrfv2plus/vrfv2plus_steps.go @@ -619,6 +619,7 @@ func RequestRandomnessAndWaitForFulfillmentUpgraded( numberOfWords uint32, randomnessRequestCountPerRequest uint16, randomnessRequestCountPerRequestDeviation uint16, + randomWordsFulfilledEventTimeout time.Duration, l zerolog.Logger, ) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, error) { logRandRequest( @@ -647,29 +648,15 @@ func RequestRandomnessAndWaitForFulfillmentUpgraded( return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrRequestRandomness, err) } - randomWordsRequestedEvent, err := coordinator.WaitForRandomWordsRequestedEvent( - [][32]byte{vrfKeyData.KeyHash}, - []*big.Int{subID}, - []common.Address{common.HexToAddress(consumer.Address())}, - time.Minute*1, - ) - if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitRandomWordsRequestedEvent, err) - } - - LogRandomnessRequestedEventUpgraded(l, coordinator, randomWordsRequestedEvent) - - randomWordsFulfilledEvent, err := coordinator.WaitForRandomWordsFulfilledEvent( - []*big.Int{subID}, - []*big.Int{randomWordsRequestedEvent.RequestId}, - time.Minute*2, + return WaitForRequestAndFulfillmentEventsUpgraded( + consumer.Address(), + coordinator, + vrfKeyData, + subID, + isNativeBilling, + randomWordsFulfilledEventTimeout, + l, ) - if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitRandomWordsFulfilledEvent, err) - } - LogRandomWordsFulfilledEventUpgraded(l, coordinator, randomWordsFulfilledEvent) - - return randomWordsFulfilledEvent, err } func SetupVRFV2PlusWrapperEnvironment( @@ -808,9 +795,9 @@ func DeployVRFV2PlusDirectFundingContracts( return &VRFV2PlusWrapperContracts{vrfv2PlusWrapper, consumers}, nil } -func DirectFundingRequestRandomnessAndWaitForFulfillment( +func WrapperRequestRandomness( consumer contracts.VRFv2PlusWrapperLoadTestConsumer, - coordinator contracts.VRFCoordinatorV2_5, + coordinatorAddress string, vrfKeyData *vrfcommon.VRFKeyData, subID *big.Int, isNativeBilling bool, @@ -819,13 +806,11 @@ func DirectFundingRequestRandomnessAndWaitForFulfillment( numberOfWords uint32, randomnessRequestCountPerRequest uint16, randomnessRequestCountPerRequestDeviation uint16, - randomWordsFulfilledEventTimeout time.Duration, - l zerolog.Logger, -) (*vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, error) { + l zerolog.Logger) (string, error) { logRandRequest( l, consumer.Address(), - coordinator.Address(), + coordinatorAddress, subID, isNativeBilling, minimumConfirmations, @@ -843,7 +828,7 @@ func DirectFundingRequestRandomnessAndWaitForFulfillment( randomnessRequestCountPerRequest, ) if err != nil { - return nil, fmt.Errorf("%s, err %w", ErrRequestRandomnessDirectFundingNativePayment, err) + return "", fmt.Errorf("%s, err %w", ErrRequestRandomnessDirectFundingNativePayment, err) } } else { _, err := consumer.RequestRandomness( @@ -853,15 +838,71 @@ func DirectFundingRequestRandomnessAndWaitForFulfillment( randomnessRequestCountPerRequest, ) if err != nil { - return nil, fmt.Errorf("%s, err %w", ErrRequestRandomnessDirectFundingLinkPayment, err) + return "", fmt.Errorf("%s, err %w", ErrRequestRandomnessDirectFundingLinkPayment, err) } } wrapperAddress, err := consumer.GetWrapper(context.Background()) + if err != nil { + return "", fmt.Errorf("error getting wrapper address, err: %w", err) + } + return wrapperAddress.Hex(), nil +} + +func DirectFundingRequestRandomnessAndWaitForFulfillment( + consumer contracts.VRFv2PlusWrapperLoadTestConsumer, + coordinator contracts.VRFCoordinatorV2_5, + vrfKeyData *vrfcommon.VRFKeyData, + subID *big.Int, + isNativeBilling bool, + minimumConfirmations uint16, + callbackGasLimit uint32, + numberOfWords uint32, + randomnessRequestCountPerRequest uint16, + randomnessRequestCountPerRequestDeviation uint16, + randomWordsFulfilledEventTimeout time.Duration, + l zerolog.Logger, +) (*vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, error) { + wrapperAddress, err := WrapperRequestRandomness(consumer, coordinator.Address(), vrfKeyData, subID, + isNativeBilling, minimumConfirmations, callbackGasLimit, numberOfWords, + randomnessRequestCountPerRequest, randomnessRequestCountPerRequestDeviation, + l) if err != nil { return nil, fmt.Errorf("error getting wrapper address, err: %w", err) } return WaitForRequestAndFulfillmentEvents( - wrapperAddress.String(), + wrapperAddress, + coordinator, + vrfKeyData, + subID, + isNativeBilling, + randomWordsFulfilledEventTimeout, + l, + ) +} + +func DirectFundingRequestRandomnessAndWaitForFulfillmentUpgraded( + consumer contracts.VRFv2PlusWrapperLoadTestConsumer, + coordinator contracts.VRFCoordinatorV2PlusUpgradedVersion, + vrfKeyData *vrfcommon.VRFKeyData, + subID *big.Int, + isNativeBilling bool, + minimumConfirmations uint16, + callbackGasLimit uint32, + numberOfWords uint32, + randomnessRequestCountPerRequest uint16, + randomnessRequestCountPerRequestDeviation uint16, + randomWordsFulfilledEventTimeout time.Duration, + l zerolog.Logger, +) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, error) { + wrapperAddress, err := WrapperRequestRandomness(consumer, coordinator.Address(), vrfKeyData, subID, + isNativeBilling, minimumConfirmations, callbackGasLimit, numberOfWords, + randomnessRequestCountPerRequest, randomnessRequestCountPerRequestDeviation, + l) + if err != nil { + return nil, fmt.Errorf("error getting wrapper address, err: %w", err) + } + return WaitForRequestAndFulfillmentEventsUpgraded( + wrapperAddress, coordinator, vrfKeyData, subID, @@ -905,6 +946,39 @@ func WaitForRequestAndFulfillmentEvents( return randomWordsFulfilledEvent, err } +func WaitForRequestAndFulfillmentEventsUpgraded( + consumerAddress string, + coordinator contracts.VRFCoordinatorV2PlusUpgradedVersion, + vrfKeyData *vrfcommon.VRFKeyData, + subID *big.Int, + isNativeBilling bool, + randomWordsFulfilledEventTimeout time.Duration, + l zerolog.Logger, +) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, error) { + randomWordsRequestedEvent, err := coordinator.WaitForRandomWordsRequestedEvent( + [][32]byte{vrfKeyData.KeyHash}, + []*big.Int{subID}, + []common.Address{common.HexToAddress(consumerAddress)}, + time.Minute*1, + ) + if err != nil { + return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitRandomWordsRequestedEvent, err) + } + + LogRandomnessRequestedEventUpgraded(l, coordinator, randomWordsRequestedEvent, isNativeBilling) + + randomWordsFulfilledEvent, err := coordinator.WaitForRandomWordsFulfilledEvent( + []*big.Int{subID}, + []*big.Int{randomWordsRequestedEvent.RequestId}, + randomWordsFulfilledEventTimeout, + ) + if err != nil { + return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitRandomWordsFulfilledEvent, err) + } + LogRandomWordsFulfilledEventUpgraded(l, coordinator, randomWordsFulfilledEvent, isNativeBilling) + return randomWordsFulfilledEvent, err +} + func ReturnFundsForFulfilledRequests(client blockchain.EVMClient, coordinator contracts.VRFCoordinatorV2_5, l zerolog.Logger) error { linkTotalBalance, err := coordinator.GetLinkTotalBalance(context.Background()) if err != nil { @@ -953,9 +1027,11 @@ func LogRandomnessRequestedEventUpgraded( l zerolog.Logger, coordinator contracts.VRFCoordinatorV2PlusUpgradedVersion, randomWordsRequestedEvent *vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested, + isNativeBilling bool, ) { l.Debug(). Str("Coordinator", coordinator.Address()). + Bool("Native Billing", isNativeBilling). Str("Request ID", randomWordsRequestedEvent.RequestId.String()). Str("Subscription ID", randomWordsRequestedEvent.SubId.String()). Str("Sender Address", randomWordsRequestedEvent.Sender.String()). @@ -970,9 +1046,11 @@ func LogRandomWordsFulfilledEventUpgraded( l zerolog.Logger, coordinator contracts.VRFCoordinatorV2PlusUpgradedVersion, randomWordsFulfilledEvent *vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, + isNativeBilling bool, ) { l.Debug(). Str("Coordinator", coordinator.Address()). + Bool("Native Billing", isNativeBilling). Str("Total Payment in Juels", randomWordsFulfilledEvent.Payment.String()). Str("TX Hash", randomWordsFulfilledEvent.Raw.TxHash.String()). Str("Subscription ID", randomWordsFulfilledEvent.SubID.String()). diff --git a/integration-tests/contracts/contract_vrf_models.go b/integration-tests/contracts/contract_vrf_models.go index 4f68d304256..0fa171fb243 100644 --- a/integration-tests/contracts/contract_vrf_models.go +++ b/integration-tests/contracts/contract_vrf_models.go @@ -166,6 +166,8 @@ type VRFV2PlusWrapper interface { Address() string SetConfig(wrapperGasOverhead uint32, coordinatorGasOverhead uint32, wrapperPremiumPercentage uint8, keyHash [32]byte, maxNumWords uint8, stalenessSeconds uint32, fallbackWeiPerUnitLink *big.Int, fulfillmentFlatFeeLinkPPM uint32, fulfillmentFlatFeeNativePPM uint32) error GetSubID(ctx context.Context) (*big.Int, error) + Migrate(newCoordinator common.Address) error + Coordinator(ctx context.Context) (common.Address, error) } type VRFOwner interface { diff --git a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go index 9f728b33043..64afb4c466d 100644 --- a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go +++ b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go @@ -50,6 +50,69 @@ type EthereumVRFV2PlusWrapper struct { wrapper *vrfv2plus_wrapper.VRFV2PlusWrapper } +func (v *EthereumVRFV2PlusWrapper) Address() string { + return v.address.Hex() +} + +func (v *EthereumVRFV2PlusWrapper) SetConfig(wrapperGasOverhead uint32, + coordinatorGasOverhead uint32, + wrapperPremiumPercentage uint8, + keyHash [32]byte, + maxNumWords uint8, + stalenessSeconds uint32, + fallbackWeiPerUnitLink *big.Int, + fulfillmentFlatFeeLinkPPM uint32, + fulfillmentFlatFeeNativePPM uint32, +) error { + opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := v.wrapper.SetConfig( + opts, + wrapperGasOverhead, + coordinatorGasOverhead, + wrapperPremiumPercentage, + keyHash, + maxNumWords, + stalenessSeconds, + fallbackWeiPerUnitLink, + fulfillmentFlatFeeLinkPPM, + fulfillmentFlatFeeNativePPM, + ) + if err != nil { + return err + } + return v.client.ProcessTransaction(tx) +} + +func (v *EthereumVRFV2PlusWrapper) GetSubID(ctx context.Context) (*big.Int, error) { + return v.wrapper.SUBSCRIPTIONID(&bind.CallOpts{ + From: common.HexToAddress(v.client.GetDefaultWallet().Address()), + Context: ctx, + }) +} + +func (v *EthereumVRFV2PlusWrapper) Migrate(newCoordinator common.Address) error { + opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := v.wrapper.Migrate(opts, newCoordinator) + if err != nil { + return err + } + return v.client.ProcessTransaction(tx) +} + +func (v *EthereumVRFV2PlusWrapper) Coordinator(ctx context.Context) (common.Address, error) { + opts := &bind.CallOpts{ + From: common.HexToAddress(v.client.GetDefaultWallet().Address()), + Context: ctx, + } + return v.wrapper.SVrfCoordinator(opts) +} + // DeployVRFCoordinatorV2_5 deploys VRFV2_5 coordinator contract func (e *EthereumContractDeployer) DeployVRFCoordinatorV2_5(bhsAddr string) (VRFCoordinatorV2_5, error) { address, _, instance, err := e.client.DeployContract("VRFCoordinatorV2Plus", func( @@ -901,10 +964,6 @@ func (e *EthereumContractDeployer) DeployVRFV2PlusWrapper(linkAddr string, linkE }, err } -func (v *EthereumVRFV2PlusWrapper) Address() string { - return v.address.Hex() -} - func (e *EthereumContractDeployer) DeployVRFV2PlusWrapperLoadTestConsumer(linkAddr string, vrfV2PlusWrapperAddr string) (VRFv2PlusWrapperLoadTestConsumer, error) { address, _, instance, err := e.client.DeployContract("VRFV2PlusWrapperLoadTestConsumer", func( auth *bind.TransactOpts, @@ -926,45 +985,6 @@ func (v *EthereumVRFV2PlusWrapperLoadTestConsumer) Address() string { return v.address.Hex() } -func (v *EthereumVRFV2PlusWrapper) SetConfig(wrapperGasOverhead uint32, - coordinatorGasOverhead uint32, - wrapperPremiumPercentage uint8, - keyHash [32]byte, - maxNumWords uint8, - stalenessSeconds uint32, - fallbackWeiPerUnitLink *big.Int, - fulfillmentFlatFeeLinkPPM uint32, - fulfillmentFlatFeeNativePPM uint32, -) error { - opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) - if err != nil { - return err - } - tx, err := v.wrapper.SetConfig( - opts, - wrapperGasOverhead, - coordinatorGasOverhead, - wrapperPremiumPercentage, - keyHash, - maxNumWords, - stalenessSeconds, - fallbackWeiPerUnitLink, - fulfillmentFlatFeeLinkPPM, - fulfillmentFlatFeeNativePPM, - ) - if err != nil { - return err - } - return v.client.ProcessTransaction(tx) -} - -func (v *EthereumVRFV2PlusWrapper) GetSubID(ctx context.Context) (*big.Int, error) { - return v.wrapper.SUBSCRIPTIONID(&bind.CallOpts{ - From: common.HexToAddress(v.client.GetDefaultWallet().Address()), - Context: ctx, - }) -} - func (v *EthereumVRFV2PlusWrapperLoadTestConsumer) Fund(ethAmount *big.Float) error { gasEstimates, err := v.client.EstimateGas(ethereum.CallMsg{ To: v.address, diff --git a/integration-tests/smoke/vrfv2plus_test.go b/integration-tests/smoke/vrfv2plus_test.go index 07360afcbeb..4241ec67d8c 100644 --- a/integration-tests/smoke/vrfv2plus_test.go +++ b/integration-tests/smoke/vrfv2plus_test.go @@ -785,176 +785,384 @@ func TestVRFv2PlusMigration(t *testing.T) { ) require.NoError(t, err, "error setting up VRF v2_5 env") - subID := subIDs[0] + // Migrate subscription from old coordinator to new coordinator, verify if balances + // are moved correctly and requests can be made successfully in the subscription in + // new coordinator + t.Run("Test migration of Subscription Billing subID", func(t *testing.T) { + subID := subIDs[0] - subscription, err := vrfv2PlusContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) - require.NoError(t, err, "error getting subscription information") + subscription, err := vrfv2PlusContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) + require.NoError(t, err, "error getting subscription information") - vrfv2plus.LogSubDetails(l, subscription, subID, vrfv2PlusContracts.CoordinatorV2Plus) + vrfv2plus.LogSubDetails(l, subscription, subID, vrfv2PlusContracts.CoordinatorV2Plus) - activeSubIdsOldCoordinatorBeforeMigration, err := vrfv2PlusContracts.CoordinatorV2Plus.GetActiveSubscriptionIds(testcontext.Get(t), big.NewInt(0), big.NewInt(0)) - require.NoError(t, err, "error occurred getting active sub ids") - require.Len(t, activeSubIdsOldCoordinatorBeforeMigration, 1, "Active Sub Ids length is not equal to 1") - require.Equal(t, subID, activeSubIdsOldCoordinatorBeforeMigration[0]) + activeSubIdsOldCoordinatorBeforeMigration, err := vrfv2PlusContracts.CoordinatorV2Plus.GetActiveSubscriptionIds(testcontext.Get(t), big.NewInt(0), big.NewInt(0)) + require.NoError(t, err, "error occurred getting active sub ids") + require.Len(t, activeSubIdsOldCoordinatorBeforeMigration, 1, "Active Sub Ids length is not equal to 1") + require.Equal(t, subID, activeSubIdsOldCoordinatorBeforeMigration[0]) - oldSubscriptionBeforeMigration, err := vrfv2PlusContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) - require.NoError(t, err, "error getting subscription information") + oldSubscriptionBeforeMigration, err := vrfv2PlusContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) + require.NoError(t, err, "error getting subscription information") - //Migration Process - newCoordinator, err := env.ContractDeployer.DeployVRFCoordinatorV2PlusUpgradedVersion(vrfv2PlusContracts.BHS.Address()) - require.NoError(t, err, "error deploying VRF CoordinatorV2PlusUpgradedVersion") - - err = env.EVMClient.WaitForEvents() - require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) - - _, err = vrfv2plus.VRFV2PlusUpgradedVersionRegisterProvingKey(vrfv2PlusData.VRFKey, newCoordinator) - require.NoError(t, err, fmt.Errorf("%s, err: %w", vrfcommon.ErrRegisteringProvingKey, err)) - - vrfv2PlusConfig := config.VRFv2Plus.General - err = newCoordinator.SetConfig( - *vrfv2PlusConfig.MinimumConfirmations, - *vrfv2PlusConfig.MaxGasLimitCoordinatorConfig, - *vrfv2PlusConfig.StalenessSeconds, - *vrfv2PlusConfig.GasAfterPaymentCalculation, - big.NewInt(*vrfv2PlusConfig.LinkNativeFeedResponse), - *vrfv2PlusConfig.FulfillmentFlatFeeNativePPM, - *vrfv2PlusConfig.FulfillmentFlatFeeLinkDiscountPPM, - *vrfv2PlusConfig.NativePremiumPercentage, - *vrfv2PlusConfig.LinkPremiumPercentage, - ) - require.NoError(t, err) + //Migration Process + newCoordinator, err := env.ContractDeployer.DeployVRFCoordinatorV2PlusUpgradedVersion(vrfv2PlusContracts.BHS.Address()) + require.NoError(t, err, "error deploying VRF CoordinatorV2PlusUpgradedVersion") - err = newCoordinator.SetLINKAndLINKNativeFeed(linkAddress.Address(), mockETHLinkFeedAddress.Address()) - require.NoError(t, err, vrfv2plus.ErrSetLinkNativeLinkFeed) - err = env.EVMClient.WaitForEvents() - require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) - - vrfJobSpecConfig := vrfcommon.VRFJobSpecConfig{ - ForwardingAllowed: *vrfv2PlusConfig.VRFJobForwardingAllowed, - CoordinatorAddress: newCoordinator.Address(), - FromAddresses: nodesMap[vrfcommon.VRF].TXKeyAddressStrings, - EVMChainID: env.EVMClient.GetChainID().String(), - MinIncomingConfirmations: int(*vrfv2PlusConfig.MinimumConfirmations), - PublicKey: vrfv2PlusData.VRFKey.Data.ID, - EstimateGasMultiplier: *vrfv2PlusConfig.VRFJobEstimateGasMultiplier, - BatchFulfillmentEnabled: *vrfv2PlusConfig.VRFJobBatchFulfillmentEnabled, - BatchFulfillmentGasMultiplier: *vrfv2PlusConfig.VRFJobBatchFulfillmentGasMultiplier, - PollPeriod: vrfv2PlusConfig.VRFJobPollPeriod.Duration, - RequestTimeout: vrfv2PlusConfig.VRFJobRequestTimeout.Duration, - } + err = env.EVMClient.WaitForEvents() + require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) - _, err = vrfv2plus.CreateVRFV2PlusJob( - nodesMap[vrfcommon.VRF].CLNode.API, - vrfJobSpecConfig, - ) - require.NoError(t, err, vrfv2plus.ErrCreateVRFV2PlusJobs) + _, err = vrfv2plus.VRFV2PlusUpgradedVersionRegisterProvingKey(vrfv2PlusData.VRFKey, newCoordinator) + require.NoError(t, err, fmt.Errorf("%s, err: %w", vrfcommon.ErrRegisteringProvingKey, err)) + + vrfv2PlusConfig := config.VRFv2Plus.General + err = newCoordinator.SetConfig( + *vrfv2PlusConfig.MinimumConfirmations, + *vrfv2PlusConfig.MaxGasLimitCoordinatorConfig, + *vrfv2PlusConfig.StalenessSeconds, + *vrfv2PlusConfig.GasAfterPaymentCalculation, + big.NewInt(*vrfv2PlusConfig.LinkNativeFeedResponse), + *vrfv2PlusConfig.FulfillmentFlatFeeNativePPM, + *vrfv2PlusConfig.FulfillmentFlatFeeLinkDiscountPPM, + *vrfv2PlusConfig.NativePremiumPercentage, + *vrfv2PlusConfig.LinkPremiumPercentage, + ) + require.NoError(t, err) - err = vrfv2PlusContracts.CoordinatorV2Plus.RegisterMigratableCoordinator(newCoordinator.Address()) - require.NoError(t, err, "error registering migratable coordinator") + err = newCoordinator.SetLINKAndLINKNativeFeed(linkAddress.Address(), mockETHLinkFeedAddress.Address()) + require.NoError(t, err, vrfv2plus.ErrSetLinkNativeLinkFeed) + err = env.EVMClient.WaitForEvents() + require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) - err = env.EVMClient.WaitForEvents() - require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) + vrfJobSpecConfig := vrfcommon.VRFJobSpecConfig{ + ForwardingAllowed: *vrfv2PlusConfig.VRFJobForwardingAllowed, + CoordinatorAddress: newCoordinator.Address(), + FromAddresses: nodesMap[vrfcommon.VRF].TXKeyAddressStrings, + EVMChainID: env.EVMClient.GetChainID().String(), + MinIncomingConfirmations: int(*vrfv2PlusConfig.MinimumConfirmations), + PublicKey: vrfv2PlusData.VRFKey.Data.ID, + EstimateGasMultiplier: *vrfv2PlusConfig.VRFJobEstimateGasMultiplier, + BatchFulfillmentEnabled: *vrfv2PlusConfig.VRFJobBatchFulfillmentEnabled, + BatchFulfillmentGasMultiplier: *vrfv2PlusConfig.VRFJobBatchFulfillmentGasMultiplier, + PollPeriod: vrfv2PlusConfig.VRFJobPollPeriod.Duration, + RequestTimeout: vrfv2PlusConfig.VRFJobRequestTimeout.Duration, + } - oldCoordinatorLinkTotalBalanceBeforeMigration, oldCoordinatorEthTotalBalanceBeforeMigration, err := vrfv2plus.GetCoordinatorTotalBalance(vrfv2PlusContracts.CoordinatorV2Plus) - require.NoError(t, err) + _, err = vrfv2plus.CreateVRFV2PlusJob( + nodesMap[vrfcommon.VRF].CLNode.API, + vrfJobSpecConfig, + ) + require.NoError(t, err, vrfv2plus.ErrCreateVRFV2PlusJobs) - migratedCoordinatorLinkTotalBalanceBeforeMigration, migratedCoordinatorEthTotalBalanceBeforeMigration, err := vrfv2plus.GetUpgradedCoordinatorTotalBalance(newCoordinator) - require.NoError(t, err) + err = vrfv2PlusContracts.CoordinatorV2Plus.RegisterMigratableCoordinator(newCoordinator.Address()) + require.NoError(t, err, "error registering migratable coordinator") - err = env.EVMClient.WaitForEvents() - require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) + err = env.EVMClient.WaitForEvents() + require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) - err = vrfv2PlusContracts.CoordinatorV2Plus.Migrate(subID, newCoordinator.Address()) - require.NoError(t, err, "error migrating sub id ", subID.String(), " from ", vrfv2PlusContracts.CoordinatorV2Plus.Address(), " to new Coordinator address ", newCoordinator.Address()) - migrationCompletedEvent, err := vrfv2PlusContracts.CoordinatorV2Plus.WaitForMigrationCompletedEvent(time.Minute * 1) - require.NoError(t, err, "error waiting for MigrationCompleted event") - err = env.EVMClient.WaitForEvents() - require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) + oldCoordinatorLinkTotalBalanceBeforeMigration, oldCoordinatorEthTotalBalanceBeforeMigration, err := vrfv2plus.GetCoordinatorTotalBalance(vrfv2PlusContracts.CoordinatorV2Plus) + require.NoError(t, err) - vrfv2plus.LogMigrationCompletedEvent(l, migrationCompletedEvent, vrfv2PlusContracts) + migratedCoordinatorLinkTotalBalanceBeforeMigration, migratedCoordinatorEthTotalBalanceBeforeMigration, err := vrfv2plus.GetUpgradedCoordinatorTotalBalance(newCoordinator) + require.NoError(t, err) - oldCoordinatorLinkTotalBalanceAfterMigration, oldCoordinatorEthTotalBalanceAfterMigration, err := vrfv2plus.GetCoordinatorTotalBalance(vrfv2PlusContracts.CoordinatorV2Plus) - require.NoError(t, err) + err = env.EVMClient.WaitForEvents() + require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) - migratedCoordinatorLinkTotalBalanceAfterMigration, migratedCoordinatorEthTotalBalanceAfterMigration, err := vrfv2plus.GetUpgradedCoordinatorTotalBalance(newCoordinator) - require.NoError(t, err) + err = vrfv2PlusContracts.CoordinatorV2Plus.Migrate(subID, newCoordinator.Address()) - migratedSubscription, err := newCoordinator.GetSubscription(testcontext.Get(t), subID) - require.NoError(t, err, "error getting subscription information") + require.NoError(t, err, "error migrating sub id ", subID.String(), " from ", vrfv2PlusContracts.CoordinatorV2Plus.Address(), " to new Coordinator address ", newCoordinator.Address()) + migrationCompletedEvent, err := vrfv2PlusContracts.CoordinatorV2Plus.WaitForMigrationCompletedEvent(time.Minute * 1) + require.NoError(t, err, "error waiting for MigrationCompleted event") + err = env.EVMClient.WaitForEvents() + require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) - vrfv2plus.LogSubDetailsAfterMigration(l, newCoordinator, subID, migratedSubscription) + vrfv2plus.LogMigrationCompletedEvent(l, migrationCompletedEvent, vrfv2PlusContracts) - //Verify that Coordinators were updated in Consumers - for _, consumer := range vrfv2PlusContracts.VRFV2PlusConsumer { - coordinatorAddressInConsumerAfterMigration, err := consumer.GetCoordinator(testcontext.Get(t)) - require.NoError(t, err, "error getting Coordinator from Consumer contract") + oldCoordinatorLinkTotalBalanceAfterMigration, oldCoordinatorEthTotalBalanceAfterMigration, err := vrfv2plus.GetCoordinatorTotalBalance(vrfv2PlusContracts.CoordinatorV2Plus) + require.NoError(t, err) + + migratedCoordinatorLinkTotalBalanceAfterMigration, migratedCoordinatorEthTotalBalanceAfterMigration, err := vrfv2plus.GetUpgradedCoordinatorTotalBalance(newCoordinator) + require.NoError(t, err) + + migratedSubscription, err := newCoordinator.GetSubscription(testcontext.Get(t), subID) + require.NoError(t, err, "error getting subscription information") + + vrfv2plus.LogSubDetailsAfterMigration(l, newCoordinator, subID, migratedSubscription) + + //Verify that Coordinators were updated in Consumers + for _, consumer := range vrfv2PlusContracts.VRFV2PlusConsumer { + coordinatorAddressInConsumerAfterMigration, err := consumer.GetCoordinator(testcontext.Get(t)) + require.NoError(t, err, "error getting Coordinator from Consumer contract") + require.Equal(t, newCoordinator.Address(), coordinatorAddressInConsumerAfterMigration.String()) + l.Debug(). + Str("Consumer", consumer.Address()). + Str("Coordinator", coordinatorAddressInConsumerAfterMigration.String()). + Msg("Coordinator Address in Consumer After Migration") + } + + //Verify old and migrated subs + require.Equal(t, oldSubscriptionBeforeMigration.NativeBalance, migratedSubscription.NativeBalance) + require.Equal(t, oldSubscriptionBeforeMigration.Balance, migratedSubscription.Balance) + require.Equal(t, oldSubscriptionBeforeMigration.Owner, migratedSubscription.Owner) + require.Equal(t, oldSubscriptionBeforeMigration.Consumers, migratedSubscription.Consumers) + + //Verify that old sub was deleted from old Coordinator + _, err = vrfv2PlusContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) + require.Error(t, err, "error not occurred when trying to get deleted subscription from old Coordinator after sub migration") + + _, err = vrfv2PlusContracts.CoordinatorV2Plus.GetActiveSubscriptionIds(testcontext.Get(t), big.NewInt(0), big.NewInt(0)) + // If (subscription billing), numActiveSub should be 0 after migration in oldCoordinator + require.Error(t, err, "error not occurred getting active sub ids. Should occur since it should revert when sub id array is empty") + + activeSubIdsMigratedCoordinator, err := newCoordinator.GetActiveSubscriptionIds(testcontext.Get(t), big.NewInt(0), big.NewInt(0)) + require.NoError(t, err, "error occurred getting active sub ids") + require.Len(t, activeSubIdsMigratedCoordinator, 1, "Active Sub Ids length is not equal to 1 for Migrated Coordinator after migration") + require.Equal(t, subID, activeSubIdsMigratedCoordinator[0]) + + //Verify that total balances changed for Link and Eth for new and old coordinator + expectedLinkTotalBalanceForMigratedCoordinator := new(big.Int).Add(oldSubscriptionBeforeMigration.Balance, migratedCoordinatorLinkTotalBalanceBeforeMigration) + expectedEthTotalBalanceForMigratedCoordinator := new(big.Int).Add(oldSubscriptionBeforeMigration.NativeBalance, migratedCoordinatorEthTotalBalanceBeforeMigration) + + expectedLinkTotalBalanceForOldCoordinator := new(big.Int).Sub(oldCoordinatorLinkTotalBalanceBeforeMigration, oldSubscriptionBeforeMigration.Balance) + expectedEthTotalBalanceForOldCoordinator := new(big.Int).Sub(oldCoordinatorEthTotalBalanceBeforeMigration, oldSubscriptionBeforeMigration.NativeBalance) + require.Equal(t, 0, expectedLinkTotalBalanceForMigratedCoordinator.Cmp(migratedCoordinatorLinkTotalBalanceAfterMigration)) + require.Equal(t, 0, expectedEthTotalBalanceForMigratedCoordinator.Cmp(migratedCoordinatorEthTotalBalanceAfterMigration)) + require.Equal(t, 0, expectedLinkTotalBalanceForOldCoordinator.Cmp(oldCoordinatorLinkTotalBalanceAfterMigration)) + require.Equal(t, 0, expectedEthTotalBalanceForOldCoordinator.Cmp(oldCoordinatorEthTotalBalanceAfterMigration)) + + //Verify rand requests fulfills with Link Token billing + _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillmentUpgraded( + vrfv2PlusContracts.VRFV2PlusConsumer[0], + newCoordinator, + vrfv2PlusData, + subID, + false, + *config.VRFv2Plus.General.MinimumConfirmations, + *config.VRFv2Plus.General.CallbackGasLimit, + *config.VRFv2Plus.General.NumberOfWords, + *config.VRFv2Plus.General.RandomnessRequestCountPerRequest, + *config.VRFv2Plus.General.RandomnessRequestCountPerRequestDeviation, + config.VRFv2Plus.General.RandomWordsFulfilledEventTimeout.Duration, + l, + ) + require.NoError(t, err, "error requesting randomness and waiting for fulfilment") + + //Verify rand requests fulfills with Native Token billing + _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillmentUpgraded( + vrfv2PlusContracts.VRFV2PlusConsumer[1], + newCoordinator, + vrfv2PlusData, + subID, + true, + *config.VRFv2Plus.General.MinimumConfirmations, + *config.VRFv2Plus.General.CallbackGasLimit, + *config.VRFv2Plus.General.NumberOfWords, + *config.VRFv2Plus.General.RandomnessRequestCountPerRequest, + *config.VRFv2Plus.General.RandomnessRequestCountPerRequestDeviation, + config.VRFv2Plus.General.RandomWordsFulfilledEventTimeout.Duration, + l, + ) + require.NoError(t, err, "error requesting randomness and waiting for fulfilment") + }) + + // Migrate wrapper subscription from old coordinator to new coordinator, verify if balances + // are moved correctly and requests can be made successfully in the subscription in + // new coordinator + t.Run("Test migration of direct billing using VRFV2PlusWrapper subID", func(t *testing.T) { + configCopy := config.MustCopy().(tc.TestConfig) + wrapperContracts, wrapperSubID, err := vrfv2plus.SetupVRFV2PlusWrapperEnvironment( + env, + &configCopy, + linkAddress, + mockETHLinkFeedAddress, + vrfv2PlusContracts.CoordinatorV2Plus, + vrfv2PlusData.KeyHash, + 1, + ) + require.NoError(t, err) + subID := wrapperSubID + + subscription, err := vrfv2PlusContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) + require.NoError(t, err, "error getting subscription information") + + vrfv2plus.LogSubDetails(l, subscription, subID, vrfv2PlusContracts.CoordinatorV2Plus) + + activeSubIdsOldCoordinatorBeforeMigration, err := vrfv2PlusContracts.CoordinatorV2Plus.GetActiveSubscriptionIds(testcontext.Get(t), big.NewInt(0), big.NewInt(0)) + require.NoError(t, err, "error occurred getting active sub ids") + require.Len(t, activeSubIdsOldCoordinatorBeforeMigration, 1, "Active Sub Ids length is not equal to 1") + activeSubID := activeSubIdsOldCoordinatorBeforeMigration[0] + require.Equal(t, subID, activeSubID) + + oldSubscriptionBeforeMigration, err := vrfv2PlusContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) + require.NoError(t, err, "error getting subscription information") + + //Migration Process + newCoordinator, err := env.ContractDeployer.DeployVRFCoordinatorV2PlusUpgradedVersion(vrfv2PlusContracts.BHS.Address()) + require.NoError(t, err, "error deploying VRF CoordinatorV2PlusUpgradedVersion") + + err = env.EVMClient.WaitForEvents() + require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) + + _, err = vrfv2plus.VRFV2PlusUpgradedVersionRegisterProvingKey(vrfv2PlusData.VRFKey, newCoordinator) + require.NoError(t, err, fmt.Errorf("%s, err: %w", vrfcommon.ErrRegisteringProvingKey, err)) + + vrfv2PlusConfig := config.VRFv2Plus.General + err = newCoordinator.SetConfig( + *vrfv2PlusConfig.MinimumConfirmations, + *vrfv2PlusConfig.MaxGasLimitCoordinatorConfig, + *vrfv2PlusConfig.StalenessSeconds, + *vrfv2PlusConfig.GasAfterPaymentCalculation, + big.NewInt(*vrfv2PlusConfig.LinkNativeFeedResponse), + *vrfv2PlusConfig.FulfillmentFlatFeeNativePPM, + *vrfv2PlusConfig.FulfillmentFlatFeeLinkDiscountPPM, + *vrfv2PlusConfig.NativePremiumPercentage, + *vrfv2PlusConfig.LinkPremiumPercentage, + ) + require.NoError(t, err) + + err = newCoordinator.SetLINKAndLINKNativeFeed(linkAddress.Address(), mockETHLinkFeedAddress.Address()) + require.NoError(t, err, vrfv2plus.ErrSetLinkNativeLinkFeed) + err = env.EVMClient.WaitForEvents() + require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) + + vrfJobSpecConfig := vrfcommon.VRFJobSpecConfig{ + ForwardingAllowed: *vrfv2PlusConfig.VRFJobForwardingAllowed, + CoordinatorAddress: newCoordinator.Address(), + FromAddresses: nodesMap[vrfcommon.VRF].TXKeyAddressStrings, + EVMChainID: env.EVMClient.GetChainID().String(), + MinIncomingConfirmations: int(*vrfv2PlusConfig.MinimumConfirmations), + PublicKey: vrfv2PlusData.VRFKey.Data.ID, + EstimateGasMultiplier: *vrfv2PlusConfig.VRFJobEstimateGasMultiplier, + BatchFulfillmentEnabled: *vrfv2PlusConfig.VRFJobBatchFulfillmentEnabled, + BatchFulfillmentGasMultiplier: *vrfv2PlusConfig.VRFJobBatchFulfillmentGasMultiplier, + PollPeriod: vrfv2PlusConfig.VRFJobPollPeriod.Duration, + RequestTimeout: vrfv2PlusConfig.VRFJobRequestTimeout.Duration, + } + + _, err = vrfv2plus.CreateVRFV2PlusJob( + nodesMap[vrfcommon.VRF].CLNode.API, + vrfJobSpecConfig, + ) + require.NoError(t, err, vrfv2plus.ErrCreateVRFV2PlusJobs) + + err = vrfv2PlusContracts.CoordinatorV2Plus.RegisterMigratableCoordinator(newCoordinator.Address()) + require.NoError(t, err, "error registering migratable coordinator") + + err = env.EVMClient.WaitForEvents() + require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) + + oldCoordinatorLinkTotalBalanceBeforeMigration, oldCoordinatorEthTotalBalanceBeforeMigration, err := vrfv2plus.GetCoordinatorTotalBalance(vrfv2PlusContracts.CoordinatorV2Plus) + require.NoError(t, err) + + migratedCoordinatorLinkTotalBalanceBeforeMigration, migratedCoordinatorEthTotalBalanceBeforeMigration, err := vrfv2plus.GetUpgradedCoordinatorTotalBalance(newCoordinator) + require.NoError(t, err) + + err = env.EVMClient.WaitForEvents() + require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) + + // Migrate sub using VRFV2PlusWrapper's migrate method + err = wrapperContracts.VRFV2PlusWrapper.Migrate(common.HexToAddress(newCoordinator.Address())) + + require.NoError(t, err, "error migrating sub id ", subID.String(), " from ", vrfv2PlusContracts.CoordinatorV2Plus.Address(), " to new Coordinator address ", newCoordinator.Address()) + migrationCompletedEvent, err := vrfv2PlusContracts.CoordinatorV2Plus.WaitForMigrationCompletedEvent(time.Minute * 1) + require.NoError(t, err, "error waiting for MigrationCompleted event") + err = env.EVMClient.WaitForEvents() + require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) + + vrfv2plus.LogMigrationCompletedEvent(l, migrationCompletedEvent, vrfv2PlusContracts) + + oldCoordinatorLinkTotalBalanceAfterMigration, oldCoordinatorEthTotalBalanceAfterMigration, err := vrfv2plus.GetCoordinatorTotalBalance(vrfv2PlusContracts.CoordinatorV2Plus) + require.NoError(t, err) + + migratedCoordinatorLinkTotalBalanceAfterMigration, migratedCoordinatorEthTotalBalanceAfterMigration, err := vrfv2plus.GetUpgradedCoordinatorTotalBalance(newCoordinator) + require.NoError(t, err) + + migratedSubscription, err := newCoordinator.GetSubscription(testcontext.Get(t), subID) + require.NoError(t, err, "error getting subscription information") + + vrfv2plus.LogSubDetailsAfterMigration(l, newCoordinator, subID, migratedSubscription) + + // Verify that Coordinators were updated in Consumers- Consumer in this case is the VRFV2PlusWrapper + coordinatorAddressInConsumerAfterMigration, err := wrapperContracts.VRFV2PlusWrapper.Coordinator(testcontext.Get(t)) + require.NoError(t, err, "error getting Coordinator from Consumer contract- VRFV2PlusWrapper") require.Equal(t, newCoordinator.Address(), coordinatorAddressInConsumerAfterMigration.String()) l.Debug(). - Str("Consumer", consumer.Address()). + Str("Consumer-VRFV2PlusWrapper", wrapperContracts.VRFV2PlusWrapper.Address()). Str("Coordinator", coordinatorAddressInConsumerAfterMigration.String()). - Msg("Coordinator Address in Consumer After Migration") - } + Msg("Coordinator Address in VRFV2PlusWrapper After Migration") - //Verify old and migrated subs - require.Equal(t, oldSubscriptionBeforeMigration.NativeBalance, migratedSubscription.NativeBalance) - require.Equal(t, oldSubscriptionBeforeMigration.Balance, migratedSubscription.Balance) - require.Equal(t, oldSubscriptionBeforeMigration.Owner, migratedSubscription.Owner) - require.Equal(t, oldSubscriptionBeforeMigration.Consumers, migratedSubscription.Consumers) - - //Verify that old sub was deleted from old Coordinator - _, err = vrfv2PlusContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) - require.Error(t, err, "error not occurred when trying to get deleted subscription from old Coordinator after sub migration") - - _, err = vrfv2PlusContracts.CoordinatorV2Plus.GetActiveSubscriptionIds(testcontext.Get(t), big.NewInt(0), big.NewInt(0)) - require.Error(t, err, "error not occurred getting active sub ids. Should occur since it should revert when sub id array is empty") - - activeSubIdsMigratedCoordinator, err := newCoordinator.GetActiveSubscriptionIds(testcontext.Get(t), big.NewInt(0), big.NewInt(0)) - require.NoError(t, err, "error occurred getting active sub ids") - require.Len(t, activeSubIdsMigratedCoordinator, 1, "Active Sub Ids length is not equal to 1 for Migrated Coordinator after migration") - require.Equal(t, subID, activeSubIdsMigratedCoordinator[0]) - - //Verify that total balances changed for Link and Eth for new and old coordinator - expectedLinkTotalBalanceForMigratedCoordinator := new(big.Int).Add(oldSubscriptionBeforeMigration.Balance, migratedCoordinatorLinkTotalBalanceBeforeMigration) - expectedEthTotalBalanceForMigratedCoordinator := new(big.Int).Add(oldSubscriptionBeforeMigration.NativeBalance, migratedCoordinatorEthTotalBalanceBeforeMigration) - - expectedLinkTotalBalanceForOldCoordinator := new(big.Int).Sub(oldCoordinatorLinkTotalBalanceBeforeMigration, oldSubscriptionBeforeMigration.Balance) - expectedEthTotalBalanceForOldCoordinator := new(big.Int).Sub(oldCoordinatorEthTotalBalanceBeforeMigration, oldSubscriptionBeforeMigration.NativeBalance) - require.Equal(t, 0, expectedLinkTotalBalanceForMigratedCoordinator.Cmp(migratedCoordinatorLinkTotalBalanceAfterMigration)) - require.Equal(t, 0, expectedEthTotalBalanceForMigratedCoordinator.Cmp(migratedCoordinatorEthTotalBalanceAfterMigration)) - require.Equal(t, 0, expectedLinkTotalBalanceForOldCoordinator.Cmp(oldCoordinatorLinkTotalBalanceAfterMigration)) - require.Equal(t, 0, expectedEthTotalBalanceForOldCoordinator.Cmp(oldCoordinatorEthTotalBalanceAfterMigration)) - - //Verify rand requests fulfills with Link Token billing - _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillmentUpgraded( - vrfv2PlusContracts.VRFV2PlusConsumer[0], - newCoordinator, - vrfv2PlusData, - subID, - false, - *config.VRFv2Plus.General.MinimumConfirmations, - *config.VRFv2Plus.General.CallbackGasLimit, - *config.VRFv2Plus.General.NumberOfWords, - *config.VRFv2Plus.General.RandomnessRequestCountPerRequest, - *config.VRFv2Plus.General.RandomnessRequestCountPerRequestDeviation, - l, - ) - require.NoError(t, err, "error requesting randomness and waiting for fulfilment") + //Verify old and migrated subs + require.Equal(t, oldSubscriptionBeforeMigration.NativeBalance, migratedSubscription.NativeBalance) + require.Equal(t, oldSubscriptionBeforeMigration.Balance, migratedSubscription.Balance) + require.Equal(t, oldSubscriptionBeforeMigration.Owner, migratedSubscription.Owner) + require.Equal(t, oldSubscriptionBeforeMigration.Consumers, migratedSubscription.Consumers) - //Verify rand requests fulfills with Native Token billing - _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillmentUpgraded( - vrfv2PlusContracts.VRFV2PlusConsumer[1], - newCoordinator, - vrfv2PlusData, - subID, - true, - *config.VRFv2Plus.General.MinimumConfirmations, - *config.VRFv2Plus.General.CallbackGasLimit, - *config.VRFv2Plus.General.NumberOfWords, - *config.VRFv2Plus.General.RandomnessRequestCountPerRequest, - *config.VRFv2Plus.General.RandomnessRequestCountPerRequestDeviation, - l, - ) - require.NoError(t, err, "error requesting randomness and waiting for fulfilment") + //Verify that old sub was deleted from old Coordinator + _, err = vrfv2PlusContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) + require.Error(t, err, "error not occurred when trying to get deleted subscription from old Coordinator after sub migration") + + _, err = vrfv2PlusContracts.CoordinatorV2Plus.GetActiveSubscriptionIds(testcontext.Get(t), big.NewInt(0), big.NewInt(0)) + // If (subscription billing) or (direct billing and numActiveSubs is 0 before this test) -> numActiveSub should be 0 after migration in oldCoordinator + require.Error(t, err, "error not occurred getting active sub ids. Should occur since it should revert when sub id array is empty") + + activeSubIdsMigratedCoordinator, err := newCoordinator.GetActiveSubscriptionIds(testcontext.Get(t), big.NewInt(0), big.NewInt(0)) + require.NoError(t, err, "error occurred getting active sub ids") + require.Len(t, activeSubIdsMigratedCoordinator, 1, "Active Sub Ids length is not equal to 1 for Migrated Coordinator after migration") + require.Equal(t, subID, activeSubIdsMigratedCoordinator[0]) + + //Verify that total balances changed for Link and Eth for new and old coordinator + expectedLinkTotalBalanceForMigratedCoordinator := new(big.Int).Add(oldSubscriptionBeforeMigration.Balance, migratedCoordinatorLinkTotalBalanceBeforeMigration) + expectedEthTotalBalanceForMigratedCoordinator := new(big.Int).Add(oldSubscriptionBeforeMigration.NativeBalance, migratedCoordinatorEthTotalBalanceBeforeMigration) + + expectedLinkTotalBalanceForOldCoordinator := new(big.Int).Sub(oldCoordinatorLinkTotalBalanceBeforeMigration, oldSubscriptionBeforeMigration.Balance) + expectedEthTotalBalanceForOldCoordinator := new(big.Int).Sub(oldCoordinatorEthTotalBalanceBeforeMigration, oldSubscriptionBeforeMigration.NativeBalance) + require.Equal(t, 0, expectedLinkTotalBalanceForMigratedCoordinator.Cmp(migratedCoordinatorLinkTotalBalanceAfterMigration)) + require.Equal(t, 0, expectedEthTotalBalanceForMigratedCoordinator.Cmp(migratedCoordinatorEthTotalBalanceAfterMigration)) + require.Equal(t, 0, expectedLinkTotalBalanceForOldCoordinator.Cmp(oldCoordinatorLinkTotalBalanceAfterMigration)) + require.Equal(t, 0, expectedEthTotalBalanceForOldCoordinator.Cmp(oldCoordinatorEthTotalBalanceAfterMigration)) + + // Verify rand requests fulfills with Link Token billing + isNativeBilling := false + randomWordsFulfilledEvent, err := vrfv2plus.DirectFundingRequestRandomnessAndWaitForFulfillmentUpgraded( + wrapperContracts.LoadTestConsumers[0], + newCoordinator, + vrfv2PlusData, + subID, + isNativeBilling, + *configCopy.VRFv2Plus.General.MinimumConfirmations, + *configCopy.VRFv2Plus.General.CallbackGasLimit, + *configCopy.VRFv2Plus.General.NumberOfWords, + *configCopy.VRFv2Plus.General.RandomnessRequestCountPerRequest, + *configCopy.VRFv2Plus.General.RandomnessRequestCountPerRequestDeviation, + configCopy.VRFv2Plus.General.RandomWordsFulfilledEventTimeout.Duration, + l, + ) + require.NoError(t, err, "error requesting randomness and waiting for fulfilment") + consumerStatus, err := wrapperContracts.LoadTestConsumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) + require.NoError(t, err, "error getting rand request status") + require.True(t, consumerStatus.Fulfilled) + + // Verify rand requests fulfills with Native Token billing + isNativeBilling = true + randomWordsFulfilledEvent, err = vrfv2plus.DirectFundingRequestRandomnessAndWaitForFulfillmentUpgraded( + wrapperContracts.LoadTestConsumers[0], + newCoordinator, + vrfv2PlusData, + subID, + isNativeBilling, + *configCopy.VRFv2Plus.General.MinimumConfirmations, + *configCopy.VRFv2Plus.General.CallbackGasLimit, + *configCopy.VRFv2Plus.General.NumberOfWords, + *configCopy.VRFv2Plus.General.RandomnessRequestCountPerRequest, + *configCopy.VRFv2Plus.General.RandomnessRequestCountPerRequestDeviation, + configCopy.VRFv2Plus.General.RandomWordsFulfilledEventTimeout.Duration, + l, + ) + require.NoError(t, err, "error requesting randomness and waiting for fulfilment") + consumerStatus, err = wrapperContracts.LoadTestConsumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) + require.NoError(t, err, "error getting rand request status") + require.True(t, consumerStatus.Fulfilled) + }) } func TestVRFV2PlusWithBHS(t *testing.T) { From 91d76d9f9c13ac35076b790c01f75c67ba8d94cc Mon Sep 17 00:00:00 2001 From: Tate Date: Mon, 4 Mar 2024 11:09:48 -0700 Subject: [PATCH 08/34] E2E buildTests script pop directory when building load tests (#12279) --- integration-tests/scripts/buildTests | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/integration-tests/scripts/buildTests b/integration-tests/scripts/buildTests index 27378bdf43f..b6033c1c415 100755 --- a/integration-tests/scripts/buildTests +++ b/integration-tests/scripts/buildTests @@ -23,7 +23,8 @@ for x in $tosplit do if [ "$x" = "load" ]; then echo "Changing directory and executing go test -c ./... for 'load' package" - cd "load" && go test -c -tags embed -o .. ./... + pushd "./load" && go test -c -tags embed -o .. ./... + popd else go test -c -tags embed ./"${x}" fi From 4534b59a716a41b6ef43287318e510120ed9f728 Mon Sep 17 00:00:00 2001 From: amit-momin <108959691+amit-momin@users.noreply.github.com> Date: Mon, 4 Mar 2024 12:40:18 -0600 Subject: [PATCH 09/34] Disable gas price warning logs when running in eip-1559 mode (#12199) * Disabled gas price warning logs when running in eip-1559 mode for block history estimator * Added warn log length check --- .../chains/evm/gas/block_history_estimator.go | 10 ++- .../evm/gas/block_history_estimator_test.go | 68 +++++++++---------- 2 files changed, 42 insertions(+), 36 deletions(-) diff --git a/core/chains/evm/gas/block_history_estimator.go b/core/chains/evm/gas/block_history_estimator.go index 66f3e5d2e67..27e20931af8 100644 --- a/core/chains/evm/gas/block_history_estimator.go +++ b/core/chains/evm/gas/block_history_estimator.go @@ -819,18 +819,24 @@ func (b *BlockHistoryEstimator) setPercentileTipCap(tipCap *assets.Wei) { func (b *BlockHistoryEstimator) setPercentileGasPrice(gasPrice *assets.Wei) { max := b.eConfig.PriceMax() min := b.eConfig.PriceMin() + eip1559 := b.eConfig.EIP1559DynamicFees() + var warn string b.priceMu.Lock() defer b.priceMu.Unlock() if gasPrice.Cmp(max) > 0 { - b.logger.Warnw(fmt.Sprintf("Calculated gas price of %s exceeds EVM.GasEstimator.PriceMax=%[2]s, setting gas price to the maximum allowed value of %[2]s instead", gasPrice.String(), max.String()), "gasPriceWei", gasPrice, "maxGasPriceWei", max) + warn = fmt.Sprintf("Calculated gas price of %s exceeds EVM.GasEstimator.PriceMax=%[2]s, setting gas price to the maximum allowed value of %[2]s instead", gasPrice.String(), max.String()) b.gasPrice = max } else if gasPrice.Cmp(min) < 0 { - b.logger.Warnw(fmt.Sprintf("Calculated gas price of %s falls below EVM.Transactions.PriceMin=%[2]s, setting gas price to the minimum allowed value of %[2]s instead", gasPrice.String(), min.String()), "gasPriceWei", gasPrice, "minGasPriceWei", min) + warn = fmt.Sprintf("Calculated gas price of %s falls below EVM.GasEstimator.PriceMin=%[2]s, setting gas price to the minimum allowed value of %[2]s instead", gasPrice.String(), min.String()) b.gasPrice = min } else { b.gasPrice = gasPrice } + + if !eip1559 && len(warn) > 0 { + b.logger.Warnw(warn, "gasPriceWei", gasPrice, "maxGasPriceWei", max, "minGasPriceWei", min) + } } // isUsable returns true if the tx is usable both generally and specifically for diff --git a/core/chains/evm/gas/block_history_estimator_test.go b/core/chains/evm/gas/block_history_estimator_test.go index 0cb160a172c..7c467d1b36f 100644 --- a/core/chains/evm/gas/block_history_estimator_test.go +++ b/core/chains/evm/gas/block_history_estimator_test.go @@ -761,11 +761,11 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) { gas.SetRollingBlockHistory(bhe, blocks) bhe.Recalculate(cltest.Head(1)) - blocks = []evmtypes.Block{evmtypes.Block{}} + blocks = []evmtypes.Block{{}} gas.SetRollingBlockHistory(bhe, blocks) bhe.Recalculate(cltest.Head(1)) - blocks = []evmtypes.Block{evmtypes.Block{Transactions: []evmtypes.Transaction{}}} + blocks = []evmtypes.Block{{Transactions: []evmtypes.Transaction{}}} gas.SetRollingBlockHistory(bhe, blocks) bhe.Recalculate(cltest.Head(1)) }) @@ -785,12 +785,12 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) { bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg) blocks := []evmtypes.Block{ - evmtypes.Block{ + { Number: 0, Hash: utils.NewHash(), Transactions: cltest.LegacyTransactionsFromGasPrices(9001), }, - evmtypes.Block{ + { Number: 1, Hash: utils.NewHash(), Transactions: cltest.LegacyTransactionsFromGasPrices(9002), @@ -805,7 +805,7 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) { require.Equal(t, maxGasPrice, price) }) - t.Run("sets gas price to EVM.Transactions.PriceMin if the calculation would otherwise fall below it", func(t *testing.T) { + t.Run("sets gas price to EVM.GasEstimator.PriceMin if the calculation would otherwise fall below it", func(t *testing.T) { ethClient := evmtest.NewEthClientMockWithDefaultChain(t) cfg := gas.NewMockConfig() bhCfg := newBlockHistoryConfig() @@ -820,12 +820,12 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) { bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg) blocks := []evmtypes.Block{ - evmtypes.Block{ + { Number: 0, Hash: utils.NewHash(), Transactions: cltest.LegacyTransactionsFromGasPrices(5), }, - evmtypes.Block{ + { Number: 1, Hash: utils.NewHash(), Transactions: cltest.LegacyTransactionsFromGasPrices(7), @@ -868,13 +868,13 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) { Number: 1, Hash: b2Hash, ParentHash: b1Hash, - Transactions: []evmtypes.Transaction{evmtypes.Transaction{GasPrice: assets.NewWeiI(70), GasLimit: 42}}, + Transactions: []evmtypes.Transaction{{GasPrice: assets.NewWeiI(70), GasLimit: 42}}, }, { Number: 2, Hash: utils.NewHash(), ParentHash: b2Hash, - Transactions: []evmtypes.Transaction{evmtypes.Transaction{GasPrice: assets.NewWeiI(90), GasLimit: 0}}, + Transactions: []evmtypes.Transaction{{GasPrice: assets.NewWeiI(90), GasLimit: 0}}, }, } @@ -904,7 +904,7 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) { b1Hash := utils.NewHash() blocks := []evmtypes.Block{ - evmtypes.Block{ + { Number: 0, Hash: b1Hash, ParentHash: common.Hash{}, @@ -940,7 +940,7 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) { b1Hash := utils.NewHash() blocks := []evmtypes.Block{ - evmtypes.Block{ + { Number: 0, Hash: b1Hash, ParentHash: common.Hash{}, @@ -979,20 +979,20 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) { b1Hash := utils.NewHash() blocks := []evmtypes.Block{ - evmtypes.Block{ + { Number: 0, Hash: b1Hash, ParentHash: common.Hash{}, Transactions: []evmtypes.Transaction{ - evmtypes.Transaction{GasPrice: assets.NewWeiI(50), GasLimit: 42}, - evmtypes.Transaction{GasPrice: unreasonablyHugeGasPrice, GasLimit: 42}, - evmtypes.Transaction{GasPrice: unreasonablyHugeGasPrice, GasLimit: 42}, - evmtypes.Transaction{GasPrice: unreasonablyHugeGasPrice, GasLimit: 42}, - evmtypes.Transaction{GasPrice: unreasonablyHugeGasPrice, GasLimit: 42}, - evmtypes.Transaction{GasPrice: unreasonablyHugeGasPrice, GasLimit: 42}, - evmtypes.Transaction{GasPrice: unreasonablyHugeGasPrice, GasLimit: 42}, - evmtypes.Transaction{GasPrice: unreasonablyHugeGasPrice, GasLimit: 42}, - evmtypes.Transaction{GasPrice: unreasonablyHugeGasPrice, GasLimit: 42}, + {GasPrice: assets.NewWeiI(50), GasLimit: 42}, + {GasPrice: unreasonablyHugeGasPrice, GasLimit: 42}, + {GasPrice: unreasonablyHugeGasPrice, GasLimit: 42}, + {GasPrice: unreasonablyHugeGasPrice, GasLimit: 42}, + {GasPrice: unreasonablyHugeGasPrice, GasLimit: 42}, + {GasPrice: unreasonablyHugeGasPrice, GasLimit: 42}, + {GasPrice: unreasonablyHugeGasPrice, GasLimit: 42}, + {GasPrice: unreasonablyHugeGasPrice, GasLimit: 42}, + {GasPrice: unreasonablyHugeGasPrice, GasLimit: 42}, }, }, } @@ -1022,7 +1022,7 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) { b1Hash := utils.NewHash() blocks := []evmtypes.Block{ - evmtypes.Block{ + { Number: 0, Hash: b1Hash, ParentHash: common.Hash{}, @@ -1068,7 +1068,7 @@ func TestBlockHistoryEstimator_Recalculate_EIP1559(t *testing.T) { gas.SetRollingBlockHistory(bhe, blocks) bhe.Recalculate(cltest.Head(1)) - blocks = []evmtypes.Block{evmtypes.Block{}} // No base fee (doesn't crash) + blocks = []evmtypes.Block{{}} // No base fee (doesn't crash) gas.SetRollingBlockHistory(bhe, blocks) bhe.Recalculate(cltest.Head(1)) @@ -1105,13 +1105,13 @@ func TestBlockHistoryEstimator_Recalculate_EIP1559(t *testing.T) { bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg) blocks := []evmtypes.Block{ - evmtypes.Block{ + { BaseFeePerGas: assets.NewWeiI(1), Number: 0, Hash: utils.NewHash(), Transactions: cltest.DynamicFeeTransactionsFromTipCaps(9001), }, - evmtypes.Block{ + { BaseFeePerGas: assets.NewWeiI(1), Number: 1, Hash: utils.NewHash(), @@ -1127,7 +1127,7 @@ func TestBlockHistoryEstimator_Recalculate_EIP1559(t *testing.T) { require.Equal(t, tipCap.Int64(), maxGasPrice.Int64()) }) - t.Run("sets tip cap to EVM.Transactions.PriceMin if the calculation would otherwise fall below it", func(t *testing.T) { + t.Run("sets tip cap to EVM.GasEstimator.TipCapMin if the calculation would otherwise fall below it", func(t *testing.T) { ethClient := evmtest.NewEthClientMockWithDefaultChain(t) cfg := gas.NewMockConfig() bhCfg := newBlockHistoryConfig() @@ -1143,13 +1143,13 @@ func TestBlockHistoryEstimator_Recalculate_EIP1559(t *testing.T) { bhe := newBlockHistoryEstimator(t, ethClient, cfg, geCfg, bhCfg) blocks := []evmtypes.Block{ - evmtypes.Block{ + { BaseFeePerGas: assets.NewWeiI(1), Number: 0, Hash: utils.NewHash(), Transactions: cltest.DynamicFeeTransactionsFromTipCaps(5), }, - evmtypes.Block{ + { BaseFeePerGas: assets.NewWeiI(1), Number: 1, Hash: utils.NewHash(), @@ -1195,13 +1195,13 @@ func TestBlockHistoryEstimator_Recalculate_EIP1559(t *testing.T) { Number: 1, Hash: b2Hash, ParentHash: b1Hash, - Transactions: []evmtypes.Transaction{evmtypes.Transaction{Type: 0x2, MaxFeePerGas: assets.NewWeiI(1000), MaxPriorityFeePerGas: assets.NewWeiI(60), GasLimit: 42}}, + Transactions: []evmtypes.Transaction{{Type: 0x2, MaxFeePerGas: assets.NewWeiI(1000), MaxPriorityFeePerGas: assets.NewWeiI(60), GasLimit: 42}}, }, { Number: 2, Hash: utils.NewHash(), ParentHash: b2Hash, - Transactions: []evmtypes.Transaction{evmtypes.Transaction{Type: 0x2, MaxFeePerGas: assets.NewWeiI(1000), MaxPriorityFeePerGas: assets.NewWeiI(80), GasLimit: 0}}, + Transactions: []evmtypes.Transaction{{Type: 0x2, MaxFeePerGas: assets.NewWeiI(1000), MaxPriorityFeePerGas: assets.NewWeiI(80), GasLimit: 0}}, }, } @@ -1231,7 +1231,7 @@ func TestBlockHistoryEstimator_Recalculate_EIP1559(t *testing.T) { b1Hash := utils.NewHash() blocks := []evmtypes.Block{ - evmtypes.Block{ + { BaseFeePerGas: assets.NewWeiI(10), Number: 0, Hash: b1Hash, @@ -1267,7 +1267,7 @@ func TestBlockHistoryEstimator_Recalculate_EIP1559(t *testing.T) { b1Hash := utils.NewHash() blocks := []evmtypes.Block{ - evmtypes.Block{ + { BaseFeePerGas: assets.NewWeiI(10), Number: 0, Hash: b1Hash, @@ -1972,13 +1972,13 @@ func TestBlockHistoryEstimator_GetDynamicFee(t *testing.T) { bhe := newBlockHistoryEstimator(t, nil, cfg, geCfg, bhCfg) blocks := []evmtypes.Block{ - evmtypes.Block{ + { BaseFeePerGas: assets.NewWeiI(88889), Number: 0, Hash: utils.NewHash(), Transactions: cltest.DynamicFeeTransactionsFromTipCaps(5000, 6000, 6000), }, - evmtypes.Block{ + { BaseFeePerGas: assets.NewWeiI(100000), Number: 1, Hash: utils.NewHash(), From af0e16e8899f5aacedaff5a052e6478e02afa585 Mon Sep 17 00:00:00 2001 From: chainchad <96362174+chainchad@users.noreply.github.com> Date: Mon, 4 Mar 2024 16:37:07 -0500 Subject: [PATCH 10/34] Avoid adding a duplicate comment with CRIB env details (#12274) * Avoid adding a duplicate comment with CRIB env details * Make script executable * Make script executable * Tweak paths * Checkout repo * Install deps * Check for comment after label --- .github/scripts/crib/package-lock.json | 440 ++++++++++++++++++++ .github/scripts/crib/package.json | 17 + .github/scripts/crib/pr-comment-crib-env.js | 100 +++++ .github/workflows/pr-labels.yml | 48 +-- 4 files changed, 567 insertions(+), 38 deletions(-) create mode 100644 .github/scripts/crib/package-lock.json create mode 100644 .github/scripts/crib/package.json create mode 100755 .github/scripts/crib/pr-comment-crib-env.js diff --git a/.github/scripts/crib/package-lock.json b/.github/scripts/crib/package-lock.json new file mode 100644 index 00000000000..cf3922a3fb0 --- /dev/null +++ b/.github/scripts/crib/package-lock.json @@ -0,0 +1,440 @@ +{ + "name": "crib", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "crib", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@actions/core": "^1.10.1", + "@actions/github": "^6.0.0", + "@octokit/rest": "^20.0.2" + } + }, + "node_modules/@actions/core": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.1.tgz", + "integrity": "sha512-3lBR9EDAY+iYIpTnTIXmWcNbX3T2kCkAEQGIQx4NVQ0575nk2k3GRZDTPQG+vVtS2izSLmINlxXf0uLtnrTP+g==", + "dependencies": { + "@actions/http-client": "^2.0.1", + "uuid": "^8.3.2" + } + }, + "node_modules/@actions/github": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@actions/github/-/github-6.0.0.tgz", + "integrity": "sha512-alScpSVnYmjNEXboZjarjukQEzgCRmjMv6Xj47fsdnqGS73bjJNDpiiXmp8jr0UZLdUB6d9jW63IcmddUP+l0g==", + "dependencies": { + "@actions/http-client": "^2.2.0", + "@octokit/core": "^5.0.1", + "@octokit/plugin-paginate-rest": "^9.0.0", + "@octokit/plugin-rest-endpoint-methods": "^10.0.0" + } + }, + "node_modules/@actions/http-client": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.0.tgz", + "integrity": "sha512-q+epW0trjVUUHboliPb4UF9g2msf+w61b32tAkFEwL/IwP0DQWgbCMM0Hbe3e3WXSKz5VcUXbzJQgy8Hkra/Lg==", + "dependencies": { + "tunnel": "^0.0.6", + "undici": "^5.25.4" + } + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@octokit/auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/core": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.1.0.tgz", + "integrity": "sha512-BDa2VAMLSh3otEiaMJ/3Y36GU4qf6GI+VivQ/P41NC6GHcdxpKlqV0ikSZ5gdQsmS3ojXeRx5vasgNTinF0Q4g==", + "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.0.0", + "@octokit/request": "^8.0.2", + "@octokit/request-error": "^5.0.0", + "@octokit/types": "^12.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/endpoint": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.4.tgz", + "integrity": "sha512-DWPLtr1Kz3tv8L0UvXTDP1fNwM0S+z6EJpRcvH66orY6Eld4XBMCSYsaWp4xIm61jTWxK68BrR7ibO+vSDnZqw==", + "dependencies": { + "@octokit/types": "^12.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/graphql": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz", + "integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==", + "dependencies": { + "@octokit/request": "^8.0.1", + "@octokit/types": "^12.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", + "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.1.tgz", + "integrity": "sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw==", + "dependencies": { + "@octokit/types": "^12.6.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.1.tgz", + "integrity": "sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==", + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.1.tgz", + "integrity": "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==", + "dependencies": { + "@octokit/types": "^12.6.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/request": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.2.0.tgz", + "integrity": "sha512-exPif6x5uwLqv1N1irkLG1zZNJkOtj8bZxuVHd71U5Ftuxf2wGNvAJyNBcPbPC+EBzwYEbBDdSFb8EPcjpYxPQ==", + "dependencies": { + "@octokit/endpoint": "^9.0.0", + "@octokit/request-error": "^5.0.0", + "@octokit/types": "^12.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/request-error": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz", + "integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==", + "dependencies": { + "@octokit/types": "^12.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/rest": { + "version": "20.0.2", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.2.tgz", + "integrity": "sha512-Ux8NDgEraQ/DMAU1PlAohyfBBXDwhnX2j33Z1nJNziqAfHi70PuxkFYIcIt8aIAxtRE7KVuKp8lSR8pA0J5iOQ==", + "dependencies": { + "@octokit/core": "^5.0.0", + "@octokit/plugin-paginate-rest": "^9.0.0", + "@octokit/plugin-request-log": "^4.0.0", + "@octokit/plugin-rest-endpoint-methods": "^10.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/types": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", + "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", + "dependencies": { + "@octokit/openapi-types": "^20.0.0" + } + }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" + }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/undici": { + "version": "5.28.3", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.3.tgz", + "integrity": "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/universal-user-agent": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", + "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==" + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + } + }, + "dependencies": { + "@actions/core": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.1.tgz", + "integrity": "sha512-3lBR9EDAY+iYIpTnTIXmWcNbX3T2kCkAEQGIQx4NVQ0575nk2k3GRZDTPQG+vVtS2izSLmINlxXf0uLtnrTP+g==", + "requires": { + "@actions/http-client": "^2.0.1", + "uuid": "^8.3.2" + } + }, + "@actions/github": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@actions/github/-/github-6.0.0.tgz", + "integrity": "sha512-alScpSVnYmjNEXboZjarjukQEzgCRmjMv6Xj47fsdnqGS73bjJNDpiiXmp8jr0UZLdUB6d9jW63IcmddUP+l0g==", + "requires": { + "@actions/http-client": "^2.2.0", + "@octokit/core": "^5.0.1", + "@octokit/plugin-paginate-rest": "^9.0.0", + "@octokit/plugin-rest-endpoint-methods": "^10.0.0" + } + }, + "@actions/http-client": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.0.tgz", + "integrity": "sha512-q+epW0trjVUUHboliPb4UF9g2msf+w61b32tAkFEwL/IwP0DQWgbCMM0Hbe3e3WXSKz5VcUXbzJQgy8Hkra/Lg==", + "requires": { + "tunnel": "^0.0.6", + "undici": "^5.25.4" + } + }, + "@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==" + }, + "@octokit/auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==" + }, + "@octokit/core": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.1.0.tgz", + "integrity": "sha512-BDa2VAMLSh3otEiaMJ/3Y36GU4qf6GI+VivQ/P41NC6GHcdxpKlqV0ikSZ5gdQsmS3ojXeRx5vasgNTinF0Q4g==", + "requires": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.0.0", + "@octokit/request": "^8.0.2", + "@octokit/request-error": "^5.0.0", + "@octokit/types": "^12.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/endpoint": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.4.tgz", + "integrity": "sha512-DWPLtr1Kz3tv8L0UvXTDP1fNwM0S+z6EJpRcvH66orY6Eld4XBMCSYsaWp4xIm61jTWxK68BrR7ibO+vSDnZqw==", + "requires": { + "@octokit/types": "^12.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/graphql": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz", + "integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==", + "requires": { + "@octokit/request": "^8.0.1", + "@octokit/types": "^12.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/openapi-types": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", + "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==" + }, + "@octokit/plugin-paginate-rest": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.1.tgz", + "integrity": "sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw==", + "requires": { + "@octokit/types": "^12.6.0" + } + }, + "@octokit/plugin-request-log": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.1.tgz", + "integrity": "sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==", + "requires": {} + }, + "@octokit/plugin-rest-endpoint-methods": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.1.tgz", + "integrity": "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==", + "requires": { + "@octokit/types": "^12.6.0" + } + }, + "@octokit/request": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.2.0.tgz", + "integrity": "sha512-exPif6x5uwLqv1N1irkLG1zZNJkOtj8bZxuVHd71U5Ftuxf2wGNvAJyNBcPbPC+EBzwYEbBDdSFb8EPcjpYxPQ==", + "requires": { + "@octokit/endpoint": "^9.0.0", + "@octokit/request-error": "^5.0.0", + "@octokit/types": "^12.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request-error": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz", + "integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==", + "requires": { + "@octokit/types": "^12.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/rest": { + "version": "20.0.2", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.2.tgz", + "integrity": "sha512-Ux8NDgEraQ/DMAU1PlAohyfBBXDwhnX2j33Z1nJNziqAfHi70PuxkFYIcIt8aIAxtRE7KVuKp8lSR8pA0J5iOQ==", + "requires": { + "@octokit/core": "^5.0.0", + "@octokit/plugin-paginate-rest": "^9.0.0", + "@octokit/plugin-request-log": "^4.0.0", + "@octokit/plugin-rest-endpoint-methods": "^10.0.0" + } + }, + "@octokit/types": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", + "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", + "requires": { + "@octokit/openapi-types": "^20.0.0" + } + }, + "before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" + }, + "deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" + }, + "undici": { + "version": "5.28.3", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.3.tgz", + "integrity": "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==", + "requires": { + "@fastify/busboy": "^2.0.0" + } + }, + "universal-user-agent": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", + "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==" + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + } + } +} diff --git a/.github/scripts/crib/package.json b/.github/scripts/crib/package.json new file mode 100644 index 00000000000..5382bff571e --- /dev/null +++ b/.github/scripts/crib/package.json @@ -0,0 +1,17 @@ +{ + "name": "crib", + "version": "1.0.0", + "description": "", + "main": "pr-comment-crib-env.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "MIT", + "dependencies": { + "@actions/core": "^1.10.1", + "@actions/github": "^6.0.0", + "@octokit/rest": "^20.0.2" + } +} diff --git a/.github/scripts/crib/pr-comment-crib-env.js b/.github/scripts/crib/pr-comment-crib-env.js new file mode 100755 index 00000000000..37ca7316cc3 --- /dev/null +++ b/.github/scripts/crib/pr-comment-crib-env.js @@ -0,0 +1,100 @@ +#!/usr/bin/env node + +const core = require("@actions/core"); +const github = require("@actions/github"); +const { Octokit } = require("@octokit/rest"); + +async function commentExists(octokit, owner, repo, prNumber, uniqueIdentifier) { + // This will automatically paginate through all comments + const comments = await octokit.paginate(octokit.rest.issues.listComments, { + owner, + repo, + issue_number: prNumber, + }); + + // Check each comment for the unique identifier + return comments.some((comment) => comment.body.includes(uniqueIdentifier)); +} + +async function run() { + try { + const token = process.env.GITHUB_TOKEN; + const octokit = new Octokit({ auth: token }); + + const context = github.context; + const labelsToCheck = ["crib"]; + const { owner, repo } = context.repo; + const prNumber = context.issue.number; + + if (!prNumber) { + core.setFailed("Could not get PR number from context"); + return; + } + + // List labels on the PR + const { data: labels } = await octokit.rest.issues.listLabelsOnIssue({ + owner, + repo, + issue_number: prNumber, + }); + + // Check if any label matches the labelsToCheck + const labelMatches = labels.some((label) => + labelsToCheck.includes(label.name) + ); + + if (!labelMatches) { + core.info("No 'crib' PR label found. Proceeding."); + return; + } + + // Comment header and unique identifier + const commentHeader = "## CRIB Environment Details"; + + // Check if the comment already exists + if (await commentExists(octokit, owner, repo, prNumber, commentHeader)) { + core.info("CRIB environment comment already exists. Skipping."); + return; + } + + // Construct the comment + const comment = `${commentHeader} :information_source: + +CRIB activated via the 'crib' label. To destroy the environment, remove the 'crib' PR label or close the PR. + +Please review the following details: + +### Subdomains + +_Use these subdomains to access the CRIB environment. They are prefixes to the internal base domain._ + +- crib-chainlink-${prNumber}-node1. +- crib-chainlink-${prNumber}-node2. +- crib-chainlink-${prNumber}-node3. +- crib-chainlink-${prNumber}-node4. +- crib-chainlink-${prNumber}-node5. +- crib-chainlink-${prNumber}-node6. +- crib-chainlink-${prNumber}-geth-http. +- crib-chainlink-${prNumber}-geth-ws. +- crib-chainlink-${prNumber}-mockserver. +`; + + // Create a comment on the PR + await octokit.rest.issues.createComment({ + owner, + repo, + issue_number: prNumber, + body: comment, + }); + } catch (error) { + core.setFailed(error.message); + } +} + +// Run the script if it's executed directly from the command line +if (require.main === module) { + run(); +} + +// Export the run function for testing purposes +module.exports = { run }; diff --git a/.github/workflows/pr-labels.yml b/.github/workflows/pr-labels.yml index 8ab5e4982fb..5480199544a 100644 --- a/.github/workflows/pr-labels.yml +++ b/.github/workflows/pr-labels.yml @@ -11,44 +11,16 @@ jobs: issues: write pull-requests: write steps: - - name: Comment on PR - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 - with: - script: | - const labelsToCheck = ["crib"]; - const { owner, repo, number: prNumber } = context.issue; - const { data: labels } = await github.rest.issues.listLabelsOnIssue({ owner, repo, issue_number: prNumber }); - const labelMatches = labels.some(label => labelsToCheck.includes(label.name)); - - if (!labelMatches) { - core.info("No 'crib' PR label found. Proceeding."); - return; - } - - const comment = `## CRIB Environment Details :information_source: - - CRIB activated via the 'crib' label. To destroy the environment, remove the 'crib' PR label or close the PR. + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - Please review the following details: - - ### Subdomains - - _Use these subdomains to access the CRIB environment. They are prefixes to the internal base domain._ + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: 20 - - crib-chainlink-${prNumber}-node1. - - crib-chainlink-${prNumber}-node2. - - crib-chainlink-${prNumber}-node3. - - crib-chainlink-${prNumber}-node4. - - crib-chainlink-${prNumber}-node5. - - crib-chainlink-${prNumber}-node6. - - crib-chainlink-${prNumber}-geth-http. - - crib-chainlink-${prNumber}-geth-ws. - - crib-chainlink-${prNumber}-mockserver. - `; + - run: npm ci + working-directory: ./.github/scripts/crib - await github.rest.issues.createComment({ - owner, - repo, - issue_number: prNumber, - body: comment - }); + - name: Comment CRIB details on PR + run: ./.github/scripts/crib/pr-comment-crib-env.js + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From f5ed66cde8878475aa36ac4a41b2de90e9a52f44 Mon Sep 17 00:00:00 2001 From: Tate Date: Mon, 4 Mar 2024 15:53:31 -0700 Subject: [PATCH 11/34] [TT-941] Add postgres version config to test toml (#12281) --- .../action.yml | 5 +++++ .../actions/setup-create-base64-config/action.yml | 5 +++++ .../setup-create-base64-upgrade-config/action.yml | 5 +++++ .github/actions/setup-merge-base64-config/action.yml | 12 ++++++++++-- .github/actions/setup-parse-base64-config/action.yml | 12 ++++++++++-- integration-tests/chaos/automation_chaos_test.go | 4 ++-- integration-tests/chaos/ocr2vrf_chaos_test.go | 4 ++-- integration-tests/chaos/ocr_chaos_test.go | 4 ++-- integration-tests/docker/test_env/test_env.go | 8 ++++++++ integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- .../load/automationv2_1/automationv2_1_test.go | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- integration-tests/reorg/automation_reorg_test.go | 4 ++-- integration-tests/smoke/ocr2vrf_test.go | 4 ++-- integration-tests/testconfig/default.toml | 3 +++ integration-tests/testconfig/testconfig.go | 2 +- 18 files changed, 65 insertions(+), 23 deletions(-) diff --git a/.github/actions/setup-create-base64-config-live-testnets/action.yml b/.github/actions/setup-create-base64-config-live-testnets/action.yml index 89d6a5e05d6..879dcce6df3 100644 --- a/.github/actions/setup-create-base64-config-live-testnets/action.yml +++ b/.github/actions/setup-create-base64-config-live-testnets/action.yml @@ -12,6 +12,9 @@ inputs: default: "public.ecr.aws/chainlink/chainlink" chainlinkVersion: description: The git commit sha to use for the image tag + chainlinkPostgresVersion: + description: The postgres version to use with the chainlink node + default: "15.6" pyroscopeServer: description: URL of Pyroscope server pyroscopeEnvironment: @@ -52,6 +55,7 @@ runs: PYROSCOPE_KEY: ${{ inputs.pyroscopeKey }} CHAINLINK_IMAGE: ${{ inputs.chainlinkImage }} CHAINLINK_VERSION: ${{ inputs.chainlinkVersion }} + CHAINLINK_POSTGRES_VERSION: ${{ inputs.chainlinkPostgresVersion }} LOKI_ENDPOINT: ${{ inputs.lokiEndpoint }} LOKI_TENANT_ID: ${{ inputs.lokiTenantId }} LOKI_BASIC_AUTH: ${{ inputs.lokiBasicAuth }} @@ -89,6 +93,7 @@ runs: [ChainlinkImage] image="$CHAINLINK_IMAGE" version="$CHAINLINK_VERSION" + postgres_version="$CHAINLINK_POSTGRES_VERSION" [Pyroscope] enabled=$pyroscope_enabled diff --git a/.github/actions/setup-create-base64-config/action.yml b/.github/actions/setup-create-base64-config/action.yml index 013221bb41e..d68d4f7b12f 100644 --- a/.github/actions/setup-create-base64-config/action.yml +++ b/.github/actions/setup-create-base64-config/action.yml @@ -12,6 +12,9 @@ inputs: chainlinkImage: description: The chainlink image to use default: "public.ecr.aws/chainlink/chainlink" + chainlinkPostgresVersion: + description: The postgres version to use with the chainlink node + default: "15.6" chainlinkVersion: description: The git commit sha to use for the image tag pyroscopeServer: @@ -48,6 +51,7 @@ runs: PYROSCOPE_KEY: ${{ inputs.pyroscopeKey }} CHAINLINK_IMAGE: ${{ inputs.chainlinkImage }} CHAINLINK_VERSION: ${{ inputs.chainlinkVersion }} + CHAINLINK_POSTGRES_VERSION: ${{ inputs.chainlinkPostgresVersion }} LOKI_ENDPOINT: ${{ inputs.lokiEndpoint }} LOKI_TENANT_ID: ${{ inputs.lokiTenantId }} LOKI_BASIC_AUTH: ${{ inputs.lokiBasicAuth }} @@ -91,6 +95,7 @@ runs: [ChainlinkImage] image="$CHAINLINK_IMAGE" version="$CHAINLINK_VERSION" + postgres_version="$CHAINLINK_POSTGRES_VERSION" [Pyroscope] enabled=$pyroscope_enabled diff --git a/.github/actions/setup-create-base64-upgrade-config/action.yml b/.github/actions/setup-create-base64-upgrade-config/action.yml index 900b15e515a..daa2d400262 100644 --- a/.github/actions/setup-create-base64-upgrade-config/action.yml +++ b/.github/actions/setup-create-base64-upgrade-config/action.yml @@ -9,6 +9,9 @@ inputs: default: "public.ecr.aws/chainlink/chainlink" chainlinkVersion: description: The git commit sha to use for the image tag + chainlinkPostgresVersion: + description: The postgres version to use with the chainlink node + default: "15.6" upgradeImage: description: The chainlink image to upgrade to default: "public.ecr.aws/chainlink/chainlink" @@ -25,6 +28,7 @@ runs: SELECTED_NETWORKS: ${{ inputs.selectedNetworks }} CHAINLINK_IMAGE: ${{ inputs.chainlinkImage }} CHAINLINK_VERSION: ${{ inputs.chainlinkVersion }} + CHAINLINK_POSTGRES_VERSION: ${{ inputs.chainlinkPostgresVersion }} UPGRADE_IMAGE: ${{ inputs.upgradeImage }} UPGRADE_VERSION: ${{ inputs.upgradeVersion }} run: | @@ -50,6 +54,7 @@ runs: [ChainlinkImage] image="$CHAINLINK_IMAGE" version="$CHAINLINK_VERSION" + postgres_version="$CHAINLINK_POSTGRES_VERSION" [ChainlinkUpgradeImage] image="$UPGRADE_IMAGE" diff --git a/.github/actions/setup-merge-base64-config/action.yml b/.github/actions/setup-merge-base64-config/action.yml index d7e8d885c4f..43dcab940ab 100644 --- a/.github/actions/setup-merge-base64-config/action.yml +++ b/.github/actions/setup-merge-base64-config/action.yml @@ -8,6 +8,14 @@ inputs: runs: using: composite steps: + - name: Install dasel + shell: bash + run: | + if ! which dasel > /dev/null; then + curl -L -o dasel "https://github.com/TomWright/dasel/releases/download/v2.6.0/dasel_linux_amd64" && chmod +x dasel && sudo mv dasel /usr/local/bin/ + else + echo "Dasel is already installed." + fi - name: Add masks and export base64 config shell: bash run: | @@ -16,9 +24,9 @@ runs: echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV decoded_toml=$(echo $BASE64_CONFIG_OVERRIDE | base64 -d) - CHAINLINK_IMAGE=$(echo "$decoded_toml" | awk -F'=' '/^[[:space:]]*image[[:space:]]*=/ {gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2}' 2>/dev/null) + CHAINLINK_IMAGE=$(echo "$decoded_toml" | dasel -r toml 'ChainlinkImage.image') echo ::add-mask::$CHAINLINK_IMAGE - CHAINLINK_VERSION=$(echo "$decoded_toml" | awk -F'=' '/^[[:space:]]*version[[:space:]]*=/ {gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2}' 2>/dev/null) + CHAINLINK_VERSION=$(echo "$decoded_toml" | dasel -r toml 'ChainlinkImage.version') NETWORKS=$(echo "$decoded_toml" | awk -F'=' '/^[[:space:]]*selected_networks[[:space:]]*=/ {gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2}' 2>/dev/null) if [ -n "$CHAINLINK_IMAGE" ]; then diff --git a/.github/actions/setup-parse-base64-config/action.yml b/.github/actions/setup-parse-base64-config/action.yml index 3acd2ab8940..5e03c6de284 100644 --- a/.github/actions/setup-parse-base64-config/action.yml +++ b/.github/actions/setup-parse-base64-config/action.yml @@ -8,13 +8,21 @@ inputs: runs: using: composite steps: + - name: Install dasel + shell: bash + run: | + if ! which dasel > /dev/null; then + curl -L -o dasel "https://github.com/TomWright/dasel/releases/download/v2.6.0/dasel_linux_amd64" && chmod +x dasel && sudo mv dasel /usr/local/bin/ + else + echo "Dasel is already installed." + fi - name: Add masks and export base64 config shell: bash run: | decoded_toml=$(echo $BASE64_CONFIG_OVERRIDE | base64 -d) - CHAINLINK_IMAGE=$(echo "$decoded_toml" | awk -F'=' '/^[[:space:]]*image[[:space:]]*=/ {gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2}' 2>/dev/null) + CHAINLINK_IMAGE=$(echo "$decoded_toml" | dasel -r toml 'ChainlinkImage.image') echo ::add-mask::$CHAINLINK_IMAGE - CHAINLINK_VERSION=$(echo "$decoded_toml" | awk -F'=' '/^[[:space:]]*version[[:space:]]*=/ {gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2}' 2>/dev/null) + CHAINLINK_VERSION=$(echo "$decoded_toml" | dasel -r toml 'ChainlinkImage.version') NETWORKS=$(echo "$decoded_toml" | awk -F'=' '/^[[:space:]]*selected_networks[[:space:]]*=/ {gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2}' 2>/dev/null) ETH2_EL_CLIENT=$(echo "$decoded_toml" | awk -F'=' '/^[[:space:]]*execution_layer[[:space:]]*=/ {gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2}' 2>/dev/null) diff --git a/integration-tests/chaos/automation_chaos_test.go b/integration-tests/chaos/automation_chaos_test.go index f427b75f5a2..abfc026efc9 100644 --- a/integration-tests/chaos/automation_chaos_test.go +++ b/integration-tests/chaos/automation_chaos_test.go @@ -140,8 +140,8 @@ func TestAutomationChaos(t *testing.T) { } var overrideFn = func(_ interface{}, target interface{}) { - ctf_config.MustConfigOverrideChainlinkVersion(config.ChainlinkImage, target) - ctf_config.MightConfigOverridePyroscopeKey(config.Pyroscope, target) + ctf_config.MustConfigOverrideChainlinkVersion(config.GetChainlinkImageConfig(), target) + ctf_config.MightConfigOverridePyroscopeKey(config.GetPyroscopeConfig(), target) } chainlinkCfg := chainlink.NewWithOverride(0, getDefaultAutomationSettings(&config), config.ChainlinkImage, overrideFn) diff --git a/integration-tests/chaos/ocr2vrf_chaos_test.go b/integration-tests/chaos/ocr2vrf_chaos_test.go index eda60a37f3c..4869dbcabd3 100644 --- a/integration-tests/chaos/ocr2vrf_chaos_test.go +++ b/integration-tests/chaos/ocr2vrf_chaos_test.go @@ -57,8 +57,8 @@ func TestOCR2VRFChaos(t *testing.T) { } var overrideFn = func(_ interface{}, target interface{}) { - ctf_config.MustConfigOverrideChainlinkVersion(testconfig.ChainlinkImage, target) - ctf_config.MightConfigOverridePyroscopeKey(testconfig.Pyroscope, target) + ctf_config.MustConfigOverrideChainlinkVersion(testconfig.GetChainlinkImageConfig(), target) + ctf_config.MightConfigOverridePyroscopeKey(testconfig.GetPyroscopeConfig(), target) } chainlinkCfg := chainlink.NewWithOverride(0, defaultOCR2VRFSettings, testconfig.ChainlinkImage, overrideFn) diff --git a/integration-tests/chaos/ocr_chaos_test.go b/integration-tests/chaos/ocr_chaos_test.go index d667e32da34..b2adec04117 100644 --- a/integration-tests/chaos/ocr_chaos_test.go +++ b/integration-tests/chaos/ocr_chaos_test.go @@ -64,8 +64,8 @@ func TestOCRChaos(t *testing.T) { require.NoError(t, err, "Error getting config") var overrideFn = func(_ interface{}, target interface{}) { - ctf_config.MustConfigOverrideChainlinkVersion(config.ChainlinkImage, target) - ctf_config.MightConfigOverridePyroscopeKey(config.Pyroscope, target) + ctf_config.MustConfigOverrideChainlinkVersion(config.GetChainlinkImageConfig(), target) + ctf_config.MightConfigOverridePyroscopeKey(config.GetPyroscopeConfig(), target) } chainlinkCfg := chainlink.NewWithOverride(0, getDefaultOcrSettings(&config), config.ChainlinkImage, overrideFn) diff --git a/integration-tests/docker/test_env/test_env.go b/integration-tests/docker/test_env/test_env.go index beea1db983b..e91a3bba6ad 100644 --- a/integration-tests/docker/test_env/test_env.go +++ b/integration-tests/docker/test_env/test_env.go @@ -160,6 +160,14 @@ func (te *CLClusterTestEnv) StartClCluster(nodeConfig *chainlink.Config, count i if te.Cfg != nil && te.Cfg.ClCluster != nil { te.ClCluster = te.Cfg.ClCluster } else { + // prepend the postgres version option from the toml config + if testconfig.GetChainlinkImageConfig().PostgresVersion != nil && *testconfig.GetChainlinkImageConfig().PostgresVersion != "" { + opts = append([]func(c *ClNode){ + func(c *ClNode) { + c.PostgresDb.EnvComponent.ContainerVersion = *testconfig.GetChainlinkImageConfig().PostgresVersion + }, + }, opts...) + } opts = append(opts, WithSecrets(secretsConfig), WithLogStream(te.LogStream)) te.ClCluster = &ClCluster{} for i := 0; i < count; i++ { diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 4d46367ec9f..a44b239a655 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -24,7 +24,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 github.com/smartcontractkit/chainlink-common v0.1.7-0.20240227191958-d13aad8b4d61 - github.com/smartcontractkit/chainlink-testing-framework v1.25.0 + github.com/smartcontractkit/chainlink-testing-framework v1.25.1 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240229181116-bfb2432a7a66 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 2626cf0e8b2..d65d5e318c5 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1528,8 +1528,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e/go.mod h1:JiykN+8W5TA4UD2ClrzQCVvcH3NcyLEVv7RwY0busrw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 h1:7m9PVtccb8/pvKTXMaGuyceFno1icRyC2SFH7KG7+70= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0/go.mod h1:SZ899lZYQ0maUulWbZg+SWqabHQ1wTbyk3jT8wJfyo8= -github.com/smartcontractkit/chainlink-testing-framework v1.25.0 h1:Thc9TEKH1O6rkHvl2L+Y8s4WuulSfjLsIy0XwaJ6HZE= -github.com/smartcontractkit/chainlink-testing-framework v1.25.0/go.mod h1:gkmsafC85u6hIqWbxKjynKf4NuFuFJDRcgxIEFsSq6E= +github.com/smartcontractkit/chainlink-testing-framework v1.25.1 h1:SEpP7yvsShsAHTVhbxS2srOWi5StrslM4niAWJC9o4E= +github.com/smartcontractkit/chainlink-testing-framework v1.25.1/go.mod h1:gkmsafC85u6hIqWbxKjynKf4NuFuFJDRcgxIEFsSq6E= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= diff --git a/integration-tests/load/automationv2_1/automationv2_1_test.go b/integration-tests/load/automationv2_1/automationv2_1_test.go index ffce754c9de..fc7166b2189 100644 --- a/integration-tests/load/automationv2_1/automationv2_1_test.go +++ b/integration-tests/load/automationv2_1/automationv2_1_test.go @@ -245,8 +245,8 @@ Load Config: nodeTOML = networks.AddNetworksConfig(nodeTOML, loadedTestConfig.Pyroscope, testNetwork) var overrideFn = func(_ interface{}, target interface{}) { - ctfconfig.MustConfigOverrideChainlinkVersion(loadedTestConfig.ChainlinkImage, target) - ctfconfig.MightConfigOverridePyroscopeKey(loadedTestConfig.Pyroscope, target) + ctfconfig.MustConfigOverrideChainlinkVersion(loadedTestConfig.GetChainlinkImageConfig(), target) + ctfconfig.MightConfigOverridePyroscopeKey(loadedTestConfig.GetPyroscopeConfig(), target) } cd := chainlink.NewWithOverride(i, map[string]any{ diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 6fbcc8ff43b..7a4c60b42f8 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 github.com/smartcontractkit/chainlink-common v0.1.7-0.20240227191958-d13aad8b4d61 - github.com/smartcontractkit/chainlink-testing-framework v1.25.0 + github.com/smartcontractkit/chainlink-testing-framework v1.25.1 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 github.com/smartcontractkit/libocr v0.0.0-20240229181116-bfb2432a7a66 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index c179a284377..ed13d29e575 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1511,8 +1511,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e/go.mod h1:JiykN+8W5TA4UD2ClrzQCVvcH3NcyLEVv7RwY0busrw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0 h1:7m9PVtccb8/pvKTXMaGuyceFno1icRyC2SFH7KG7+70= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240213121419-1272736c2ac0/go.mod h1:SZ899lZYQ0maUulWbZg+SWqabHQ1wTbyk3jT8wJfyo8= -github.com/smartcontractkit/chainlink-testing-framework v1.25.0 h1:Thc9TEKH1O6rkHvl2L+Y8s4WuulSfjLsIy0XwaJ6HZE= -github.com/smartcontractkit/chainlink-testing-framework v1.25.0/go.mod h1:gkmsafC85u6hIqWbxKjynKf4NuFuFJDRcgxIEFsSq6E= +github.com/smartcontractkit/chainlink-testing-framework v1.25.1 h1:SEpP7yvsShsAHTVhbxS2srOWi5StrslM4niAWJC9o4E= +github.com/smartcontractkit/chainlink-testing-framework v1.25.1/go.mod h1:gkmsafC85u6hIqWbxKjynKf4NuFuFJDRcgxIEFsSq6E= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240227164431-18a7065e23ea h1:ZdLmNAfKRjH8AYUvjiiDGUgiWQfq/7iNpxyTkvjx/ko= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240227164431-18a7065e23ea/go.mod h1:gCKC9w6XpNk6jm+XIk2psrkkfxhi421N9NSiFceXW88= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= diff --git a/integration-tests/reorg/automation_reorg_test.go b/integration-tests/reorg/automation_reorg_test.go index 643101dfb92..aa1cb6bcde0 100644 --- a/integration-tests/reorg/automation_reorg_test.go +++ b/integration-tests/reorg/automation_reorg_test.go @@ -151,8 +151,8 @@ func TestAutomationReorg(t *testing.T) { defaultAutomationSettings["toml"] = networks.AddNetworkDetailedConfig(baseTOML, config.Pyroscope, networkTOML, network) var overrideFn = func(_ interface{}, target interface{}) { - ctf_config.MustConfigOverrideChainlinkVersion(config.ChainlinkImage, target) - ctf_config.MightConfigOverridePyroscopeKey(config.Pyroscope, target) + ctf_config.MustConfigOverrideChainlinkVersion(config.GetChainlinkImageConfig(), target) + ctf_config.MightConfigOverridePyroscopeKey(config.GetPyroscopeConfig(), target) } cd := chainlink.NewWithOverride(0, defaultAutomationSettings, config.ChainlinkImage, overrideFn) diff --git a/integration-tests/smoke/ocr2vrf_test.go b/integration-tests/smoke/ocr2vrf_test.go index c01ac46fbbc..3f9a7e3649a 100644 --- a/integration-tests/smoke/ocr2vrf_test.go +++ b/integration-tests/smoke/ocr2vrf_test.go @@ -183,8 +183,8 @@ func setupOCR2VRFEnvironment(t *testing.T) (testEnvironment *environment.Environ } var overrideFn = func(_ interface{}, target interface{}) { - ctf_config.MustConfigOverrideChainlinkVersion(ocr2vrfSmokeConfig.ChainlinkImage, target) - ctf_config.MightConfigOverridePyroscopeKey(ocr2vrfSmokeConfig.Pyroscope, target) + ctf_config.MustConfigOverrideChainlinkVersion(ocr2vrfSmokeConfig.GetChainlinkImageConfig(), target) + ctf_config.MightConfigOverridePyroscopeKey(ocr2vrfSmokeConfig.GetPyroscopeConfig(), target) } cd := chainlink.NewWithOverride(0, map[string]interface{}{ diff --git a/integration-tests/testconfig/default.toml b/integration-tests/testconfig/default.toml index 26b68fd4f1f..34051aff5e8 100644 --- a/integration-tests/testconfig/default.toml +++ b/integration-tests/testconfig/default.toml @@ -6,6 +6,9 @@ log_targets=["file"] log_producer_timeout="10s" log_producer_retry_limit=10 +[ChainlinkImage] +postgres_version="15.6" + [Network] selected_networks=["simulated"] diff --git a/integration-tests/testconfig/testconfig.go b/integration-tests/testconfig/testconfig.go index 0de5e12f489..89749c6ca1c 100644 --- a/integration-tests/testconfig/testconfig.go +++ b/integration-tests/testconfig/testconfig.go @@ -418,7 +418,7 @@ func (c *TestConfig) readNetworkConfiguration() error { func (c *TestConfig) Validate() error { defer func() { if r := recover(); r != nil { - panic(fmt.Errorf("Panic during test config validation: '%v'. Most probably due to presence of partial product config", r)) + panic(fmt.Errorf("panic during test config validation: '%v'. Most probably due to presence of partial product config", r)) } }() if c.ChainlinkImage == nil { From 89d0ad1586a16ecd96572d86170e8b3fe7c27bc9 Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Mon, 4 Mar 2024 18:26:46 -0500 Subject: [PATCH 12/34] fix arb gas info vendor and arb module (#12282) * fix arb gas info vendor and arb module * linting --- .../automation/dev/chains/ArbitrumModule.sol | 4 +- .../src/precompiles/ArbGasInfo.sol | 183 ++++++++++++++---- .../automation/AutomationRegistry2_2.test.ts | 18 +- .../arbitrum_module/arbitrum_module.go | 2 +- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 5 files changed, 158 insertions(+), 51 deletions(-) diff --git a/contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol b/contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol index b151ec8a26d..fad7e459c63 100644 --- a/contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol +++ b/contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol @@ -36,8 +36,8 @@ contract ArbitrumModule is ChainModuleBase { } function getMaxL1Fee(uint256 dataSize) external view override returns (uint256) { - (, uint256 perL1CalldataUnit, , , , ) = ARB_GAS.getPricesInWei(); - return perL1CalldataUnit * dataSize * 16; + (, uint256 perL1CalldataByte, , , , ) = ARB_GAS.getPricesInWei(); + return perL1CalldataByte * dataSize; } function getGasOverhead() diff --git a/contracts/src/v0.8/vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol b/contracts/src/v0.8/vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol index 19d29c88a8e..0517df276b0 100644 --- a/contracts/src/v0.8/vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol +++ b/contracts/src/v0.8/vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol @@ -1,43 +1,152 @@ // Copyright 2021-2022, Offchain Labs, Inc. -// For license information, see https://github.com/nitro/blob/master/LICENSE +// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.4.21 <0.9.0; +/// @title Provides insight into the cost of using the chain. +/// @notice These methods have been adjusted to account for Nitro's heavy use of calldata compression. +/// Of note to end-users, we no longer make a distinction between non-zero and zero-valued calldata bytes. +/// Precompiled contract that exists in every Arbitrum chain at 0x000000000000000000000000000000000000006c. interface ArbGasInfo { - // return gas prices in wei, assuming the specified aggregator is used - // ( - // per L2 tx, - // per L1 calldata unit, (zero byte = 4 units, nonzero byte = 16 units) - // per storage allocation, - // per ArbGas base, - // per ArbGas congestion, - // per ArbGas total - // ) - function getPricesInWeiWithAggregator(address aggregator) external view returns (uint, uint, uint, uint, uint, uint); - - // return gas prices in wei, as described above, assuming the caller's preferred aggregator is used - // if the caller hasn't specified a preferred aggregator, the default aggregator is assumed - function getPricesInWei() external view returns (uint, uint, uint, uint, uint, uint); - - // return prices in ArbGas (per L2 tx, per L1 calldata unit, per storage allocation), - // assuming the specified aggregator is used - function getPricesInArbGasWithAggregator(address aggregator) external view returns (uint, uint, uint); - - // return gas prices in ArbGas, as described above, assuming the caller's preferred aggregator is used - // if the caller hasn't specified a preferred aggregator, the default aggregator is assumed - function getPricesInArbGas() external view returns (uint, uint, uint); - - // return gas accounting parameters (speedLimitPerSecond, gasPoolMax, maxTxGasLimit) - function getGasAccountingParams() external view returns (uint, uint, uint); - - // get ArbOS's estimate of the L1 gas price in wei - function getL1GasPriceEstimate() external view returns(uint); - - // set ArbOS's estimate of the L1 gas price in wei - // reverts unless called by chain owner or designated gas oracle (if any) - function setL1GasPriceEstimate(uint priceInWei) external; - - // get L1 gas fees paid by the current transaction (txBaseFeeWei, calldataFeeWei) - function getCurrentTxL1GasFees() external view returns(uint); -} + /// @notice Get gas prices for a provided aggregator + /// @return return gas prices in wei + /// ( + /// per L2 tx, + /// per L1 calldata byte + /// per storage allocation, + /// per ArbGas base, + /// per ArbGas congestion, + /// per ArbGas total + /// ) + function getPricesInWeiWithAggregator(address aggregator) + external + view + returns ( + uint256, + uint256, + uint256, + uint256, + uint256, + uint256 + ); + + /// @notice Get gas prices. Uses the caller's preferred aggregator, or the default if the caller doesn't have a preferred one. + /// @return return gas prices in wei + /// ( + /// per L2 tx, + /// per L1 calldata byte + /// per storage allocation, + /// per ArbGas base, + /// per ArbGas congestion, + /// per ArbGas total + /// ) + function getPricesInWei() + external + view + returns ( + uint256, + uint256, + uint256, + uint256, + uint256, + uint256 + ); + + /// @notice Get prices in ArbGas for the supplied aggregator + /// @return (per L2 tx, per L1 calldata byte, per storage allocation) + function getPricesInArbGasWithAggregator(address aggregator) + external + view + returns ( + uint256, + uint256, + uint256 + ); + + /// @notice Get prices in ArbGas. Assumes the callers preferred validator, or the default if caller doesn't have a preferred one. + /// @return (per L2 tx, per L1 calldata byte, per storage allocation) + function getPricesInArbGas() + external + view + returns ( + uint256, + uint256, + uint256 + ); + + /// @notice Get the gas accounting parameters. `gasPoolMax` is always zero, as the exponential pricing model has no such notion. + /// @return (speedLimitPerSecond, gasPoolMax, maxTxGasLimit) + function getGasAccountingParams() + external + view + returns ( + uint256, + uint256, + uint256 + ); + + /// @notice Get the minimum gas price needed for a tx to succeed + function getMinimumGasPrice() external view returns (uint256); + + /// @notice Get ArbOS's estimate of the L1 basefee in wei + function getL1BaseFeeEstimate() external view returns (uint256); + + /// @notice Get how slowly ArbOS updates its estimate of the L1 basefee + function getL1BaseFeeEstimateInertia() external view returns (uint64); + + /// @notice Get the L1 pricer reward rate, in wei per unit + /// Available in ArbOS version 11 + function getL1RewardRate() external view returns (uint64); + + /// @notice Get the L1 pricer reward recipient + /// Available in ArbOS version 11 + function getL1RewardRecipient() external view returns (address); + + /// @notice Deprecated -- Same as getL1BaseFeeEstimate() + function getL1GasPriceEstimate() external view returns (uint256); + + /// @notice Get L1 gas fees paid by the current transaction + function getCurrentTxL1GasFees() external view returns (uint256); + + /// @notice Get the backlogged amount of gas burnt in excess of the speed limit + function getGasBacklog() external view returns (uint64); + + /// @notice Get how slowly ArbOS updates the L2 basefee in response to backlogged gas + function getPricingInertia() external view returns (uint64); + + /// @notice Get the forgivable amount of backlogged gas ArbOS will ignore when raising the basefee + function getGasBacklogTolerance() external view returns (uint64); + + /// @notice Returns the surplus of funds for L1 batch posting payments (may be negative). + function getL1PricingSurplus() external view returns (int256); + + /// @notice Returns the base charge (in L1 gas) attributed to each data batch in the calldata pricer + function getPerBatchGasCharge() external view returns (int64); + + /// @notice Returns the cost amortization cap in basis points + function getAmortizedCostCapBips() external view returns (uint64); + + /// @notice Returns the available funds from L1 fees + function getL1FeesAvailable() external view returns (uint256); + + /// @notice Returns the equilibration units parameter for L1 price adjustment algorithm + /// Available in ArbOS version 20 + function getL1PricingEquilibrationUnits() external view returns (uint256); + + /// @notice Returns the last time the L1 calldata pricer was updated. + /// Available in ArbOS version 20 + function getLastL1PricingUpdateTime() external view returns (uint64); + + /// @notice Returns the amount of L1 calldata payments due for rewards (per the L1 reward rate) + /// Available in ArbOS version 20 + function getL1PricingFundsDueForRewards() external view returns (uint256); + + /// @notice Returns the amount of L1 calldata posted since the last update. + /// Available in ArbOS version 20 + function getL1PricingUnitsSinceUpdate() external view returns (uint64); + + /// @notice Returns the L1 pricing surplus as of the last update (may be negative). + /// Available in ArbOS version 20 + function getLastL1PricingSurplus() external view returns (int256); +} \ No newline at end of file diff --git a/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts b/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts index ef6fe6616ab..512956ed4ee 100644 --- a/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts +++ b/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts @@ -3421,17 +3421,15 @@ describe('AutomationRegistry2_2', () => { beforeEach(async () => { const arbL1PriceinWei = BigNumber.from(1000) // Same as MockArbGasInfo.sol - maxl1CostWeiArbWithoutMultiplier = arbL1PriceinWei - .mul(16) - .mul( - maxPerformDataSize - .add(registryTransmitCalldataFixedBytesOverhead) - .add( - registryTransmitCalldataPerSignerBytesOverhead.mul( - BigNumber.from(f + 1), - ), + maxl1CostWeiArbWithoutMultiplier = arbL1PriceinWei.mul( + maxPerformDataSize + .add(registryTransmitCalldataFixedBytesOverhead) + .add( + registryTransmitCalldataPerSignerBytesOverhead.mul( + BigNumber.from(f + 1), ), - ) + ), + ) maxl1CostWeiOptWithoutMultiplier = BigNumber.from(2000000) // Same as MockOVMGasPriceOracle.sol }) diff --git a/core/gethwrappers/generated/arbitrum_module/arbitrum_module.go b/core/gethwrappers/generated/arbitrum_module/arbitrum_module.go index 8da8f57d5fa..537fbe21544 100644 --- a/core/gethwrappers/generated/arbitrum_module/arbitrum_module.go +++ b/core/gethwrappers/generated/arbitrum_module/arbitrum_module.go @@ -30,7 +30,7 @@ var ( var ArbitrumModuleMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"blockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainModuleFixedOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"chainModulePerByteOverhead\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"dataSize\",\"type\":\"uint256\"}],\"name\":\"getMaxL1Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b50610426806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c806357e871e71161005057806357e871e71461009a57806385df51fd146100a2578063de9ee35e146100b557600080fd5b8063125441401461006c57806318b8f61314610092575b600080fd5b61007f61007a36600461033e565b6100cb565b6040519081526020015b60405180910390f35b61007f610163565b61007f6101da565b61007f6100b036600461033e565b610228565b6040805161138881526000602082015201610089565b600080606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c060405180830381865afa15801561011a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061013e9190610357565b50505050915050828161015191906103d0565b61015c9060106103d0565b9392505050565b6000606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d591906103ed565b905090565b6000606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b1573d6000803e3d6000fd5b600080606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610277573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029b91906103ed565b905080831015806102b657506101006102b48483610406565b115b156102c45750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815260048101849052606490632b407a8290602401602060405180830381865afa15801561031a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061015c91906103ed565b60006020828403121561035057600080fd5b5035919050565b60008060008060008060c0878903121561037057600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176103e7576103e76103a1565b92915050565b6000602082840312156103ff57600080fd5b5051919050565b818103818111156103e7576103e76103a156fea164736f6c6343000813000a", + Bin: "0x608060405234801561001057600080fd5b5061041b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c806357e871e71161005057806357e871e71461009a57806385df51fd146100a2578063de9ee35e146100b557600080fd5b8063125441401461006c57806318b8f61314610092575b600080fd5b61007f61007a366004610333565b6100cb565b6040519081526020015b60405180910390f35b61007f610158565b61007f6101cf565b61007f6100b0366004610333565b61021d565b6040805161138881526000602082015201610089565b600080606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c060405180830381865afa15801561011a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061013e919061034c565b50505050915050828161015191906103c5565b9392505050565b6000606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101ca91906103e2565b905090565b6000606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101a6573d6000803e3d6000fd5b600080606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561026c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029091906103e2565b905080831015806102ab57506101006102a984836103fb565b115b156102b95750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815260048101849052606490632b407a8290602401602060405180830381865afa15801561030f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061015191906103e2565b60006020828403121561034557600080fd5b5035919050565b60008060008060008060c0878903121561036557600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176103dc576103dc610396565b92915050565b6000602082840312156103f457600080fd5b5051919050565b818103818111156103dc576103dc61039656fea164736f6c6343000813000a", } var ArbitrumModuleABI = ArbitrumModuleMetaData.ABI diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 054f55e6e27..f060457e0eb 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,7 +1,7 @@ GETH_VERSION: 1.13.8 aggregator_v2v3_interface: ../../contracts/solc/v0.8.6/AggregatorV2V3Interface/AggregatorV2V3Interface.abi ../../contracts/solc/v0.8.6/AggregatorV2V3Interface/AggregatorV2V3Interface.bin 95e8814b408bb05bf21742ef580d98698b7db6a9bac6a35c3de12b23aec4ee28 aggregator_v3_interface: ../../contracts/solc/v0.8.6/AggregatorV2V3Interface/AggregatorV3Interface.abi ../../contracts/solc/v0.8.6/AggregatorV2V3Interface/AggregatorV3Interface.bin 351b55d3b0f04af67db6dfb5c92f1c64479400ca1fec77afc20bc0ce65cb49ab -arbitrum_module: ../../contracts/solc/v0.8.19/ArbitrumModule/ArbitrumModule.abi ../../contracts/solc/v0.8.19/ArbitrumModule/ArbitrumModule.bin 9615cb0e524e6ca87e86e1714420c08d4de6f6407bfb5546da04ac7dea7f9107 +arbitrum_module: ../../contracts/solc/v0.8.19/ArbitrumModule/ArbitrumModule.abi ../../contracts/solc/v0.8.19/ArbitrumModule/ArbitrumModule.bin b76cf77e3e8200c5f292e93af3f620f68f207f83634aacaaee43d682701dfea3 authorized_forwarder: ../../contracts/solc/v0.8.19/AuthorizedForwarder/AuthorizedForwarder.abi ../../contracts/solc/v0.8.19/AuthorizedForwarder/AuthorizedForwarder.bin 8ea76c883d460f8353a45a493f2aebeb5a2d9a7b4619d1bc4fff5fb590bb3e10 authorized_receiver: ../../contracts/solc/v0.8.19/AuthorizedReceiver/AuthorizedReceiver.abi ../../contracts/solc/v0.8.19/AuthorizedReceiver/AuthorizedReceiver.bin 18e8969ba3234b027e1b16c11a783aca58d0ea5c2361010ec597f134b7bf1c4f automation_consumer_benchmark: ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark/AutomationConsumerBenchmark.abi ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark/AutomationConsumerBenchmark.bin f52c76f1aaed4be541d82d97189d70f5aa027fc9838037dd7a7d21910c8c488e From 1a788b94b0e4eb94677cb614c09e79818c754ca2 Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Mon, 4 Mar 2024 18:55:03 -0500 Subject: [PATCH 13/34] populate core node from address for registry (#12291) --- .../ocr2keeper/evmregistry/v21/mercury/streams/streams.go | 5 +++++ .../evmregistry/v21/mercury/streams/streams_test.go | 4 ++++ .../ocr2keeper/evmregistry/v21/registry_check_pipeline.go | 3 +++ integration-tests/contracts/contract_deployer.go | 2 -- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/streams/streams.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/streams/streams.go index a63c15408a5..843091ea7a0 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/streams/streams.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/streams/streams.go @@ -28,6 +28,10 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/utils" ) +const ( + zeroAddress = "0x0000000000000000000000000000000000000000" +) + type Lookup interface { Lookup(ctx context.Context, checkResults []ocr2keepers.CheckResult) []ocr2keepers.CheckResult } @@ -208,6 +212,7 @@ func (s *streams) CheckCallback(ctx context.Context, values [][]byte, lookup *me func (s *streams) makeCallbackEthCall(ctx context.Context, payload []byte, lookup *mercury.StreamsLookup, checkResults []ocr2keepers.CheckResult, i int) error { var responseBytes hexutil.Bytes args := map[string]interface{}{ + "from": zeroAddress, "to": s.registry.Address().Hex(), "data": hexutil.Bytes(payload), } diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/streams/streams_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/streams/streams_test.go index e67540a7f2b..6a4aa69ec4d 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/streams/streams_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury/streams/streams_test.go @@ -17,6 +17,7 @@ import ( "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/mercury" @@ -243,6 +244,7 @@ func TestStreams_CheckErrorHandler(t *testing.T) { require.Nil(t, err) args := map[string]interface{}{ + "from": zeroAddress, "to": s.registry.Address().Hex(), "data": hexutil.Bytes(payload), } @@ -397,6 +399,7 @@ func TestStreams_CheckCallback(t *testing.T) { payload, err := s.abi.Pack("checkCallback", tt.lookup.UpkeepId, values, tt.lookup.ExtraData) require.Nil(t, err) args := map[string]interface{}{ + "from": zeroAddress, "to": s.registry.Address().Hex(), "data": hexutil.Bytes(payload), } @@ -948,6 +951,7 @@ func TestStreams_StreamsLookup(t *testing.T) { payload, err := s.abi.Pack("checkCallback", upkeepId, tt.values, tt.extraData) require.Nil(t, err) args := map[string]interface{}{ + "from": zeroAddress, "to": s.registry.Address().Hex(), "data": hexutil.Bytes(payload), } diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry_check_pipeline.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry_check_pipeline.go index 6a09ae1aca3..3e935d0adf1 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry_check_pipeline.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry_check_pipeline.go @@ -22,6 +22,7 @@ const ( // checkBlockTooOldRange is the number of blocks that can be behind the latest block before // we return a CheckBlockTooOld error checkBlockTooOldRange = 128 + zeroAddress = "0x0000000000000000000000000000000000000000" ) type checkResult struct { @@ -233,6 +234,7 @@ func (r *EvmRegistry) checkUpkeeps(ctx context.Context, payloads []ocr2keepers.U Method: "eth_call", Args: []interface{}{ map[string]interface{}{ + "from": zeroAddress, "to": r.addr.Hex(), "data": hexutil.Bytes(payload), }, @@ -320,6 +322,7 @@ func (r *EvmRegistry) simulatePerformUpkeeps(ctx context.Context, checkResults [ Method: "eth_call", Args: []interface{}{ map[string]interface{}{ + "from": zeroAddress, "to": r.addr.Hex(), "data": hexutil.Bytes(payload), }, diff --git a/integration-tests/contracts/contract_deployer.go b/integration-tests/contracts/contract_deployer.go index 1cf2a6bede2..8bf720cdb10 100644 --- a/integration-tests/contracts/contract_deployer.go +++ b/integration-tests/contracts/contract_deployer.go @@ -1268,8 +1268,6 @@ func (e *EthereumContractDeployer) DeployKeeperRegistry( var allowedReadOnlyAddress common.Address if chainId == networks.PolygonZkEvmMainnet.ChainID || chainId == networks.PolygonZkEvmCardona.ChainID { allowedReadOnlyAddress = common.HexToAddress("0x1111111111111111111111111111111111111111") - } else if chainId == networks.GnosisMainnet.ChainID || chainId == networks.GnosisChiado.ChainID { - allowedReadOnlyAddress = common.HexToAddress("0xfffffffffffffffffffffffffffffffffffffffe") } else { allowedReadOnlyAddress = common.HexToAddress("0x0000000000000000000000000000000000000000") } From 53857e7fb7afb6aff53457a7761137ae3053bd4d Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Tue, 5 Mar 2024 01:45:34 +0100 Subject: [PATCH 14/34] fix ttl docs (#12283) Co-authored-by: chainchad <96362174+chainchad@users.noreply.github.com> --- charts/chainlink-cluster/devspace.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/chainlink-cluster/devspace.yaml b/charts/chainlink-cluster/devspace.yaml index 4909d8ffb97..d2b412ba264 100644 --- a/charts/chainlink-cluster/devspace.yaml +++ b/charts/chainlink-cluster/devspace.yaml @@ -68,7 +68,7 @@ pipelines: --set=helm.values.chainlink.nodes[5].image=$image echo echo "Namespace ${DEVSPACE_NAMESPACE} will be deleted in ${NS_TTL}" - echo "To extend the TTL for e.g. 72 hours, run: devspace ttl ${DEVSPACE_NAMESPACE} 72h" + echo "To extend the TTL for e.g. 72 hours, run: devspace run ttl ${DEVSPACE_NAMESPACE} 72h" echo echo "############################################" From 1f16d03fcb034c3f5c1d5551e9dc1ad5c82e62e0 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Tue, 5 Mar 2024 08:21:03 -0600 Subject: [PATCH 15/34] golangci-lint: add depguard to disallow modules (#12200) --- .golangci.yml | 29 +++++++++++++++++++ core/chains/evm/types/types.go | 1 + core/scripts/go.mod | 1 - ...annel_definition_cache_integration_test.go | 2 +- core/services/relay/evm/types/types.go | 3 +- go.mod | 3 +- integration-tests/go.mod | 1 - integration-tests/go.sum | 2 -- integration-tests/load/go.mod | 1 - integration-tests/load/go.sum | 2 -- 10 files changed, 34 insertions(+), 11 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 71468b4975f..af8c27a7f8f 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -13,6 +13,7 @@ linters: - unconvert - sqlclosecheck - noctx + - depguard linters-settings: exhaustive: default-signifies-exhaustive: true @@ -78,6 +79,34 @@ linters-settings: # - name: confusing-results - name: bool-literal-in-expr - name: atomic + depguard: + rules: + main: + list-mode: lax + deny: + - pkg: cosmossdk.io/errors + desc: Use the standard library instead + - pkg: github.com/gofrs/uuid + desc: Use github.com/google/uuid instead + - pkg: github.com/satori/go.uuid + desc: Use github.com/google/uuid instead + - pkg: github.com/test-go/testify/assert + desc: Use github.com/stretchr/testify/assert instead + - pkg: github.com/test-go/testify/mock + desc: Use github.com/stretchr/testify/mock instead + - pkg: github.com/test-go/testify/require + desc: Use github.com/stretchr/testify/require instead +# TODO https://smartcontract-it.atlassian.net/browse/BCI-2589 +# - pkg: go.uber.org/multierr +# desc: Use the standard library instead, for example https://pkg.go.dev/errors#Join + - pkg: gopkg.in/guregu/null.v1 + desc: Use gopkg.in/guregu/null.v4 instead + - pkg: gopkg.in/guregu/null.v2 + desc: Use gopkg.in/guregu/null.v4 instead + - pkg: gopkg.in/guregu/null.v3 + desc: Use gopkg.in/guregu/null.v4 instead + - pkg: https://github.com/go-gorm/gorm + desc: Use github.com/jmoiron/sqlx directly instead issues: exclude-rules: - path: test diff --git a/core/chains/evm/types/types.go b/core/chains/evm/types/types.go index 89739e61e1b..0112dc80ee3 100644 --- a/core/chains/evm/types/types.go +++ b/core/chains/evm/types/types.go @@ -13,6 +13,7 @@ import ( "gopkg.in/guregu/null.v4" "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" ) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 6e08c980f4f..39560095094 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -317,7 +317,6 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect google.golang.org/grpc v1.59.0 // indirect google.golang.org/protobuf v1.32.0 // indirect - gopkg.in/guregu/null.v2 v2.1.2 // indirect gopkg.in/guregu/null.v4 v4.0.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect diff --git a/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go b/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go index c24ea46231d..418c5a90eb4 100644 --- a/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go +++ b/core/services/ocr2/plugins/llo/onchain_channel_definition_cache_integration_test.go @@ -9,8 +9,8 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth/ethconfig" chainselectors "github.com/smartcontractkit/chain-selectors" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/test-go/testify/assert" "go.uber.org/zap/zapcore" "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" diff --git a/core/services/relay/evm/types/types.go b/core/services/relay/evm/types/types.go index 0697605edab..aa6116b64bb 100644 --- a/core/services/relay/evm/types/types.go +++ b/core/services/relay/evm/types/types.go @@ -9,8 +9,9 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/lib/pq" + "gopkg.in/guregu/null.v4" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - "gopkg.in/guregu/null.v2" "github.com/smartcontractkit/chainlink-common/pkg/codec" "github.com/smartcontractkit/chainlink-common/pkg/services" diff --git a/go.mod b/go.mod index 75e1874d4d6..5cb8673e314 100644 --- a/go.mod +++ b/go.mod @@ -82,7 +82,6 @@ require ( github.com/smartcontractkit/wsrpc v0.7.2 github.com/spf13/cast v1.6.0 github.com/stretchr/testify v1.8.4 - github.com/test-go/testify v1.1.4 github.com/theodesp/go-heaps v0.0.0-20190520121037-88e35354fe0a github.com/tidwall/gjson v1.17.0 github.com/ugorji/go/codec v1.2.12 @@ -107,7 +106,6 @@ require ( gonum.org/v1/gonum v0.14.0 google.golang.org/grpc v1.59.0 google.golang.org/protobuf v1.32.0 - gopkg.in/guregu/null.v2 v2.1.2 gopkg.in/guregu/null.v4 v4.0.0 gopkg.in/natefinch/lumberjack.v2 v2.2.1 ) @@ -325,6 +323,7 @@ require ( google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect + gopkg.in/guregu/null.v2 v2.1.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/integration-tests/go.mod b/integration-tests/go.mod index a44b239a655..2f7ed16e3b2 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -458,7 +458,6 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect google.golang.org/grpc v1.59.0 // indirect google.golang.org/protobuf v1.32.0 // indirect - gopkg.in/guregu/null.v2 v2.1.2 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index d65d5e318c5..b5dda40ca97 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -2349,8 +2349,6 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= -gopkg.in/guregu/null.v2 v2.1.2 h1:YOuepWdYqGnrenzPyMi+ybCjeDzjdazynbwsXXOk4i8= -gopkg.in/guregu/null.v2 v2.1.2/go.mod h1:XORrx8tyS5ZDcyUboCIxQtta/Aujk/6pfWrn9Xe33mU= gopkg.in/guregu/null.v4 v4.0.0 h1:1Wm3S1WEA2I26Kq+6vcW+w0gcDo44YKYD7YIEJNHDjg= gopkg.in/guregu/null.v4 v4.0.0/go.mod h1:YoQhUrADuG3i9WqesrCmpNRwm1ypAgSHYqoOcTu/JrI= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 7a4c60b42f8..aed5be4806d 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -454,7 +454,6 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect google.golang.org/grpc v1.59.0 // indirect google.golang.org/protobuf v1.32.0 // indirect - gopkg.in/guregu/null.v2 v2.1.2 // indirect gopkg.in/guregu/null.v4 v4.0.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index ed13d29e575..bb3385b81f0 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -2334,8 +2334,6 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= -gopkg.in/guregu/null.v2 v2.1.2 h1:YOuepWdYqGnrenzPyMi+ybCjeDzjdazynbwsXXOk4i8= -gopkg.in/guregu/null.v2 v2.1.2/go.mod h1:XORrx8tyS5ZDcyUboCIxQtta/Aujk/6pfWrn9Xe33mU= gopkg.in/guregu/null.v4 v4.0.0 h1:1Wm3S1WEA2I26Kq+6vcW+w0gcDo44YKYD7YIEJNHDjg= gopkg.in/guregu/null.v4 v4.0.0/go.mod h1:YoQhUrADuG3i9WqesrCmpNRwm1ypAgSHYqoOcTu/JrI= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= From 30bf51af943115a9ec926c30a4d42a61568bac8d Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Tue, 5 Mar 2024 09:33:39 -0500 Subject: [PATCH 16/34] fix cancel upkeep by owner (#12290) * fix arb gas info vendor and arb module * linting * fix cancel upkeep by owner * fix tests * tidy up cancelUpkeep * update --- .../dev/v2_2/AutomationRegistryLogicA2_2.sol | 4 ++-- .../automation/AutomationRegistry2_2.test.ts | 17 ++++++++--------- .../automation_registry_logic_a_wrapper_2_2.go | 2 +- ...-wrapper-dependency-versions-do-not-edit.txt | 2 +- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicA2_2.sol b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicA2_2.sol index 645394e254f..b5269fcb63a 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicA2_2.sol +++ b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicA2_2.sol @@ -275,11 +275,11 @@ contract AutomationRegistryLogicA2_2 is AutomationRegistryBase2_2, Chainable { */ function cancelUpkeep(uint256 id) external { Upkeep memory upkeep = s_upkeep[id]; - bool canceled = upkeep.maxValidBlocknumber != UINT32_MAX; bool isOwner = msg.sender == owner(); uint256 height = s_hotVars.chainModule.blockNumber(); - if (canceled && !(isOwner && upkeep.maxValidBlocknumber > height)) revert CannotCancel(); + if (upkeep.maxValidBlocknumber == 0) revert CannotCancel(); + if (upkeep.maxValidBlocknumber != UINT32_MAX) revert UpkeepCancelled(); if (!isOwner && msg.sender != s_upkeepAdmin[id]) revert OnlyCallableByOwnerOrAdmin(); if (!isOwner) { diff --git a/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts b/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts index 512956ed4ee..365e61ed3e2 100644 --- a/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts +++ b/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts @@ -5212,7 +5212,7 @@ describe('AutomationRegistry2_2', () => { await registry.connect(owner).cancelUpkeep(upkeepId) await evmRevert( registry.connect(owner).cancelUpkeep(upkeepId), - 'CannotCancel()', + 'UpkeepCancelled()', ) }) @@ -5225,12 +5225,11 @@ describe('AutomationRegistry2_2', () => { oldExpiration = registration.maxValidBlocknumber }) - it('allows the owner to cancel it more quickly', async () => { - await registry.connect(owner).cancelUpkeep(upkeepId) - - const registration = await registry.getUpkeep(upkeepId) - const newExpiration = registration.maxValidBlocknumber - assert.isTrue(newExpiration.lt(oldExpiration)) + it('reverts with proper error', async () => { + await evmRevert( + registry.connect(owner).cancelUpkeep(upkeepId), + 'UpkeepCancelled()', + ) }) }) }) @@ -5241,7 +5240,7 @@ describe('AutomationRegistry2_2', () => { await evmRevert( registry.connect(admin).cancelUpkeep(upkeepId), - 'CannotCancel()', + 'UpkeepCancelled()', ) }) @@ -5254,7 +5253,7 @@ describe('AutomationRegistry2_2', () => { await evmRevert( registry.connect(owner).cancelUpkeep(upkeepId), - 'CannotCancel()', + 'UpkeepCancelled()', ) }) diff --git a/core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_2/automation_registry_logic_a_wrapper_2_2.go b/core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_2/automation_registry_logic_a_wrapper_2_2.go index 9d0abfc6252..4496ee2ab23 100644 --- a/core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_2/automation_registry_logic_a_wrapper_2_2.go +++ b/core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_2/automation_registry_logic_a_wrapper_2_2.go @@ -32,7 +32,7 @@ var ( var AutomationRegistryLogicAMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicB2_2\",\"name\":\"logicB\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_2.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_2.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_2.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"executeCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_2.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"migrateUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedUpkeeps\",\"type\":\"bytes\"}],\"name\":\"receiveUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"enumAutomationRegistryBase2_2.Trigger\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101406040523480156200001257600080fd5b5060405162005ee738038062005ee78339810160408190526200003591620003b1565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b9190620003b1565b826001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001009190620003b1565b836001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001659190620003b1565b846001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca9190620003b1565b856001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f9190620003b1565b3380600081620002865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620002b957620002b981620002ed565b5050506001600160a01b0394851660805292841660a05290831660c052821660e052811661010052166101205250620003d8565b336001600160a01b03821603620003475760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200027d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b0381168114620003ae57600080fd5b50565b600060208284031215620003c457600080fd5b8151620003d18162000398565b9392505050565b60805160a05160c05160e0516101005161012051615aaa6200043d6000396000818161010e01526101a9015260006131260152600081816103e10152611ffe0152600061330f015260006133f3015260008181611e40015261240c0152615aaa6000f3fe60806040523480156200001157600080fd5b50600436106200010c5760003560e01c806385c1b0ba11620000a5578063c8048022116200006f578063c804802214620002b7578063ce7dc5b414620002ce578063f2fde38b14620002e5578063f7d334ba14620002fc576200010c565b806385c1b0ba14620002535780638da5cb5b146200026a5780638e86139b1462000289578063948108f714620002a0576200010c565b80634ee88d3511620000e75780634ee88d3514620001ef5780636ded9eae146200020657806371791aa0146200021d57806379ba50971462000249576200010c565b806328f32f38146200015457806329c5efad146200017e578063349e8cca14620001a7575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156200014d573d6000f35b3d6000fd5b005b6200016b6200016536600462004045565b62000313565b6040519081526020015b60405180910390f35b620001956200018f3660046200412b565b6200068d565b60405162000175949392919062004253565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200162000175565b620001526200020036600462004290565b62000931565b6200016b62000217366004620042e0565b62000999565b620002346200022e3660046200412b565b620009ff565b60405162000175979695949392919062004393565b620001526200114d565b6200015262000264366004620043e5565b62001250565b60005473ffffffffffffffffffffffffffffffffffffffff16620001c9565b620001526200029a36600462004472565b62001ec1565b62000152620002b1366004620044d5565b62002249565b62000152620002c836600462004504565b620024dc565b62000195620002df366004620045da565b62002927565b62000152620002f636600462004651565b620029ed565b620002346200030d36600462004504565b62002a05565b6000805473ffffffffffffffffffffffffffffffffffffffff1633148015906200034757506200034560093362002a43565b155b156200037f576040517fd48b678b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff89163b620003ce576040517f09ee12d500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b620003d98662002a77565b9050600089307f00000000000000000000000000000000000000000000000000000000000000006040516200040e9062003dd1565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f08015801562000458573d6000803e3d6000fd5b5090506200051f826040518060e001604052806000151581526020018c63ffffffff16815260200163ffffffff801681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff168152602001600063ffffffff168152508a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92508a915062002d239050565b6015805474010000000000000000000000000000000000000000900463ffffffff169060146200054f83620046a0565b91906101000a81548163ffffffff021916908363ffffffff16021790555050817fbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d0128a8a604051620005c892919063ffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a2817fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d8787604051620006049291906200470f565b60405180910390a2817f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d5664856040516200063e919062004725565b60405180910390a2817f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf48508460405162000678919062004725565b60405180910390a25098975050505050505050565b600060606000806200069e6200310e565b600086815260046020908152604091829020825160e081018452815460ff811615158252610100810463ffffffff90811694830194909452650100000000008104841694820194909452690100000000000000000090930473ffffffffffffffffffffffffffffffffffffffff166060840152600101546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a0840152780100000000000000000000000000000000000000000000000090041660c08201525a9150600080826060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620007b8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007de919062004747565b73ffffffffffffffffffffffffffffffffffffffff166014600101600c9054906101000a900463ffffffff1663ffffffff168960405162000820919062004767565b60006040518083038160008787f1925050503d806000811462000860576040519150601f19603f3d011682016040523d82523d6000602084013e62000865565b606091505b50915091505a62000877908562004785565b935081620008a257600060405180602001604052806000815250600796509650965050505062000928565b80806020019051810190620008b89190620047f6565b909750955086620008e657600060405180602001604052806000815250600496509650965050505062000928565b601654865164010000000090910463ffffffff1610156200092457600060405180602001604052806000815250600596509650965050505062000928565b5050505b92959194509250565b6200093c8362003180565b6000838152601b6020526040902062000957828483620048eb565b50827f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d566483836040516200098c9291906200470f565b60405180910390a2505050565b6000620009f388888860008989604051806020016040528060008152508a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506200031392505050565b98975050505050505050565b60006060600080600080600062000a156200310e565b600062000a228a62003236565b905060006012604051806101600160405290816000820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160008201600c9054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160109054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160149054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160189054906101000a900462ffffff1662ffffff1662ffffff16815260200160008201601b9054906101000a900461ffff1661ffff1661ffff16815260200160008201601d9054906101000a900460ff1660ff1660ff16815260200160008201601e9054906101000a900460ff1615151515815260200160008201601f9054906101000a900460ff161515151581526020016001820160009054906101000a900460ff161515151581526020016001820160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090506000600460008d81526020019081526020016000206040518060e00160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160059054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160018201600c9054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff1681526020016001820160189054906101000a900463ffffffff1663ffffffff1663ffffffff168152505090508160e001511562000db7576000604051806020016040528060008152506009600084602001516000808263ffffffff169250995099509950995099509950995050505062001141565b604081015163ffffffff9081161462000e08576000604051806020016040528060008152506001600084602001516000808263ffffffff169250995099509950995099509950995050505062001141565b80511562000e4e576000604051806020016040528060008152506002600084602001516000808263ffffffff169250995099509950995099509950995050505062001141565b62000e5982620032ec565b8095508196505050600062000e76838584602001518989620034de565b9050806bffffffffffffffffffffffff168260a001516bffffffffffffffffffffffff16101562000ee0576000604051806020016040528060008152506006600085602001516000808263ffffffff1692509a509a509a509a509a509a509a505050505062001141565b600062000eef8e868f62003793565b90505a9850600080846060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000f47573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f6d919062004747565b73ffffffffffffffffffffffffffffffffffffffff166014600101600c9054906101000a900463ffffffff1663ffffffff168460405162000faf919062004767565b60006040518083038160008787f1925050503d806000811462000fef576040519150601f19603f3d011682016040523d82523d6000602084013e62000ff4565b606091505b50915091505a62001006908c62004785565b9a5081620010865760165481516801000000000000000090910463ffffffff1610156200106357505060408051602080820190925260008082529490910151939c509a50600899505063ffffffff90911695506200114192505050565b602090940151939b5060039a505063ffffffff9092169650620011419350505050565b808060200190518101906200109c9190620047f6565b909e509c508d620010dd57505060408051602080820190925260008082529490910151939c509a50600499505063ffffffff90911695506200114192505050565b6016548d5164010000000090910463ffffffff1610156200112e57505060408051602080820190925260008082529490910151939c509a50600599505063ffffffff90911695506200114192505050565b505050506020015163ffffffff16945050505b92959891949750929550565b60015473ffffffffffffffffffffffffffffffffffffffff163314620011d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600173ffffffffffffffffffffffffffffffffffffffff82166000908152601a602052604090205460ff1660038111156200128f576200128f620041e8565b14158015620012db5750600373ffffffffffffffffffffffffffffffffffffffff82166000908152601a602052604090205460ff166003811115620012d857620012d8620041e8565b14155b1562001313576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6014546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1662001373576040517fd12d7d8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000829003620013af576040517f2c2fc94100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081018290526000808567ffffffffffffffff81111562001406576200140662003ecc565b60405190808252806020026020018201604052801562001430578160200160208202803683370190505b50905060008667ffffffffffffffff81111562001451576200145162003ecc565b604051908082528060200260200182016040528015620014d857816020015b6040805160e08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181620014705790505b50905060008767ffffffffffffffff811115620014f957620014f962003ecc565b6040519080825280602002602001820160405280156200152e57816020015b6060815260200190600190039081620015185790505b50905060008867ffffffffffffffff8111156200154f576200154f62003ecc565b6040519080825280602002602001820160405280156200158457816020015b60608152602001906001900390816200156e5790505b50905060008967ffffffffffffffff811115620015a557620015a562003ecc565b604051908082528060200260200182016040528015620015da57816020015b6060815260200190600190039081620015c45790505b50905060005b8a81101562001bbe578b8b82818110620015fe57620015fe62004a13565b60209081029290920135600081815260048452604090819020815160e081018352815460ff811615158252610100810463ffffffff90811697830197909752650100000000008104871693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490931660c08401529a50909850620016dd90508962003180565b60608801516040517f1a5da6c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c8116600483015290911690631a5da6c890602401600060405180830381600087803b1580156200174d57600080fd5b505af115801562001762573d6000803e3d6000fd5b50505050878582815181106200177c576200177c62004a13565b6020026020010181905250600560008a815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16868281518110620017d057620017d062004a13565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015260008a815260079091526040902080546200180f9062004843565b80601f01602080910402602001604051908101604052809291908181526020018280546200183d9062004843565b80156200188e5780601f1062001862576101008083540402835291602001916200188e565b820191906000526020600020905b8154815290600101906020018083116200187057829003601f168201915b5050505050848281518110620018a857620018a862004a13565b6020026020010181905250601b60008a81526020019081526020016000208054620018d39062004843565b80601f0160208091040260200160405190810160405280929190818152602001828054620019019062004843565b8015620019525780601f10620019265761010080835404028352916020019162001952565b820191906000526020600020905b8154815290600101906020018083116200193457829003601f168201915b50505050508382815181106200196c576200196c62004a13565b6020026020010181905250601c60008a81526020019081526020016000208054620019979062004843565b80601f0160208091040260200160405190810160405280929190818152602001828054620019c59062004843565b801562001a165780601f10620019ea5761010080835404028352916020019162001a16565b820191906000526020600020905b815481529060010190602001808311620019f857829003601f168201915b505050505082828151811062001a305762001a3062004a13565b60200260200101819052508760a001516bffffffffffffffffffffffff168762001a5b919062004a42565b60008a815260046020908152604080832080547fffffff000000000000000000000000000000000000000000000000000000000016815560010180547fffffffff000000000000000000000000000000000000000000000000000000001690556007909152812091985062001ad1919062003ddf565b6000898152601b6020526040812062001aea9162003ddf565b6000898152601c6020526040812062001b039162003ddf565b600089815260066020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905562001b4460028a62003983565b5060a0880151604080516bffffffffffffffffffffffff909216825273ffffffffffffffffffffffffffffffffffffffff8c1660208301528a917fb38647142fbb1ea4c000fc4569b37a4e9a9f6313317b84ee3e5326c1a6cd06ff910160405180910390a28062001bb58162004a58565b915050620015e0565b508560195462001bcf919062004785565b60195560008b8b868167ffffffffffffffff81111562001bf35762001bf362003ecc565b60405190808252806020026020018201604052801562001c1d578160200160208202803683370190505b508988888860405160200162001c3b98979695949392919062004c1f565b60405160208183030381529060405290508973ffffffffffffffffffffffffffffffffffffffff16638e86139b6014600001600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c71249ab60038e73ffffffffffffffffffffffffffffffffffffffff1663aab9edd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001cf7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001d1d919062004cfe565b866040518463ffffffff1660e01b815260040162001d3e9392919062004d23565b600060405180830381865afa15801562001d5c573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405262001da4919081019062004d4a565b6040518263ffffffff1660e01b815260040162001dc2919062004725565b600060405180830381600087803b15801562001ddd57600080fd5b505af115801562001df2573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d81166004830152602482018b90527f000000000000000000000000000000000000000000000000000000000000000016925063a9059cbb91506044016020604051808303816000875af115801562001e8c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001eb2919062004d83565b50505050505050505050505050565b6002336000908152601a602052604090205460ff16600381111562001eea5762001eea620041e8565b1415801562001f2057506003336000908152601a602052604090205460ff16600381111562001f1d5762001f1d620041e8565b14155b1562001f58576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080808080808062001f6e888a018a62004f6e565b965096509650965096509650965060005b87518110156200223d57600073ffffffffffffffffffffffffffffffffffffffff1687828151811062001fb65762001fb662004a13565b60200260200101516060015173ffffffffffffffffffffffffffffffffffffffff1603620020ca5785818151811062001ff35762001ff362004a13565b6020026020010151307f00000000000000000000000000000000000000000000000000000000000000006040516200202b9062003dd1565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f08015801562002075573d6000803e3d6000fd5b508782815181106200208b576200208b62004a13565b60200260200101516060019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b62002182888281518110620020e357620020e362004a13565b602002602001015188838151811062002100576200210062004a13565b60200260200101518784815181106200211d576200211d62004a13565b60200260200101518785815181106200213a576200213a62004a13565b602002602001015187868151811062002157576200215762004a13565b602002602001015187878151811062002174576200217462004a13565b602002602001015162002d23565b87818151811062002197576200219762004a13565b60200260200101517f74931a144e43a50694897f241d973aecb5024c0e910f9bb80a163ea3c1cf5a71888381518110620021d557620021d562004a13565b602002602001015160a0015133604051620022209291906bffffffffffffffffffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a280620022348162004a58565b91505062001f7f565b50505050505050505050565b600082815260046020908152604091829020825160e081018452815460ff81161515825263ffffffff6101008204811694830194909452650100000000008104841694820185905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a083015278010000000000000000000000000000000000000000000000009004821660c0820152911462002347576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818160a001516200235991906200509f565b600084815260046020526040902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006bffffffffffffffffffffffff93841602179055601954620023c19184169062004a42565b6019556040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526bffffffffffffffffffffffff831660448201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906323b872dd906064016020604051808303816000875af11580156200246b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002491919062004d83565b506040516bffffffffffffffffffffffff83168152339084907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a3505050565b6000818152600460209081526040808320815160e081018352815460ff81161515825263ffffffff6101008204811695830195909552650100000000008104851693820184905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a083015278010000000000000000000000000000000000000000000000009004831660c08201529291141590620025c560005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161490506000601260010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa15801562002668573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200268e9190620050c7565b9050828015620026b25750818015620026b0575080846040015163ffffffff16115b155b15620026ea576040517ffbc0357800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b811580156200271d575060008581526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b1562002755576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816200276b576200276860328262004a42565b90505b6000858152600460205260409020805463ffffffff80841665010000000000027fffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffff90921691909117909155620027c79060029087906200398316565b5060145460808501516bffffffffffffffffffffffff918216916000911682111562002830576080860151620027fe9083620050e1565b90508560a001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff16111562002830575060a08501515b808660a00151620028429190620050e1565b600088815260046020526040902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006bffffffffffffffffffffffff93841602179055601554620028aa918391166200509f565b601580547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff9290921691909117905560405167ffffffffffffffff84169088907f91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f79118190600090a350505050505050565b600060606000806000634b56a42e60e01b8888886040516024016200294f9392919062005109565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050620029da89826200068d565b929c919b50995090975095505050505050565b620029f762003991565b62002a028162003a14565b50565b60006060600080600080600062002a2c8860405180602001604052806000815250620009ff565b959e949d50929b5090995097509550909350915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b90505b92915050565b6000806000601260010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff166385df51fd60018473ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa15801562002b10573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002b369190620050c7565b62002b42919062004785565b6040518263ffffffff1660e01b815260040162002b6191815260200190565b602060405180830381865afa15801562002b7f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002ba59190620050c7565b601554604080516020810193909352309083015274010000000000000000000000000000000000000000900463ffffffff166060820152608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083015201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060045b600f81101562002cb1578382828151811062002c6d5762002c6d62004a13565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508062002ca88162004a58565b91505062002c4d565b5084600181111562002cc75762002cc7620041e8565b60f81b81600f8151811062002ce05762002ce062004a13565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535062002d1a816200513d565b95945050505050565b6012547e01000000000000000000000000000000000000000000000000000000000000900460ff161562002d83576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601654835163ffffffff909116101562002dc9576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108fc856020015163ffffffff16108062002e075750601554602086015163ffffffff70010000000000000000000000000000000090920482169116115b1562002e3f576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152600460205260409020546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff161562002ea9576040517f6e3b930b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152600460209081526040808320885181548a8501518b85015160608d01517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009093169315157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169390931761010063ffffffff92831602177fffffff000000000000000000000000000000000000000000000000ffffffffff1665010000000000938216939093027fffffff0000000000000000000000000000000000000000ffffffffffffffffff1692909217690100000000000000000073ffffffffffffffffffffffffffffffffffffffff9283160217835560808b01516001909301805460a08d015160c08e01516bffffffffffffffffffffffff9687167fffffffffffffffff000000000000000000000000000000000000000000000000909316929092176c010000000000000000000000009690911695909502949094177fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009490931693909302919091179091556005835281842080547fffffffffffffffffffffffff000000000000000000000000000000000000000016918916919091179055600790915290206200309c848262005180565b508460a001516bffffffffffffffffffffffff16601954620030bf919062004a42565b6019556000868152601b60205260409020620030dc838262005180565b506000868152601c60205260409020620030f7828262005180565b506200310560028762003b0b565b50505050505050565b3273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146200317e576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314620031de576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090205465010000000000900463ffffffff9081161462002a02576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818160045b600f811015620032cb577fff0000000000000000000000000000000000000000000000000000000000000082168382602081106200327f576200327f62004a13565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614620032b657506000949350505050565b80620032c28162004a58565b9150506200323d565b5081600f1a6001811115620032e457620032e4620041e8565b949350505050565b6000806000836080015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa15801562003379573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200339f9190620052c2565b5094509092505050600081131580620033b757508142105b80620033dc5750828015620033dc5750620033d3824262004785565b8463ffffffff16105b15620033ed576017549550620033f1565b8095505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156200345d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620034839190620052c2565b50945090925050506000811315806200349b57508142105b80620034c05750828015620034c05750620034b7824262004785565b8463ffffffff16105b15620034d1576018549450620034d5565b8094505b50505050915091565b60008080866001811115620034f757620034f7620041e8565b0362003507575061ea6062003561565b60018660018111156200351e576200351e620041e8565b036200352f575062014c0862003561565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008760c00151600162003576919062005317565b620035869060ff16604062005333565b601654620035a6906103a490640100000000900463ffffffff1662004a42565b620035b2919062004a42565b601354604080517fde9ee35e00000000000000000000000000000000000000000000000000000000815281519394506000938493610100900473ffffffffffffffffffffffffffffffffffffffff169263de9ee35e92600480820193918290030181865afa15801562003629573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200364f91906200534d565b909250905081836200366383601862004a42565b6200366f919062005333565b60c08c01516200368190600162005317565b620036929060ff166115e062005333565b6200369e919062004a42565b620036aa919062004a42565b620036b6908562004a42565b935060008a610140015173ffffffffffffffffffffffffffffffffffffffff166312544140856040518263ffffffff1660e01b8152600401620036fb91815260200190565b602060405180830381865afa15801562003719573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200373f9190620050c7565b8b60a0015161ffff1662003754919062005333565b9050600080620037718d8c63ffffffff1689868e8e600062003b19565b90925090506200378281836200509f565b9d9c50505050505050505050505050565b60606000836001811115620037ac57620037ac620041e8565b0362003879576000848152600760205260409081902090517f6e04ff0d0000000000000000000000000000000000000000000000000000000091620037f49160240162005415565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915290506200397c565b6001836001811115620038905762003890620041e8565b036200352f57600082806020019051810190620038ae91906200548c565b6000868152600760205260409081902090519192507f40691db40000000000000000000000000000000000000000000000000000000091620038f5918491602401620055a0565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915291506200397c9050565b9392505050565b600062002a6e838362003c74565b60005473ffffffffffffffffffffffffffffffffffffffff1633146200317e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401620011cb565b3373ffffffffffffffffffffffffffffffffffffffff82160362003a95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620011cb565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600062002a6e838362003d7f565b60008060008960a0015161ffff168662003b34919062005333565b905083801562003b435750803a105b1562003b4c57503a5b6000858862003b5c8b8d62004a42565b62003b68908562005333565b62003b74919062004a42565b62003b8890670de0b6b3a764000062005333565b62003b94919062005668565b905060008b6040015163ffffffff1664e8d4a5100062003bb5919062005333565b60208d0151889063ffffffff168b62003bcf8f8862005333565b62003bdb919062004a42565b62003beb90633b9aca0062005333565b62003bf7919062005333565b62003c03919062005668565b62003c0f919062004a42565b90506b033b2e3c9fd0803ce800000062003c2a828462004a42565b111562003c63576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909b909a5098505050505050505050565b6000818152600183016020526040812054801562003d6d57600062003c9b60018362004785565b855490915060009062003cb19060019062004785565b905081811462003d1d57600086600001828154811062003cd55762003cd562004a13565b906000526020600020015490508087600001848154811062003cfb5762003cfb62004a13565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062003d315762003d31620056a4565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062002a71565b600091505062002a71565b5092915050565b600081815260018301602052604081205462003dc85750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562002a71565b50600062002a71565b6103ca80620056d483390190565b50805462003ded9062004843565b6000825580601f1062003dfe575050565b601f01602090049060005260206000209081019062002a0291905b8082111562003e2f576000815560010162003e19565b5090565b73ffffffffffffffffffffffffffffffffffffffff8116811462002a0257600080fd5b803563ffffffff8116811462003e6b57600080fd5b919050565b80356002811062003e6b57600080fd5b60008083601f84011262003e9357600080fd5b50813567ffffffffffffffff81111562003eac57600080fd5b60208301915083602082850101111562003ec557600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160e0810167ffffffffffffffff8111828210171562003f215762003f2162003ecc565b60405290565b604051610100810167ffffffffffffffff8111828210171562003f215762003f2162003ecc565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171562003f985762003f9862003ecc565b604052919050565b600067ffffffffffffffff82111562003fbd5762003fbd62003ecc565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011262003ffb57600080fd5b8135620040126200400c8262003fa0565b62003f4e565b8181528460208386010111156200402857600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060008060e0898b0312156200406257600080fd5b88356200406f8162003e33565b97506200407f60208a0162003e56565b96506040890135620040918162003e33565b9550620040a160608a0162003e70565b9450608089013567ffffffffffffffff80821115620040bf57600080fd5b620040cd8c838d0162003e80565b909650945060a08b0135915080821115620040e757600080fd5b620040f58c838d0162003fe9565b935060c08b01359150808211156200410c57600080fd5b506200411b8b828c0162003fe9565b9150509295985092959890939650565b600080604083850312156200413f57600080fd5b82359150602083013567ffffffffffffffff8111156200415e57600080fd5b6200416c8582860162003fe9565b9150509250929050565b60005b838110156200419357818101518382015260200162004179565b50506000910152565b60008151808452620041b681602086016020860162004176565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600a81106200424f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b84151581526080602082015260006200427060808301866200419c565b905062004281604083018562004217565b82606083015295945050505050565b600080600060408486031215620042a657600080fd5b83359250602084013567ffffffffffffffff811115620042c557600080fd5b620042d38682870162003e80565b9497909650939450505050565b600080600080600080600060a0888a031215620042fc57600080fd5b8735620043098162003e33565b9650620043196020890162003e56565b955060408801356200432b8162003e33565b9450606088013567ffffffffffffffff808211156200434957600080fd5b620043578b838c0162003e80565b909650945060808a01359150808211156200437157600080fd5b50620043808a828b0162003e80565b989b979a50959850939692959293505050565b871515815260e060208201526000620043b060e08301896200419c565b9050620043c1604083018862004217565b8560608301528460808301528360a08301528260c083015298975050505050505050565b600080600060408486031215620043fb57600080fd5b833567ffffffffffffffff808211156200441457600080fd5b818601915086601f8301126200442957600080fd5b8135818111156200443957600080fd5b8760208260051b85010111156200444f57600080fd5b60209283019550935050840135620044678162003e33565b809150509250925092565b600080602083850312156200448657600080fd5b823567ffffffffffffffff8111156200449e57600080fd5b620044ac8582860162003e80565b90969095509350505050565b80356bffffffffffffffffffffffff8116811462003e6b57600080fd5b60008060408385031215620044e957600080fd5b82359150620044fb60208401620044b8565b90509250929050565b6000602082840312156200451757600080fd5b5035919050565b600067ffffffffffffffff8211156200453b576200453b62003ecc565b5060051b60200190565b600082601f8301126200455757600080fd5b813560206200456a6200400c836200451e565b82815260059290921b840181019181810190868411156200458a57600080fd5b8286015b84811015620045cf57803567ffffffffffffffff811115620045b05760008081fd5b620045c08986838b010162003fe9565b8452509183019183016200458e565b509695505050505050565b60008060008060608587031215620045f157600080fd5b84359350602085013567ffffffffffffffff808211156200461157600080fd5b6200461f8883890162004545565b945060408701359150808211156200463657600080fd5b50620046458782880162003e80565b95989497509550505050565b6000602082840312156200466457600080fd5b81356200397c8162003e33565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600063ffffffff808316818103620046bc57620046bc62004671565b6001019392505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000620032e4602083018486620046c6565b60208152600062002a6e60208301846200419c565b805162003e6b8162003e33565b6000602082840312156200475a57600080fd5b81516200397c8162003e33565b600082516200477b81846020870162004176565b9190910192915050565b8181038181111562002a715762002a7162004671565b801515811462002a0257600080fd5b600082601f830112620047bc57600080fd5b8151620047cd6200400c8262003fa0565b818152846020838601011115620047e357600080fd5b620032e482602083016020870162004176565b600080604083850312156200480a57600080fd5b825162004817816200479b565b602084015190925067ffffffffffffffff8111156200483557600080fd5b6200416c85828601620047aa565b600181811c908216806200485857607f821691505b60208210810362004892577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f821115620048e657600081815260208120601f850160051c81016020861015620048c15750805b601f850160051c820191505b81811015620048e257828155600101620048cd565b5050505b505050565b67ffffffffffffffff83111562004906576200490662003ecc565b6200491e8362004917835462004843565b8362004898565b6000601f8411600181146200497357600085156200493c5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835562004a0c565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015620049c45786850135825560209485019460019092019101620049a2565b508682101562004a00577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8082018082111562002a715762002a7162004671565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362004a8c5762004a8c62004671565b5060010190565b600081518084526020808501945080840160005b8381101562004b525781518051151588528381015163ffffffff908116858a01526040808301519091169089015260608082015173ffffffffffffffffffffffffffffffffffffffff16908901526080808201516bffffffffffffffffffffffff169089015260a08082015162004b2d828b01826bffffffffffffffffffffffff169052565b505060c09081015163ffffffff169088015260e0909601959082019060010162004aa7565b509495945050505050565b600081518084526020808501945080840160005b8381101562004b5257815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010162004b71565b600082825180855260208086019550808260051b84010181860160005b8481101562004c12577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086840301895262004bff8383516200419c565b9884019892509083019060010162004bc2565b5090979650505050505050565b60e081528760e082015260006101007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8a111562004c5c57600080fd5b8960051b808c8386013783018381038201602085015262004c808282018b62004a93565b915050828103604084015262004c97818962004b5d565b9050828103606084015262004cad818862004b5d565b9050828103608084015262004cc3818762004ba5565b905082810360a084015262004cd9818662004ba5565b905082810360c084015262004cef818562004ba5565b9b9a5050505050505050505050565b60006020828403121562004d1157600080fd5b815160ff811681146200397c57600080fd5b60ff8416815260ff8316602082015260606040820152600062002d1a60608301846200419c565b60006020828403121562004d5d57600080fd5b815167ffffffffffffffff81111562004d7557600080fd5b620032e484828501620047aa565b60006020828403121562004d9657600080fd5b81516200397c816200479b565b600082601f83011262004db557600080fd5b8135602062004dc86200400c836200451e565b82815260059290921b8401810191818101908684111562004de857600080fd5b8286015b84811015620045cf578035835291830191830162004dec565b600082601f83011262004e1757600080fd5b8135602062004e2a6200400c836200451e565b82815260e0928302850182019282820191908785111562004e4a57600080fd5b8387015b8581101562004c125781818a03121562004e685760008081fd5b62004e7262003efb565b813562004e7f816200479b565b815262004e8e82870162003e56565b86820152604062004ea181840162003e56565b9082015260608281013562004eb68162003e33565b90820152608062004ec9838201620044b8565b9082015260a062004edc838201620044b8565b9082015260c062004eef83820162003e56565b90820152845292840192810162004e4e565b600082601f83011262004f1357600080fd5b8135602062004f266200400c836200451e565b82815260059290921b8401810191818101908684111562004f4657600080fd5b8286015b84811015620045cf57803562004f608162003e33565b835291830191830162004f4a565b600080600080600080600060e0888a03121562004f8a57600080fd5b873567ffffffffffffffff8082111562004fa357600080fd5b62004fb18b838c0162004da3565b985060208a013591508082111562004fc857600080fd5b62004fd68b838c0162004e05565b975060408a013591508082111562004fed57600080fd5b62004ffb8b838c0162004f01565b965060608a01359150808211156200501257600080fd5b620050208b838c0162004f01565b955060808a01359150808211156200503757600080fd5b620050458b838c0162004545565b945060a08a01359150808211156200505c57600080fd5b6200506a8b838c0162004545565b935060c08a01359150808211156200508157600080fd5b50620050908a828b0162004545565b91505092959891949750929550565b6bffffffffffffffffffffffff81811683821601908082111562003d785762003d7862004671565b600060208284031215620050da57600080fd5b5051919050565b6bffffffffffffffffffffffff82811682821603908082111562003d785762003d7862004671565b6040815260006200511e604083018662004ba5565b828103602084015262005133818587620046c6565b9695505050505050565b8051602080830151919081101562004892577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b815167ffffffffffffffff8111156200519d576200519d62003ecc565b620051b581620051ae845462004843565b8462004898565b602080601f8311600181146200520b5760008415620051d45750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555620048e2565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156200525a5788860151825594840194600190910190840162005239565b50858210156200529757878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b805169ffffffffffffffffffff8116811462003e6b57600080fd5b600080600080600060a08688031215620052db57600080fd5b620052e686620052a7565b94506020860151935060408601519250606086015191506200530b60808701620052a7565b90509295509295909350565b60ff818116838216019081111562002a715762002a7162004671565b808202811582820484141762002a715762002a7162004671565b600080604083850312156200536157600080fd5b505080516020909101519092909150565b60008154620053818162004843565b808552602060018381168015620053a15760018114620053da576200540a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b89010195506200540a565b866000528260002060005b85811015620054025781548a8201860152908301908401620053e5565b890184019650505b505050505092915050565b60208152600062002a6e602083018462005372565b600082601f8301126200543c57600080fd5b815160206200544f6200400c836200451e565b82815260059290921b840181019181810190868411156200546f57600080fd5b8286015b84811015620045cf578051835291830191830162005473565b6000602082840312156200549f57600080fd5b815167ffffffffffffffff80821115620054b857600080fd5b908301906101008286031215620054ce57600080fd5b620054d862003f27565b82518152602083015160208201526040830151604082015260608301516060820152608083015160808201526200551260a084016200473a565b60a082015260c0830151828111156200552a57600080fd5b62005538878286016200542a565b60c08301525060e0830151828111156200555157600080fd5b6200555f87828601620047aa565b60e08301525095945050505050565b600081518084526020808501945080840160005b8381101562004b525781518752958201959082019060010162005582565b60408152825160408201526020830151606082015260408301516080820152606083015160a0820152608083015160c082015273ffffffffffffffffffffffffffffffffffffffff60a08401511660e0820152600060c0840151610100808185015250620056136101408401826200556e565b905060e08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0848303016101208501526200565182826200419c565b915050828103602084015262002d1a818562005372565b6000826200569f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe60c060405234801561001057600080fd5b506040516103ca3803806103ca83398101604081905261002f91610076565b600080546001600160a01b0319166001600160a01b039384161790559181166080521660a0526100b9565b80516001600160a01b038116811461007157600080fd5b919050565b60008060006060848603121561008b57600080fd5b6100948461005a565b92506100a26020850161005a565b91506100b06040850161005a565b90509250925092565b60805160a0516102e76100e36000396000603801526000818160c4015261011701526102e76000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806379188d161461007b578063f00e6a2a146100aa575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610076573d6000f35b3d6000fd5b61008e6100893660046101c1565b6100ee565b6040805192151583526020830191909152015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526020016100a1565b60008054819073ffffffffffffffffffffffffffffffffffffffff16331461011557600080fd5b7f00000000000000000000000000000000000000000000000000000000000000005a91505a61138881101561014957600080fd5b61138881039050856040820482031161016157600080fd5b50803b61016d57600080fd5b6000808551602087016000858af192505a610188908361029a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080604083850312156101d457600080fd5b82359150602083013567ffffffffffffffff808211156101f357600080fd5b818501915085601f83011261020757600080fd5b81358181111561021957610219610192565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561025f5761025f610192565b8160405282815288602084870101111561027857600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b818103818111156102d4577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9291505056fea164736f6c6343000813000aa164736f6c6343000813000a", + Bin: "0x6101406040523480156200001257600080fd5b5060405162005f1538038062005f158339810160408190526200003591620003b1565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b9190620003b1565b826001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001009190620003b1565b836001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001659190620003b1565b846001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca9190620003b1565b856001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f9190620003b1565b3380600081620002865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620002b957620002b981620002ed565b5050506001600160a01b0394851660805292841660a05290831660c052821660e052811661010052166101205250620003d8565b336001600160a01b03821603620003475760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200027d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b0381168114620003ae57600080fd5b50565b600060208284031215620003c457600080fd5b8151620003d18162000398565b9392505050565b60805160a05160c05160e0516101005161012051615ad86200043d6000396000818161010e01526101a9015260006131540152600081816103e10152611ffe0152600061333d01526000613421015260008181611e40015261240c0152615ad86000f3fe60806040523480156200001157600080fd5b50600436106200010c5760003560e01c806385c1b0ba11620000a5578063c8048022116200006f578063c804802214620002b7578063ce7dc5b414620002ce578063f2fde38b14620002e5578063f7d334ba14620002fc576200010c565b806385c1b0ba14620002535780638da5cb5b146200026a5780638e86139b1462000289578063948108f714620002a0576200010c565b80634ee88d3511620000e75780634ee88d3514620001ef5780636ded9eae146200020657806371791aa0146200021d57806379ba50971462000249576200010c565b806328f32f38146200015457806329c5efad146200017e578063349e8cca14620001a7575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156200014d573d6000f35b3d6000fd5b005b6200016b6200016536600462004073565b62000313565b6040519081526020015b60405180910390f35b620001956200018f36600462004159565b6200068d565b60405162000175949392919062004281565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200162000175565b6200015262000200366004620042be565b62000931565b6200016b620002173660046200430e565b62000999565b620002346200022e36600462004159565b620009ff565b604051620001759796959493929190620043c1565b620001526200114d565b620001526200026436600462004413565b62001250565b60005473ffffffffffffffffffffffffffffffffffffffff16620001c9565b620001526200029a366004620044a0565b62001ec1565b62000152620002b136600462004503565b62002249565b62000152620002c836600462004532565b620024dc565b62000195620002df36600462004608565b62002955565b62000152620002f63660046200467f565b62002a1b565b620002346200030d36600462004532565b62002a33565b6000805473ffffffffffffffffffffffffffffffffffffffff1633148015906200034757506200034560093362002a71565b155b156200037f576040517fd48b678b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff89163b620003ce576040517f09ee12d500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b620003d98662002aa5565b9050600089307f00000000000000000000000000000000000000000000000000000000000000006040516200040e9062003dff565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f08015801562000458573d6000803e3d6000fd5b5090506200051f826040518060e001604052806000151581526020018c63ffffffff16815260200163ffffffff801681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff168152602001600063ffffffff168152508a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92508a915062002d519050565b6015805474010000000000000000000000000000000000000000900463ffffffff169060146200054f83620046ce565b91906101000a81548163ffffffff021916908363ffffffff16021790555050817fbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d0128a8a604051620005c892919063ffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a2817fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d8787604051620006049291906200473d565b60405180910390a2817f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d5664856040516200063e919062004753565b60405180910390a2817f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf48508460405162000678919062004753565b60405180910390a25098975050505050505050565b600060606000806200069e6200313c565b600086815260046020908152604091829020825160e081018452815460ff811615158252610100810463ffffffff90811694830194909452650100000000008104841694820194909452690100000000000000000090930473ffffffffffffffffffffffffffffffffffffffff166060840152600101546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a0840152780100000000000000000000000000000000000000000000000090041660c08201525a9150600080826060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620007b8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007de919062004775565b73ffffffffffffffffffffffffffffffffffffffff166014600101600c9054906101000a900463ffffffff1663ffffffff168960405162000820919062004795565b60006040518083038160008787f1925050503d806000811462000860576040519150601f19603f3d011682016040523d82523d6000602084013e62000865565b606091505b50915091505a620008779085620047b3565b935081620008a257600060405180602001604052806000815250600796509650965050505062000928565b80806020019051810190620008b8919062004824565b909750955086620008e657600060405180602001604052806000815250600496509650965050505062000928565b601654865164010000000090910463ffffffff1610156200092457600060405180602001604052806000815250600596509650965050505062000928565b5050505b92959194509250565b6200093c83620031ae565b6000838152601b602052604090206200095782848362004919565b50827f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d566483836040516200098c9291906200473d565b60405180910390a2505050565b6000620009f388888860008989604051806020016040528060008152508a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506200031392505050565b98975050505050505050565b60006060600080600080600062000a156200313c565b600062000a228a62003264565b905060006012604051806101600160405290816000820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160008201600c9054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160109054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160149054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160189054906101000a900462ffffff1662ffffff1662ffffff16815260200160008201601b9054906101000a900461ffff1661ffff1661ffff16815260200160008201601d9054906101000a900460ff1660ff1660ff16815260200160008201601e9054906101000a900460ff1615151515815260200160008201601f9054906101000a900460ff161515151581526020016001820160009054906101000a900460ff161515151581526020016001820160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090506000600460008d81526020019081526020016000206040518060e00160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160059054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160018201600c9054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff1681526020016001820160189054906101000a900463ffffffff1663ffffffff1663ffffffff168152505090508160e001511562000db7576000604051806020016040528060008152506009600084602001516000808263ffffffff169250995099509950995099509950995050505062001141565b604081015163ffffffff9081161462000e08576000604051806020016040528060008152506001600084602001516000808263ffffffff169250995099509950995099509950995050505062001141565b80511562000e4e576000604051806020016040528060008152506002600084602001516000808263ffffffff169250995099509950995099509950995050505062001141565b62000e59826200331a565b8095508196505050600062000e768385846020015189896200350c565b9050806bffffffffffffffffffffffff168260a001516bffffffffffffffffffffffff16101562000ee0576000604051806020016040528060008152506006600085602001516000808263ffffffff1692509a509a509a509a509a509a509a505050505062001141565b600062000eef8e868f620037c1565b90505a9850600080846060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000f47573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f6d919062004775565b73ffffffffffffffffffffffffffffffffffffffff166014600101600c9054906101000a900463ffffffff1663ffffffff168460405162000faf919062004795565b60006040518083038160008787f1925050503d806000811462000fef576040519150601f19603f3d011682016040523d82523d6000602084013e62000ff4565b606091505b50915091505a62001006908c620047b3565b9a5081620010865760165481516801000000000000000090910463ffffffff1610156200106357505060408051602080820190925260008082529490910151939c509a50600899505063ffffffff90911695506200114192505050565b602090940151939b5060039a505063ffffffff9092169650620011419350505050565b808060200190518101906200109c919062004824565b909e509c508d620010dd57505060408051602080820190925260008082529490910151939c509a50600499505063ffffffff90911695506200114192505050565b6016548d5164010000000090910463ffffffff1610156200112e57505060408051602080820190925260008082529490910151939c509a50600599505063ffffffff90911695506200114192505050565b505050506020015163ffffffff16945050505b92959891949750929550565b60015473ffffffffffffffffffffffffffffffffffffffff163314620011d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600173ffffffffffffffffffffffffffffffffffffffff82166000908152601a602052604090205460ff1660038111156200128f576200128f62004216565b14158015620012db5750600373ffffffffffffffffffffffffffffffffffffffff82166000908152601a602052604090205460ff166003811115620012d857620012d862004216565b14155b1562001313576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6014546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1662001373576040517fd12d7d8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000829003620013af576040517f2c2fc94100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081018290526000808567ffffffffffffffff81111562001406576200140662003efa565b60405190808252806020026020018201604052801562001430578160200160208202803683370190505b50905060008667ffffffffffffffff81111562001451576200145162003efa565b604051908082528060200260200182016040528015620014d857816020015b6040805160e08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181620014705790505b50905060008767ffffffffffffffff811115620014f957620014f962003efa565b6040519080825280602002602001820160405280156200152e57816020015b6060815260200190600190039081620015185790505b50905060008867ffffffffffffffff8111156200154f576200154f62003efa565b6040519080825280602002602001820160405280156200158457816020015b60608152602001906001900390816200156e5790505b50905060008967ffffffffffffffff811115620015a557620015a562003efa565b604051908082528060200260200182016040528015620015da57816020015b6060815260200190600190039081620015c45790505b50905060005b8a81101562001bbe578b8b82818110620015fe57620015fe62004a41565b60209081029290920135600081815260048452604090819020815160e081018352815460ff811615158252610100810463ffffffff90811697830197909752650100000000008104871693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490931660c08401529a50909850620016dd905089620031ae565b60608801516040517f1a5da6c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c8116600483015290911690631a5da6c890602401600060405180830381600087803b1580156200174d57600080fd5b505af115801562001762573d6000803e3d6000fd5b50505050878582815181106200177c576200177c62004a41565b6020026020010181905250600560008a815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16868281518110620017d057620017d062004a41565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015260008a815260079091526040902080546200180f9062004871565b80601f01602080910402602001604051908101604052809291908181526020018280546200183d9062004871565b80156200188e5780601f1062001862576101008083540402835291602001916200188e565b820191906000526020600020905b8154815290600101906020018083116200187057829003601f168201915b5050505050848281518110620018a857620018a862004a41565b6020026020010181905250601b60008a81526020019081526020016000208054620018d39062004871565b80601f0160208091040260200160405190810160405280929190818152602001828054620019019062004871565b8015620019525780601f10620019265761010080835404028352916020019162001952565b820191906000526020600020905b8154815290600101906020018083116200193457829003601f168201915b50505050508382815181106200196c576200196c62004a41565b6020026020010181905250601c60008a81526020019081526020016000208054620019979062004871565b80601f0160208091040260200160405190810160405280929190818152602001828054620019c59062004871565b801562001a165780601f10620019ea5761010080835404028352916020019162001a16565b820191906000526020600020905b815481529060010190602001808311620019f857829003601f168201915b505050505082828151811062001a305762001a3062004a41565b60200260200101819052508760a001516bffffffffffffffffffffffff168762001a5b919062004a70565b60008a815260046020908152604080832080547fffffff000000000000000000000000000000000000000000000000000000000016815560010180547fffffffff000000000000000000000000000000000000000000000000000000001690556007909152812091985062001ad1919062003e0d565b6000898152601b6020526040812062001aea9162003e0d565b6000898152601c6020526040812062001b039162003e0d565b600089815260066020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905562001b4460028a620039b1565b5060a0880151604080516bffffffffffffffffffffffff909216825273ffffffffffffffffffffffffffffffffffffffff8c1660208301528a917fb38647142fbb1ea4c000fc4569b37a4e9a9f6313317b84ee3e5326c1a6cd06ff910160405180910390a28062001bb58162004a86565b915050620015e0565b508560195462001bcf9190620047b3565b60195560008b8b868167ffffffffffffffff81111562001bf35762001bf362003efa565b60405190808252806020026020018201604052801562001c1d578160200160208202803683370190505b508988888860405160200162001c3b98979695949392919062004c4d565b60405160208183030381529060405290508973ffffffffffffffffffffffffffffffffffffffff16638e86139b6014600001600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c71249ab60038e73ffffffffffffffffffffffffffffffffffffffff1663aab9edd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001cf7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001d1d919062004d2c565b866040518463ffffffff1660e01b815260040162001d3e9392919062004d51565b600060405180830381865afa15801562001d5c573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405262001da4919081019062004d78565b6040518263ffffffff1660e01b815260040162001dc2919062004753565b600060405180830381600087803b15801562001ddd57600080fd5b505af115801562001df2573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d81166004830152602482018b90527f000000000000000000000000000000000000000000000000000000000000000016925063a9059cbb91506044016020604051808303816000875af115801562001e8c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001eb2919062004db1565b50505050505050505050505050565b6002336000908152601a602052604090205460ff16600381111562001eea5762001eea62004216565b1415801562001f2057506003336000908152601a602052604090205460ff16600381111562001f1d5762001f1d62004216565b14155b1562001f58576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080808080808062001f6e888a018a62004f9c565b965096509650965096509650965060005b87518110156200223d57600073ffffffffffffffffffffffffffffffffffffffff1687828151811062001fb65762001fb662004a41565b60200260200101516060015173ffffffffffffffffffffffffffffffffffffffff1603620020ca5785818151811062001ff35762001ff362004a41565b6020026020010151307f00000000000000000000000000000000000000000000000000000000000000006040516200202b9062003dff565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f08015801562002075573d6000803e3d6000fd5b508782815181106200208b576200208b62004a41565b60200260200101516060019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b62002182888281518110620020e357620020e362004a41565b602002602001015188838151811062002100576200210062004a41565b60200260200101518784815181106200211d576200211d62004a41565b60200260200101518785815181106200213a576200213a62004a41565b602002602001015187868151811062002157576200215762004a41565b602002602001015187878151811062002174576200217462004a41565b602002602001015162002d51565b87818151811062002197576200219762004a41565b60200260200101517f74931a144e43a50694897f241d973aecb5024c0e910f9bb80a163ea3c1cf5a71888381518110620021d557620021d562004a41565b602002602001015160a0015133604051620022209291906bffffffffffffffffffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a280620022348162004a86565b91505062001f7f565b50505050505050505050565b600082815260046020908152604091829020825160e081018452815460ff81161515825263ffffffff6101008204811694830194909452650100000000008104841694820185905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a083015278010000000000000000000000000000000000000000000000009004821660c0820152911462002347576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818160a00151620023599190620050cd565b600084815260046020526040902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006bffffffffffffffffffffffff93841602179055601954620023c19184169062004a70565b6019556040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526bffffffffffffffffffffffff831660448201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906323b872dd906064016020604051808303816000875af11580156200246b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002491919062004db1565b506040516bffffffffffffffffffffffff83168152339084907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a3505050565b6000818152600460209081526040808320815160e081018352815460ff81161515825263ffffffff610100820481169583019590955265010000000000810485169382019390935273ffffffffffffffffffffffffffffffffffffffff6901000000000000000000909304929092166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c082015290620025c460005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161490506000601260010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa15801562002667573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200268d9190620050f5565b9050826040015163ffffffff16600003620026d4576040517ffbc0357800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604083015163ffffffff9081161462002719576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b811580156200274c575060008481526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b1562002784576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816200279a576200279760328262004a70565b90505b6000848152600460205260409020805463ffffffff80841665010000000000027fffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffff90921691909117909155620027f6906002908690620039b116565b5060145460808401516bffffffffffffffffffffffff91821691600091168211156200285f5760808501516200282d90836200510f565b90508460a001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff1611156200285f575060a08401515b808560a001516200287191906200510f565b600087815260046020526040902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006bffffffffffffffffffffffff93841602179055601554620028d991839116620050cd565b601580547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff9290921691909117905560405167ffffffffffffffff84169087907f91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f79118190600090a3505050505050565b600060606000806000634b56a42e60e01b8888886040516024016200297d9392919062005137565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152905062002a0889826200068d565b929c919b50995090975095505050505050565b62002a25620039bf565b62002a308162003a42565b50565b60006060600080600080600062002a5a8860405180602001604052806000815250620009ff565b959e949d50929b5090995097509550909350915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b90505b92915050565b6000806000601260010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff166385df51fd60018473ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa15801562002b3e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002b649190620050f5565b62002b709190620047b3565b6040518263ffffffff1660e01b815260040162002b8f91815260200190565b602060405180830381865afa15801562002bad573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002bd39190620050f5565b601554604080516020810193909352309083015274010000000000000000000000000000000000000000900463ffffffff166060820152608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083015201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060045b600f81101562002cdf578382828151811062002c9b5762002c9b62004a41565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508062002cd68162004a86565b91505062002c7b565b5084600181111562002cf55762002cf562004216565b60f81b81600f8151811062002d0e5762002d0e62004a41565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535062002d48816200516b565b95945050505050565b6012547e01000000000000000000000000000000000000000000000000000000000000900460ff161562002db1576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601654835163ffffffff909116101562002df7576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108fc856020015163ffffffff16108062002e355750601554602086015163ffffffff70010000000000000000000000000000000090920482169116115b1562002e6d576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152600460205260409020546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff161562002ed7576040517f6e3b930b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152600460209081526040808320885181548a8501518b85015160608d01517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009093169315157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169390931761010063ffffffff92831602177fffffff000000000000000000000000000000000000000000000000ffffffffff1665010000000000938216939093027fffffff0000000000000000000000000000000000000000ffffffffffffffffff1692909217690100000000000000000073ffffffffffffffffffffffffffffffffffffffff9283160217835560808b01516001909301805460a08d015160c08e01516bffffffffffffffffffffffff9687167fffffffffffffffff000000000000000000000000000000000000000000000000909316929092176c010000000000000000000000009690911695909502949094177fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009490931693909302919091179091556005835281842080547fffffffffffffffffffffffff00000000000000000000000000000000000000001691891691909117905560079091529020620030ca8482620051ae565b508460a001516bffffffffffffffffffffffff16601954620030ed919062004a70565b6019556000868152601b602052604090206200310a8382620051ae565b506000868152601c60205260409020620031258282620051ae565b506200313360028762003b39565b50505050505050565b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614620031ac576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff1633146200320c576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090205465010000000000900463ffffffff9081161462002a30576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818160045b600f811015620032f9577fff000000000000000000000000000000000000000000000000000000000000008216838260208110620032ad57620032ad62004a41565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614620032e457506000949350505050565b80620032f08162004a86565b9150506200326b565b5081600f1a600181111562003312576200331262004216565b949350505050565b6000806000836080015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015620033a7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620033cd9190620052f0565b5094509092505050600081131580620033e557508142105b806200340a57508280156200340a5750620034018242620047b3565b8463ffffffff16105b156200341b5760175495506200341f565b8095505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156200348b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620034b19190620052f0565b5094509092505050600081131580620034c957508142105b80620034ee5750828015620034ee5750620034e58242620047b3565b8463ffffffff16105b15620034ff57601854945062003503565b8094505b50505050915091565b6000808086600181111562003525576200352562004216565b0362003535575061ea606200358f565b60018660018111156200354c576200354c62004216565b036200355d575062014c086200358f565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008760c001516001620035a4919062005345565b620035b49060ff16604062005361565b601654620035d4906103a490640100000000900463ffffffff1662004a70565b620035e0919062004a70565b601354604080517fde9ee35e00000000000000000000000000000000000000000000000000000000815281519394506000938493610100900473ffffffffffffffffffffffffffffffffffffffff169263de9ee35e92600480820193918290030181865afa15801562003657573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200367d91906200537b565b909250905081836200369183601862004a70565b6200369d919062005361565b60c08c0151620036af90600162005345565b620036c09060ff166115e062005361565b620036cc919062004a70565b620036d8919062004a70565b620036e4908562004a70565b935060008a610140015173ffffffffffffffffffffffffffffffffffffffff166312544140856040518263ffffffff1660e01b81526004016200372991815260200190565b602060405180830381865afa15801562003747573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200376d9190620050f5565b8b60a0015161ffff1662003782919062005361565b90506000806200379f8d8c63ffffffff1689868e8e600062003b47565b9092509050620037b08183620050cd565b9d9c50505050505050505050505050565b60606000836001811115620037da57620037da62004216565b03620038a7576000848152600760205260409081902090517f6e04ff0d0000000000000000000000000000000000000000000000000000000091620038229160240162005443565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050620039aa565b6001836001811115620038be57620038be62004216565b036200355d57600082806020019051810190620038dc9190620054ba565b6000868152600760205260409081902090519192507f40691db4000000000000000000000000000000000000000000000000000000009162003923918491602401620055ce565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529150620039aa9050565b9392505050565b600062002a9c838362003ca2565b60005473ffffffffffffffffffffffffffffffffffffffff163314620031ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401620011cb565b3373ffffffffffffffffffffffffffffffffffffffff82160362003ac3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620011cb565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600062002a9c838362003dad565b60008060008960a0015161ffff168662003b62919062005361565b905083801562003b715750803a105b1562003b7a57503a5b6000858862003b8a8b8d62004a70565b62003b96908562005361565b62003ba2919062004a70565b62003bb690670de0b6b3a764000062005361565b62003bc2919062005696565b905060008b6040015163ffffffff1664e8d4a5100062003be3919062005361565b60208d0151889063ffffffff168b62003bfd8f8862005361565b62003c09919062004a70565b62003c1990633b9aca0062005361565b62003c25919062005361565b62003c31919062005696565b62003c3d919062004a70565b90506b033b2e3c9fd0803ce800000062003c58828462004a70565b111562003c91576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909b909a5098505050505050505050565b6000818152600183016020526040812054801562003d9b57600062003cc9600183620047b3565b855490915060009062003cdf90600190620047b3565b905081811462003d4b57600086600001828154811062003d035762003d0362004a41565b906000526020600020015490508087600001848154811062003d295762003d2962004a41565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062003d5f5762003d5f620056d2565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062002a9f565b600091505062002a9f565b5092915050565b600081815260018301602052604081205462003df65750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562002a9f565b50600062002a9f565b6103ca806200570283390190565b50805462003e1b9062004871565b6000825580601f1062003e2c575050565b601f01602090049060005260206000209081019062002a3091905b8082111562003e5d576000815560010162003e47565b5090565b73ffffffffffffffffffffffffffffffffffffffff8116811462002a3057600080fd5b803563ffffffff8116811462003e9957600080fd5b919050565b80356002811062003e9957600080fd5b60008083601f84011262003ec157600080fd5b50813567ffffffffffffffff81111562003eda57600080fd5b60208301915083602082850101111562003ef357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160e0810167ffffffffffffffff8111828210171562003f4f5762003f4f62003efa565b60405290565b604051610100810167ffffffffffffffff8111828210171562003f4f5762003f4f62003efa565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171562003fc65762003fc662003efa565b604052919050565b600067ffffffffffffffff82111562003feb5762003feb62003efa565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126200402957600080fd5b8135620040406200403a8262003fce565b62003f7c565b8181528460208386010111156200405657600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060008060e0898b0312156200409057600080fd5b88356200409d8162003e61565b9750620040ad60208a0162003e84565b96506040890135620040bf8162003e61565b9550620040cf60608a0162003e9e565b9450608089013567ffffffffffffffff80821115620040ed57600080fd5b620040fb8c838d0162003eae565b909650945060a08b01359150808211156200411557600080fd5b620041238c838d0162004017565b935060c08b01359150808211156200413a57600080fd5b50620041498b828c0162004017565b9150509295985092959890939650565b600080604083850312156200416d57600080fd5b82359150602083013567ffffffffffffffff8111156200418c57600080fd5b6200419a8582860162004017565b9150509250929050565b60005b83811015620041c1578181015183820152602001620041a7565b50506000910152565b60008151808452620041e4816020860160208601620041a4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600a81106200427d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b84151581526080602082015260006200429e6080830186620041ca565b9050620042af604083018562004245565b82606083015295945050505050565b600080600060408486031215620042d457600080fd5b83359250602084013567ffffffffffffffff811115620042f357600080fd5b620043018682870162003eae565b9497909650939450505050565b600080600080600080600060a0888a0312156200432a57600080fd5b8735620043378162003e61565b9650620043476020890162003e84565b95506040880135620043598162003e61565b9450606088013567ffffffffffffffff808211156200437757600080fd5b620043858b838c0162003eae565b909650945060808a01359150808211156200439f57600080fd5b50620043ae8a828b0162003eae565b989b979a50959850939692959293505050565b871515815260e060208201526000620043de60e0830189620041ca565b9050620043ef604083018862004245565b8560608301528460808301528360a08301528260c083015298975050505050505050565b6000806000604084860312156200442957600080fd5b833567ffffffffffffffff808211156200444257600080fd5b818601915086601f8301126200445757600080fd5b8135818111156200446757600080fd5b8760208260051b85010111156200447d57600080fd5b60209283019550935050840135620044958162003e61565b809150509250925092565b60008060208385031215620044b457600080fd5b823567ffffffffffffffff811115620044cc57600080fd5b620044da8582860162003eae565b90969095509350505050565b80356bffffffffffffffffffffffff8116811462003e9957600080fd5b600080604083850312156200451757600080fd5b823591506200452960208401620044e6565b90509250929050565b6000602082840312156200454557600080fd5b5035919050565b600067ffffffffffffffff82111562004569576200456962003efa565b5060051b60200190565b600082601f8301126200458557600080fd5b81356020620045986200403a836200454c565b82815260059290921b84018101918181019086841115620045b857600080fd5b8286015b84811015620045fd57803567ffffffffffffffff811115620045de5760008081fd5b620045ee8986838b010162004017565b845250918301918301620045bc565b509695505050505050565b600080600080606085870312156200461f57600080fd5b84359350602085013567ffffffffffffffff808211156200463f57600080fd5b6200464d8883890162004573565b945060408701359150808211156200466457600080fd5b50620046738782880162003eae565b95989497509550505050565b6000602082840312156200469257600080fd5b8135620039aa8162003e61565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600063ffffffff808316818103620046ea57620046ea6200469f565b6001019392505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60208152600062003312602083018486620046f4565b60208152600062002a9c6020830184620041ca565b805162003e998162003e61565b6000602082840312156200478857600080fd5b8151620039aa8162003e61565b60008251620047a9818460208701620041a4565b9190910192915050565b8181038181111562002a9f5762002a9f6200469f565b801515811462002a3057600080fd5b600082601f830112620047ea57600080fd5b8151620047fb6200403a8262003fce565b8181528460208386010111156200481157600080fd5b62003312826020830160208701620041a4565b600080604083850312156200483857600080fd5b82516200484581620047c9565b602084015190925067ffffffffffffffff8111156200486357600080fd5b6200419a85828601620047d8565b600181811c908216806200488657607f821691505b602082108103620048c0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156200491457600081815260208120601f850160051c81016020861015620048ef5750805b601f850160051c820191505b818110156200491057828155600101620048fb565b5050505b505050565b67ffffffffffffffff83111562004934576200493462003efa565b6200494c8362004945835462004871565b83620048c6565b6000601f841160018114620049a157600085156200496a5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835562004a3a565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015620049f25786850135825560209485019460019092019101620049d0565b508682101562004a2e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8082018082111562002a9f5762002a9f6200469f565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362004aba5762004aba6200469f565b5060010190565b600081518084526020808501945080840160005b8381101562004b805781518051151588528381015163ffffffff908116858a01526040808301519091169089015260608082015173ffffffffffffffffffffffffffffffffffffffff16908901526080808201516bffffffffffffffffffffffff169089015260a08082015162004b5b828b01826bffffffffffffffffffffffff169052565b505060c09081015163ffffffff169088015260e0909601959082019060010162004ad5565b509495945050505050565b600081518084526020808501945080840160005b8381101562004b8057815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010162004b9f565b600082825180855260208086019550808260051b84010181860160005b8481101562004c40577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086840301895262004c2d838351620041ca565b9884019892509083019060010162004bf0565b5090979650505050505050565b60e081528760e082015260006101007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8a111562004c8a57600080fd5b8960051b808c8386013783018381038201602085015262004cae8282018b62004ac1565b915050828103604084015262004cc5818962004b8b565b9050828103606084015262004cdb818862004b8b565b9050828103608084015262004cf1818762004bd3565b905082810360a084015262004d07818662004bd3565b905082810360c084015262004d1d818562004bd3565b9b9a5050505050505050505050565b60006020828403121562004d3f57600080fd5b815160ff81168114620039aa57600080fd5b60ff8416815260ff8316602082015260606040820152600062002d486060830184620041ca565b60006020828403121562004d8b57600080fd5b815167ffffffffffffffff81111562004da357600080fd5b6200331284828501620047d8565b60006020828403121562004dc457600080fd5b8151620039aa81620047c9565b600082601f83011262004de357600080fd5b8135602062004df66200403a836200454c565b82815260059290921b8401810191818101908684111562004e1657600080fd5b8286015b84811015620045fd578035835291830191830162004e1a565b600082601f83011262004e4557600080fd5b8135602062004e586200403a836200454c565b82815260e0928302850182019282820191908785111562004e7857600080fd5b8387015b8581101562004c405781818a03121562004e965760008081fd5b62004ea062003f29565b813562004ead81620047c9565b815262004ebc82870162003e84565b86820152604062004ecf81840162003e84565b9082015260608281013562004ee48162003e61565b90820152608062004ef7838201620044e6565b9082015260a062004f0a838201620044e6565b9082015260c062004f1d83820162003e84565b90820152845292840192810162004e7c565b600082601f83011262004f4157600080fd5b8135602062004f546200403a836200454c565b82815260059290921b8401810191818101908684111562004f7457600080fd5b8286015b84811015620045fd57803562004f8e8162003e61565b835291830191830162004f78565b600080600080600080600060e0888a03121562004fb857600080fd5b873567ffffffffffffffff8082111562004fd157600080fd5b62004fdf8b838c0162004dd1565b985060208a013591508082111562004ff657600080fd5b620050048b838c0162004e33565b975060408a01359150808211156200501b57600080fd5b620050298b838c0162004f2f565b965060608a01359150808211156200504057600080fd5b6200504e8b838c0162004f2f565b955060808a01359150808211156200506557600080fd5b620050738b838c0162004573565b945060a08a01359150808211156200508a57600080fd5b620050988b838c0162004573565b935060c08a0135915080821115620050af57600080fd5b50620050be8a828b0162004573565b91505092959891949750929550565b6bffffffffffffffffffffffff81811683821601908082111562003da65762003da66200469f565b6000602082840312156200510857600080fd5b5051919050565b6bffffffffffffffffffffffff82811682821603908082111562003da65762003da66200469f565b6040815260006200514c604083018662004bd3565b828103602084015262005161818587620046f4565b9695505050505050565b80516020808301519190811015620048c0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b815167ffffffffffffffff811115620051cb57620051cb62003efa565b620051e381620051dc845462004871565b84620048c6565b602080601f831160018114620052395760008415620052025750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855562004910565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015620052885788860151825594840194600190910190840162005267565b5085821015620052c557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b805169ffffffffffffffffffff8116811462003e9957600080fd5b600080600080600060a086880312156200530957600080fd5b6200531486620052d5565b94506020860151935060408601519250606086015191506200533960808701620052d5565b90509295509295909350565b60ff818116838216019081111562002a9f5762002a9f6200469f565b808202811582820484141762002a9f5762002a9f6200469f565b600080604083850312156200538f57600080fd5b505080516020909101519092909150565b60008154620053af8162004871565b808552602060018381168015620053cf5760018114620054085762005438565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b890101955062005438565b866000528260002060005b85811015620054305781548a820186015290830190840162005413565b890184019650505b505050505092915050565b60208152600062002a9c6020830184620053a0565b600082601f8301126200546a57600080fd5b815160206200547d6200403a836200454c565b82815260059290921b840181019181810190868411156200549d57600080fd5b8286015b84811015620045fd5780518352918301918301620054a1565b600060208284031215620054cd57600080fd5b815167ffffffffffffffff80821115620054e657600080fd5b908301906101008286031215620054fc57600080fd5b6200550662003f55565b82518152602083015160208201526040830151604082015260608301516060820152608083015160808201526200554060a0840162004768565b60a082015260c0830151828111156200555857600080fd5b620055668782860162005458565b60c08301525060e0830151828111156200557f57600080fd5b6200558d87828601620047d8565b60e08301525095945050505050565b600081518084526020808501945080840160005b8381101562004b8057815187529582019590820190600101620055b0565b60408152825160408201526020830151606082015260408301516080820152606083015160a0820152608083015160c082015273ffffffffffffffffffffffffffffffffffffffff60a08401511660e0820152600060c0840151610100808185015250620056416101408401826200559c565b905060e08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0848303016101208501526200567f8282620041ca565b915050828103602084015262002d488185620053a0565b600082620056cd577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe60c060405234801561001057600080fd5b506040516103ca3803806103ca83398101604081905261002f91610076565b600080546001600160a01b0319166001600160a01b039384161790559181166080521660a0526100b9565b80516001600160a01b038116811461007157600080fd5b919050565b60008060006060848603121561008b57600080fd5b6100948461005a565b92506100a26020850161005a565b91506100b06040850161005a565b90509250925092565b60805160a0516102e76100e36000396000603801526000818160c4015261011701526102e76000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806379188d161461007b578063f00e6a2a146100aa575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610076573d6000f35b3d6000fd5b61008e6100893660046101c1565b6100ee565b6040805192151583526020830191909152015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526020016100a1565b60008054819073ffffffffffffffffffffffffffffffffffffffff16331461011557600080fd5b7f00000000000000000000000000000000000000000000000000000000000000005a91505a61138881101561014957600080fd5b61138881039050856040820482031161016157600080fd5b50803b61016d57600080fd5b6000808551602087016000858af192505a610188908361029a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080604083850312156101d457600080fd5b82359150602083013567ffffffffffffffff808211156101f357600080fd5b818501915085601f83011261020757600080fd5b81358181111561021957610219610192565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561025f5761025f610192565b8160405282815288602084870101111561027857600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b818103818111156102d4577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9291505056fea164736f6c6343000813000aa164736f6c6343000813000a", } var AutomationRegistryLogicAABI = AutomationRegistryLogicAMetaData.ABI diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index f060457e0eb..89c92d2b4cb 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -8,7 +8,7 @@ automation_consumer_benchmark: ../../contracts/solc/v0.8.16/AutomationConsumerBe automation_forwarder_logic: ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.abi ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.bin 15ae0c367297955fdab4b552dbb10e1f2be80a8fde0efec4a4d398693e9d72b5 automation_registrar_wrapper2_1: ../../contracts/solc/v0.8.16/AutomationRegistrar2_1/AutomationRegistrar2_1.abi ../../contracts/solc/v0.8.16/AutomationRegistrar2_1/AutomationRegistrar2_1.bin eb06d853aab39d3196c593b03e555851cbe8386e0fe54a74c2479f62d14b3c42 automation_registrar_wrapper2_2: ../../contracts/solc/v0.8.19/AutomationRegistrar2_2/AutomationRegistrar2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistrar2_2/AutomationRegistrar2_2.bin 7c61908c1bb1bfd05a4da22bb73d62c0e2c05240f3f8fb5e06331603ff2246a9 -automation_registry_logic_a_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.bin 38036d73155b89d241e6f17aab0af78be21e90dfa9e455cd575fe02d1a6474f9 +automation_registry_logic_a_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.bin 58d09c16be20a6d3f70be6d06299ed61415b7796c71f176d87ce015e1294e029 automation_registry_logic_b_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.bin e5669214a6b747b17331ebbf8f2d13cf7100d3313d652c6f1304ccf158441fc6 automation_registry_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.bin eca1187a878b622ef3fced041a28a4229d45dd797d95630838ff6351b6afc437 automation_utils_2_1: ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.abi ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.bin 331bfa79685aee6ddf63b64c0747abee556c454cae3fb8175edff425b615d8aa From c70f811b22f20aca0e8105925543e76ada7406cb Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Tue, 5 Mar 2024 17:31:12 +0100 Subject: [PATCH 17/34] update README.md to reflect TOML-related changes, add easy-to-act-on error messages when typical configuration is missing (#12298) --- integration-tests/README.md | 25 ++- integration-tests/testconfig/README.md | 168 ++++++++++++++++++ integration-tests/testconfig/testconfig.go | 17 +- .../testconfig/testconfig_utils.go | 70 ++++++++ 4 files changed, 271 insertions(+), 9 deletions(-) create mode 100644 integration-tests/testconfig/README.md create mode 100644 integration-tests/testconfig/testconfig_utils.go diff --git a/integration-tests/README.md b/integration-tests/README.md index 37a8fa19ed3..1ea3609f11e 100644 --- a/integration-tests/README.md +++ b/integration-tests/README.md @@ -14,7 +14,26 @@ If you have previously run these smoke tests using GitHub Actions or some sort o ## Configure -See the [example.env](./example.env) file for environment variables you can set to configure things like network settings, Chainlink version, and log level. Remember to use `source .env` to activate your settings. +We have finished first pass at moving the configuration from env vars to TOML files. Currently all product-related configuration is already in TOML files, but env vars still are used to control things like log level, Slack notifications and Kubernetes-related settings. See the [example.env](./example.env) file for environment variables. + +We have added what we think are sensible defaults for all products, you can find them in `./testconfig//.toml` files. Each product folder contains also an `example.toml` file with all possible TOML keys and some description. Detailed description of TOML configuration can be found in [README.md](./testconfig/README.md), but if you want to run some tests using default value all you need to do is provide Chainlink image and version: +```toml +# ./testconfig/overrides.toml + +[ChainlinkImage] +image = "your image name" +version = "your tag" +``` + +You could also think about that config this way: +```toml +# ./testconfig/overrides.toml +[ChainlinkImage] +image = "${CHAINLINK_IMAGE}" +version = "${CHAINLINK_VERSION}" +``` + +Of course above just and example, in real world no substitution will take place unless you use some templating tool, but it should give you an idea on how to move from env vars to TOML files. **Remember** your runtime configuration needs to be placed in `./testconfig/overrides.toml` file **that should never be committed**. ## Build @@ -26,10 +45,10 @@ e.g. `make build_docker_image image=chainlink tag=test-tag` -You'll want to set the `CHAINLINK_IMAGE` and `CHAINLINK_VERSION` env values appropriately as well. See [example.env](./example.env) for more details. - ## Run +Make sure you have `./testconfig/overrides.toml` file with your Chainlink image and version. + `go test ./smoke/_test.go` Most test files have a couple of tests, it's recommended to look into the file and focus on a specific one if possible. 90% of the time this will probably be the `Basic` test. See [ocr_test.go](./smoke/ocr_test.go) for example, which contains the `TestOCRBasic` test. diff --git a/integration-tests/testconfig/README.md b/integration-tests/testconfig/README.md new file mode 100644 index 00000000000..a86531551ff --- /dev/null +++ b/integration-tests/testconfig/README.md @@ -0,0 +1,168 @@ +# TOML is the Ultimate Choice! + +## Introduction + +Final implementation has undergone minor adjustments in comparison to the approach by Adam Hamric, Anindita Ghosh, and Sergey Kudasov stated in the ADR. The primary changes are as follows: +* `TEST_LOG_LEVEL` remains an environment variable, pending the release of version 2. +* `TEST_TYPE` is also kept as an environment variable to facilitate dynamic configuration selection by some tests. +* TOML configuration of Chainlink nodes themselves has not been added, awaiting version 2. +* The hierarchy of configuration overrides has been streamlined for simplicity. + +By design, all test configurations are intended to reside within the `testconfig` package, organized into application-specific folders. However, the system can locate these configurations in any folder within the `integration-tests` directory, selecting the first one found. To identify the configurations in use, execute tests with the `debug` log level. + +The `testconfig` package serves as a centralized resource for accessing configurations across all products, including shared settings like logging and network preferences, as well as initial funding for Chainlink nodes. Product configurations, if present, are subjected to validation based on logical assumptions and observed code values. The `TestConfig` structure includes a `Save()` method, allowing for the preservation of test configurations after all adjustments have been applied. + +## Configuration and Overrides + +The order of precedence for overrides is as follows: +* Environment variable `BASE64_CONFIG_OVERRIDE` +* File `overrides.toml` +* Product-specific file, e.g., `[product_name].toml` +* The `default.toml` file + +The `BASE64_CONFIG_OVERRIDE` environment variable is primarily intended for use in continuous integration environments, enabling the substitution of default settings with confidential or user-specific parameters. For instance: + +```bash +cat << EOF > config.toml +[Network] +selected_networks=["$SELECTED_NETWORKS"] + +[ChainlinkImage] +image="$CHAINLINK_IMAGE" +version="$CHAINLINK_VERSION" +postgres_version="$CHAINLINK_POSTGRES_VERSION" + +[Pyroscope] +enabled=$pyroscope_enabled +server_url="$PYROSCOPE_SERVER" +environment="$PYROSCOPE_ENVIRONMENT" +key_secret="$PYROSCOPE_KEY" + +[Logging] +test_log_collect=false +run_id="$RUN_ID" + +[Logging.LogStream] +log_targets=["$LOG_TARGETS"] + +[Logging.Loki] +tenant_id="$LOKI_TENANT_ID" +endpoint="$LOKI_ENDPOINT" +basic_auth_secret="$LOKI_BASIC_AUTH" + +[Logging.Grafana] +base_url="$GRAFANA_URL" +dashboard_url="$GRAFANA_DASHBOARD_URL" +EOF + +BASE64_CONFIG_OVERRIDE=$(cat config.toml | base64 -w 0) +echo ::add-mask::$BASE64_CONFIG_OVERRIDE +echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV +``` + +**It is highly recommended to use reusable GHA actions present in [.actions](../../../.github/.actions) to generate and apply the base64-encoded configuration.** Own implementation of `BASE64_CONFIG_OVERRIDE` generation is discouraged and should be used only if existing actions do not cover the use case. But even in that case it might be a better idea to extend existing actions. + +This variable is automatically relayed to Kubernetes-based tests, eliminating the need for manual intervention in test scripts. + +The `overrides.toml` file is recommended for local use to adjust dynamic variables or modify predefined settings. At the very minimum it should contain the Chainlink image and version, as shown in the example below: + +```toml +[ChainlinkImage] +image = "your image name" +version = "your tag" +``` + +Product-specific configurations, such as those in `[product_name].toml`, house the bulk of default and variant settings, supporting default configurations like the following in `log_poller.toml`: + +```toml +# product defaults +[LogPoller] +[LogPoller.General] +generator = "looped" +contracts = 2 +events_per_tx = 4 +use_finality_tag = true +log_poll_interval = "500ms" +# 0 disables backup poller +backup_log_poller_block_delay = 0 + +[LogPoller.Looped] +execution_count = 100 +min_emit_wait_time_ms = 200 +max_emit_wait_time_ms = 500 +``` + +Named configurations allow for the customization of settings through unique identifiers, such as a test name or type, acting as specific overrides. Here's how you can define and use these configurations: + +For instance, to tailor configurations for a particular test, you might define it as follows: + +```toml +# Here the configuration name is "TestLogManyFiltersPollerFinalityTag" +[TestLogManyFiltersPollerFinalityTag.LogPoller.General] +contracts = 300 +``` + +Alternatively, for a configuration that applies to a certain type of test, as seen in `vrfv2.toml`, you could specify: + +```toml +# Here the configuration name is "Soak" +[Soak.VRFv2.Common] +cancel_subs_after_test_run = true +``` + +When processing TOML files, the system initially searches for a general (unnamed) configuration. If a named configuration is found, it can specifically override the general (unnamed) settings, providing a targeted approach to configuration management based on distinct identifiers like test names or types. + +Finally `default.toml` file is envisioned to contain fundamental and universally applicable settings, such as logging configurations. + +## Local/Kubernetes Usage + +GitHub workflows in this repository have been updated to dynamically generate and utilize base64-encoded TOML configurations derived from user inputs or environment variables. For local execution or remote Kubernetes runners, users must manually supply certain variables, which cannot be embedded in configuration files due to their sensitive or dynamic nature. + +Essential variables might include: +* Chainlink image and version +* Test duration for specific tests (e.g., load, soak) +* Configuration specific to Loki (mandatory for certain tests) +* Grafana dashboard URLs + +For local testing, it is advisable to place these variables in the `overrides.toml` file. For Kubernetes or remote runners, the process involves creating a TOML file with the necessary values, encoding it in base64, and setting the result as the `BASE64_CONFIG_OVERRIDE` environment variable. + +## Embeded config +Because Go automatically excludes TOML files during the compilation of binaries, we must take deliberate steps to include our configuration files in the compiled binary. This can be accomplished by using a custom build tag `-o embed`. Implementing this tag will incorporate all the default configurations located in the `./testconfig` folder directly into the binary. Therefore, when executing tests from the binary, you'll only need to supply the `overrides.toml` file. This file should list only the settings you wish to modify; all other configurations will be sourced from the embedded configurations. You can access these embedded configurations [here](.integration-tests/testconfig/configs_embed.go). + +## To bear in mind +### Validation failures +When the system encounters even a single setting related to a specific product or configuration within the configurations, it triggers a comprehensive validation of the entire configuration for that product. This approach is based on the assumption that if any configuration for a given product is specified, the entire set of configurations for that product must be complete and valid. This is particularly crucial when dealing with the `overrides.toml` file, where it's easy to overlook the need to comment out or adjust values when switching between configurations for different products. Essentially, the presence of any specific configuration detail necessitates that all relevant configurations for that product be fully defined and correct to prevent validation errors. + +## Possible nil pointers +If no configuration values are set for a product or its logging parameters, the system won't perform validation checks. This can lead to a 'nil pointer exception' error if you attempt to access a configuration property later on. This situation arises because we use pointers to facilitate optional overrides; accessing an unset (nil) pointer will cause an error. To avoid such issues, especially when general validations might not cover every scenario, it's crucial for users to ensure that all necessary configuration options are explicitly set. Additionally, it's highly recommended to implement test-specific validations to confirm that all required values for a particular test are indeed established. This proactive approach helps prevent runtime errors and ensures smooth test execution. + +## Contributing +It's crucial to incorporate all new test configuration settings directly into the TOML configuration files, steering clear of using environment variables for this purpose. Our goal is to centralize all configuration details, including examples, within the same package. This approach simplifies the process of understanding the available configuration options and identifying the appropriate values to use for each setting. + +## Reusing TestConfig in other projects +To ensure the cleanliness and simplicity of your project's configuration, it's advised against using the `testconfig` code as a direct library in other projects. The reason is that much of this code is tailored specifically to its current application, which might not align with the requirements of your project. Your project might not necessitate any overrides or could perhaps benefit from a simpler configuration approach. + +However, if you find a need to utilize some methods from this project, the recommended practice is to implement the required interfaces within your project's configuration package, rather than directly copying and pasting code. For instance, if you aim to incorporate a setup action similar to the `SetupVRFV2Environment` for VRFv2, like the one shown below: + +```go +func SetupVRFV2Environment( + env *test_env.CLClusterTestEnv, + nodesToCreate []vrfcommon.VRFNodeType, + vrfv2TestConfig types.VRFv2TestConfig, + useVRFOwner bool, + useTestCoordinator bool, + linkToken contracts.LinkToken, + mockNativeLINKFeed contracts.MockETHLINKFeed, + registerProvingKeyAgainstAddress string, + numberOfTxKeysToCreate int, + numberOfConsumers int, + numberOfSubToCreate int, + l zerolog.Logger, +) (*vrfcommon.VRFContracts, []uint64, *vrfcommon.VRFKeyData, map[vrfcommon.VRFNodeType]*vrfcommon.VRFNode, error) { +``` + +You should not replicate the entire `TestConfig` structure. Instead, create an implementation of the `types.VRFv2TestConfig` interface in your project and use that as the parameter. This approach allows you to maintain a streamlined and focused configuration package in your project. + +## Known Issues/Limitations +* Duplicate file names in different locations may lead to unpredictable configurations being selected. +* The use of pointer fields for optional configuration elements necessitates careful handling, especially for programmatic modifications, to avoid unintended consequences. The `MustCopy()` function is recommended for creating deep copies of configurations for isolated modifications. Unfortunately some of the custom types are not copied at all, you need to set them manually. It's true for example for `blockchain.StrDuration` type. diff --git a/integration-tests/testconfig/testconfig.go b/integration-tests/testconfig/testconfig.go index 89749c6ca1c..7f27ba76700 100644 --- a/integration-tests/testconfig/testconfig.go +++ b/integration-tests/testconfig/testconfig.go @@ -384,6 +384,8 @@ func GetConfig(configurationName string, product Product) (TestConfig, error) { logger.Debug().Msg("Validating test config") err = testConfig.Validate() if err != nil { + logger.Error(). + Msg("Error validating test config. You might want refer to integration-tests/testconfig/README.md for more information.") return TestConfig{}, errors.Wrapf(err, "error validating test config") } @@ -397,7 +399,7 @@ func GetConfig(configurationName string, product Product) (TestConfig, error) { func (c *TestConfig) readNetworkConfiguration() error { // currently we need to read that kind of secrets only for network configuration - if c == nil { + if c.Network == nil { c.Network = &ctf_config.NetworkConfig{} } @@ -421,19 +423,22 @@ func (c *TestConfig) Validate() error { panic(fmt.Errorf("panic during test config validation: '%v'. Most probably due to presence of partial product config", r)) } }() + if c.ChainlinkImage == nil { - return fmt.Errorf("chainlink image config must be set") + return MissingImageInfoAsError("chainlink image config must be set") } - if err := c.ChainlinkImage.Validate(); err != nil { - return errors.Wrapf(err, "chainlink image config validation failed") + if c.ChainlinkImage != nil { + if err := c.ChainlinkImage.Validate(); err != nil { + return MissingImageInfoAsError(fmt.Sprintf("chainlink image config validation failed: %s", err.Error())) + } } if c.ChainlinkUpgradeImage != nil { if err := c.ChainlinkUpgradeImage.Validate(); err != nil { - return errors.Wrapf(err, "chainlink upgrade image config validation failed") + return MissingImageInfoAsError(fmt.Sprintf("chainlink upgrade image config validation failed: %s", err.Error())) } } if err := c.Network.Validate(); err != nil { - return errors.Wrapf(err, "network config validation failed") + return NoSelectedNetworkInfoAsError(fmt.Sprintf("network config validation failed: %s", err.Error())) } if c.Logging == nil { diff --git a/integration-tests/testconfig/testconfig_utils.go b/integration-tests/testconfig/testconfig_utils.go new file mode 100644 index 00000000000..d1803c22650 --- /dev/null +++ b/integration-tests/testconfig/testconfig_utils.go @@ -0,0 +1,70 @@ +package testconfig + +import ( + "fmt" + "os" + "strings" +) + +// MissingImageInfoAsError return a helfpul error message when the no Chainlink image info is found in TOML config. +// If legacy env vars are found it prints ready to use TOML configuration +func MissingImageInfoAsError(errStr string) error { + intro := ` +Old configuration approach detected. Please use TOML instead of env vars. +Please refer to integration-tests/testconfig/README.md for more information. +` + + var imgStr, versionStr string + + if img := os.Getenv("CHAINLINK_IMAGE"); img != "" { + imgStr = fmt.Sprintf("image = \"%s\"\n", img) + } + + if version := os.Getenv("CHAINLINK_VERSION"); version != "" { + versionStr = fmt.Sprintf("version = \"%s\"\n", version) + } + + finalErrStr := fmt.Sprintf("%s\n%s", errStr, intro) + + if imgStr != "" && versionStr != "" { + extraInfo := ` +Or if you want to run your tests right now add following content to integration-tests/testconfig/overrides.toml: +[ChainlinkImage] +` + finalErrStr = fmt.Sprintf("%s\n%s%s%s%s", errStr, intro, extraInfo, imgStr, versionStr) + } + + return fmt.Errorf(finalErrStr) +} + +// NoSelectedNetworkInfoAsError return a helfpul error message when the no selected network info is found in TOML config. +// If legacy env var is found it prints ready to use TOML configuration. +func NoSelectedNetworkInfoAsError(errStr string) error { + intro := ` +Old configuration approach detected. Please use TOML instead of env vars. +Please refer to integration-tests/testconfig/README.md for more information. +` + + finalErrStr := fmt.Sprintf("%s\n%s", errStr, intro) + + if net := os.Getenv("SELECTED_NETWORKS"); net != "" { + parts := strings.Split(net, ",") + selectedNetworkStr := "[" + for i, network := range parts { + selectedNetworkStr += fmt.Sprintf("\"%s\"", network) + + if i < len(parts)-1 { + selectedNetworkStr += ", " + } + } + selectedNetworkStr += "]" + + extraInfo := ` +Or if you want to run your tests right now add following content to integration-tests/testconfig/overrides.toml: +[Network] +selected_networks=` + finalErrStr = fmt.Sprintf("%s\n%s%s%s", errStr, intro, extraInfo, selectedNetworkStr) + } + + return fmt.Errorf(finalErrStr) +} From 30ac78fb9d0f8995f9b33cda9a65023984237973 Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Tue, 5 Mar 2024 11:06:40 -0800 Subject: [PATCH 18/34] chore: migrate to grafana internal (#12270) * fix: remove unused references for grafana cloud * fix: grafana internal for golangci-lint * chore: other grafana internal credentials --- .github/actions/build-chainlink-image/action.yml | 4 ---- .github/actions/golangci-lint/action.yml | 11 +++++++---- .github/workflows/automation-nightly-tests.yml | 2 -- .github/workflows/ci-core.yml | 5 +++-- .github/workflows/ci-scripts.yml | 5 +++-- .github/workflows/client-compatibility-tests.yml | 2 -- .github/workflows/helm-chart.yml | 7 ++++--- .github/workflows/integration-tests-publish.yml | 2 -- .github/workflows/integration-tests.yml | 9 ++++----- .github/workflows/live-testnet-tests.yml | 2 -- .github/workflows/operator-ui-ci.yml | 7 ++++--- 11 files changed, 25 insertions(+), 31 deletions(-) diff --git a/.github/actions/build-chainlink-image/action.yml b/.github/actions/build-chainlink-image/action.yml index 7a2f8a04b71..324a5353b24 100644 --- a/.github/actions/build-chainlink-image/action.yml +++ b/.github/actions/build-chainlink-image/action.yml @@ -11,10 +11,6 @@ inputs: git_commit_sha: description: The git commit sha to use for the image tag default: ${{ github.sha }} - GRAFANA_CLOUD_BASIC_AUTH: - description: "grafana cloud basic auth" - GRAFANA_CLOUD_HOST: - description: "grafana cloud hostname" AWS_REGION: description: "AWS region to use for ECR" AWS_ROLE_TO_ASSUME: diff --git a/.github/actions/golangci-lint/action.yml b/.github/actions/golangci-lint/action.yml index 945bb9fd014..d0fd87774cc 100644 --- a/.github/actions/golangci-lint/action.yml +++ b/.github/actions/golangci-lint/action.yml @@ -21,11 +21,13 @@ inputs: go-module-file: description: Set where the go module file is located at default: "go.sum" - # grafana cloud inputs + # grafana inputs gc-host: - description: "grafana cloud hostname" + description: "grafana hostname" gc-basic-auth: - description: "grafana cloud basic auth" + description: "grafana basic auth" + gc-org-id: + description: "grafana org id" runs: using: composite @@ -64,9 +66,10 @@ runs: path: ${{ inputs.go-directory }}/golangci-lint-report.xml - name: Collect Metrics if: always() - uses: smartcontractkit/push-gha-metrics-action@d1618b772a97fd87e6505de97b872ee0b1f1729a # v2.0.2 + uses: smartcontractkit/push-gha-metrics-action@0281b09807758be1dcc41651e44e62b353808c47 # v2.1.0 with: basic-auth: ${{ inputs.gc-basic-auth }} hostname: ${{ inputs.gc-host }} + org-id: ${{ inputs.gc-org-id }} this-job-name: ${{ inputs.name }} continue-on-error: true diff --git a/.github/workflows/automation-nightly-tests.yml b/.github/workflows/automation-nightly-tests.yml index 83551bd2e6b..0427fe5b47d 100644 --- a/.github/workflows/automation-nightly-tests.yml +++ b/.github/workflows/automation-nightly-tests.yml @@ -38,8 +38,6 @@ jobs: tag_suffix: "" dockerfile: core/chainlink.Dockerfile git_commit_sha: ${{ github.sha }} - GRAFANA_CLOUD_BASIC_AUTH: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} - GRAFANA_CLOUD_HOST: ${{ secrets.GRAFANA_CLOUD_HOST }} AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index 9f43918d27e..19da48d1dac 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -26,8 +26,9 @@ jobs: - name: Golang Lint uses: ./.github/actions/golangci-lint with: - gc-basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} - gc-host: ${{ secrets.GRAFANA_CLOUD_HOST }} + gc-basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + gc-host: ${{ secrets.GRAFANA_INTERNAL_HOST }} + gc-org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - name: Notify Slack if: ${{ failure() && (github.event_name == 'merge_group' || github.event.branch == 'develop')}} uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 diff --git a/.github/workflows/ci-scripts.yml b/.github/workflows/ci-scripts.yml index 11bd53ef995..f44967d5e20 100644 --- a/.github/workflows/ci-scripts.yml +++ b/.github/workflows/ci-scripts.yml @@ -17,8 +17,9 @@ jobs: go-directory: core/scripts go-version-file: core/scripts/go.mod go-module-file: core/scripts/go.sum - gc-basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} - gc-host: ${{ secrets.GRAFANA_CLOUD_HOST }} + gc-basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + gc-host: ${{ secrets.GRAFANA_INTERNAL_HOST }} + gc-org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} test-scripts: if: ${{ github.event_name == 'pull_request' }} diff --git a/.github/workflows/client-compatibility-tests.yml b/.github/workflows/client-compatibility-tests.yml index 3b752746c44..890d938705a 100644 --- a/.github/workflows/client-compatibility-tests.yml +++ b/.github/workflows/client-compatibility-tests.yml @@ -42,8 +42,6 @@ jobs: tag_suffix: "" dockerfile: core/chainlink.Dockerfile git_commit_sha: ${{ github.sha }} - GRAFANA_CLOUD_BASIC_AUTH: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} - GRAFANA_CLOUD_HOST: ${{ secrets.GRAFANA_CLOUD_HOST }} AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} diff --git a/.github/workflows/helm-chart.yml b/.github/workflows/helm-chart.yml index d723ef5cd4d..1a12a512e39 100644 --- a/.github/workflows/helm-chart.yml +++ b/.github/workflows/helm-chart.yml @@ -21,11 +21,12 @@ jobs: helm repo add tempo https://grafana.github.io/helm-charts helm repo add grafana https://grafana.github.io/helm-charts - name: ci-lint-helm-charts - uses: smartcontractkit/.github/actions/ci-lint-charts@9fd15fe8e698a5e28bfd06b3a91471c56568dcb3 # ci-lint-charts@0.1.1 + uses: smartcontractkit/.github/actions/ci-lint-charts@6b08487b176ef7cad086526d0b54ddff6691c044 # ci-lint-charts@0.1.2 with: # chart testing inputs chart-testing-extra-args: "--lint-conf=lintconf.yaml" # grafana inputs metrics-job-name: ci-lint-helm-charts - gc-basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} - gc-host: ${{ secrets.GRAFANA_CLOUD_HOST }} + gc-basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + gc-host: ${{ secrets.GRAFANA_INTERNAL_HOST }} + gc-org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} diff --git a/.github/workflows/integration-tests-publish.yml b/.github/workflows/integration-tests-publish.yml index 71105c93d71..ab4049cdab2 100644 --- a/.github/workflows/integration-tests-publish.yml +++ b/.github/workflows/integration-tests-publish.yml @@ -93,7 +93,5 @@ jobs: tag_suffix: ${{ matrix.image.tag-suffix }} dockerfile: ${{ matrix.image.dockerfile }} git_commit_sha: ${{ github.sha }} - GRAFANA_CLOUD_BASIC_AUTH: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} - GRAFANA_CLOUD_HOST: ${{ secrets.GRAFANA_CLOUD_HOST }} AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 2b1b5e9f83d..e8c15109938 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -160,8 +160,6 @@ jobs: tag_suffix: ${{ matrix.image.tag-suffix }} dockerfile: ${{ matrix.image.dockerfile }} git_commit_sha: ${{ github.sha }} - GRAFANA_CLOUD_BASIC_AUTH: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} - GRAFANA_CLOUD_HOST: ${{ secrets.GRAFANA_CLOUD_HOST }} AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} @@ -270,10 +268,11 @@ jobs: - name: Collect Metrics if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@d1618b772a97fd87e6505de97b872ee0b1f1729a # v2.0.2 + uses: smartcontractkit/push-gha-metrics-action@0281b09807758be1dcc41651e44e62b353808c47 # v2.1.0 with: - basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} this-job-name: ETH Smoke Tests ${{ matrix.product.name }} test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' continue-on-error: true diff --git a/.github/workflows/live-testnet-tests.yml b/.github/workflows/live-testnet-tests.yml index be5944ba1a1..49a4796552f 100644 --- a/.github/workflows/live-testnet-tests.yml +++ b/.github/workflows/live-testnet-tests.yml @@ -86,8 +86,6 @@ jobs: tag_suffix: "" dockerfile: core/chainlink.Dockerfile git_commit_sha: ${{ github.sha }} - GRAFANA_CLOUD_BASIC_AUTH: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} - GRAFANA_CLOUD_HOST: ${{ secrets.GRAFANA_CLOUD_HOST }} AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} diff --git a/.github/workflows/operator-ui-ci.yml b/.github/workflows/operator-ui-ci.yml index 6e1a5e76033..8fbd366a346 100644 --- a/.github/workflows/operator-ui-ci.yml +++ b/.github/workflows/operator-ui-ci.yml @@ -15,10 +15,11 @@ jobs: steps: - name: Collect Metrics id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@v1 + uses: smartcontractkit/push-gha-metrics-action@0281b09807758be1dcc41651e44e62b353808c47 # v2.1.0 with: - basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} this-job-name: Breaking Changes GQL Check continue-on-error: true From b9c1b72a68ee5e58105a421d6e57115b6ecf00d8 Mon Sep 17 00:00:00 2001 From: Anindita Ghosh <88458927+AnieeG@users.noreply.github.com> Date: Tue, 5 Mar 2024 14:06:41 -0800 Subject: [PATCH 19/34] add toml tags to chainlink config (#12305) --- integration-tests/client/chainlink_models.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/integration-tests/client/chainlink_models.go b/integration-tests/client/chainlink_models.go index 0e144d3ab39..f95089f36fa 100644 --- a/integration-tests/client/chainlink_models.go +++ b/integration-tests/client/chainlink_models.go @@ -20,11 +20,11 @@ type EIServiceConfig struct { // ChainlinkConfig represents the variables needed to connect to a Chainlink node type ChainlinkConfig struct { - URL string - Email string - Password string - InternalIP string - HTTPTimeout *time.Duration + URL string `toml:",omitempty"` + Email string `toml:",omitempty"` + Password string `toml:",omitempty"` + InternalIP string `toml:",omitempty"` + HTTPTimeout *time.Duration `toml:"-"` } // ResponseSlice is the generic model that can be used for all Chainlink API responses that are an slice From df9ad537d01891d7e4fe0ccf2dec5f8a6a8de35b Mon Sep 17 00:00:00 2001 From: Sri Kidambi <1702865+kidambisrinivas@users.noreply.github.com> Date: Tue, 5 Mar 2024 22:14:20 +0000 Subject: [PATCH 20/34] Lint warning fixes (#12303) * Lint warning fixes * Update go wrappers * Prettier fix --- contracts/foundry.toml | 10 +++++++ .../scripts/native_solc_compile_all_vrfv2plus | 2 ++ .../src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol | 6 ++-- .../testhelpers/ExposedVRFCoordinatorV2_5.sol | 2 +- .../VRFV2PlusLoadTestWithMetrics.sol | 6 ++-- .../testhelpers/VRFMockETHLINKAggregator.sol | 10 +++---- .../test/v0.8/foundry/vrf/VRFV2Plus.t.sol | 28 +++++++------------ .../vrf_mock_ethlink_aggregator.go | 16 +++++------ ...rapper-dependency-versions-do-not-edit.txt | 2 +- core/gethwrappers/go_generate_vrfv2plus.go | 1 + 10 files changed, 44 insertions(+), 39 deletions(-) diff --git a/contracts/foundry.toml b/contracts/foundry.toml index 13807c71bdf..b87f1f891ea 100644 --- a/contracts/foundry.toml +++ b/contracts/foundry.toml @@ -28,6 +28,16 @@ src = 'src/v0.8/vrf' test = 'test/v0.8/foundry/vrf' # skips tests for no VRF foundry tests solc_version = '0.8.6' +[profile.vrfv2plus_coordinator] +optimizer_runs = 50 +src = 'src/v0.8/vrf' +solc_version = '0.8.6' + +[profile.vrfv2plus] +optimizer_runs = 1_000_000 +src = 'src/v0.8/vrf' +solc_version = '0.8.6' + [profile.automation] optimizer_runs = 10000 src = 'src/v0.8/automation' diff --git a/contracts/scripts/native_solc_compile_all_vrfv2plus b/contracts/scripts/native_solc_compile_all_vrfv2plus index f25d851b5cd..fb7d783cc03 100755 --- a/contracts/scripts/native_solc_compile_all_vrfv2plus +++ b/contracts/scripts/native_solc_compile_all_vrfv2plus @@ -65,3 +65,5 @@ compileContract vrf/dev/TrustedBlockhashStore.sol compileContract vrf/dev/testhelpers/VRFV2PlusLoadTestWithMetrics.sol compileContractAltOpts vrf/dev/testhelpers/VRFCoordinatorV2PlusUpgradedVersion.sol 5 compileContract vrf/dev/testhelpers/VRFV2PlusWrapperLoadTestConsumer.sol +compileContract vrf/testhelpers/VRFMockETHLINKAggregator.sol +compileContract vrf/dev/testhelpers/VRFV2PlusLoadTestWithMetrics.sol diff --git a/contracts/src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol b/contracts/src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol index 619930e6439..e03181b7254 100644 --- a/contracts/src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol +++ b/contracts/src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol @@ -503,7 +503,7 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { uint256 weiPerUnitGas, bool nativePayment, bool onlyPremium - ) internal returns (uint96) { + ) internal view returns (uint96) { if (nativePayment) { return _calculatePaymentAmountNative(startGas, weiPerUnitGas, onlyPremium); } @@ -514,7 +514,7 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { uint256 startGas, uint256 weiPerUnitGas, bool onlyPremium - ) internal returns (uint96) { + ) internal view returns (uint96) { // Will return non-zero on chains that have this enabled uint256 l1CostWei = ChainSpecificUtil._getCurrentTxL1GasFees(msg.data); // calculate the payment without the premium @@ -533,7 +533,7 @@ contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { uint256 startGas, uint256 weiPerUnitGas, bool onlyPremium - ) internal returns (uint96) { + ) internal view returns (uint96) { int256 weiPerUnitLink; weiPerUnitLink = _getFeedData(); if (weiPerUnitLink <= 0) { diff --git a/contracts/src/v0.8/vrf/dev/testhelpers/ExposedVRFCoordinatorV2_5.sol b/contracts/src/v0.8/vrf/dev/testhelpers/ExposedVRFCoordinatorV2_5.sol index 80f74372f15..b3ece7126ef 100644 --- a/contracts/src/v0.8/vrf/dev/testhelpers/ExposedVRFCoordinatorV2_5.sol +++ b/contracts/src/v0.8/vrf/dev/testhelpers/ExposedVRFCoordinatorV2_5.sol @@ -71,7 +71,7 @@ contract ExposedVRFCoordinatorV2_5 is VRFCoordinatorV2_5 { uint256 weiPerUnitGas, bool nativePayment, bool onlyPremium - ) external returns (uint96) { + ) external view returns (uint96) { return _calculatePaymentAmount(startGas, weiPerUnitGas, nativePayment, onlyPremium); } } diff --git a/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusLoadTestWithMetrics.sol b/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusLoadTestWithMetrics.sol index 45eb14ee19d..d937728a790 100644 --- a/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusLoadTestWithMetrics.sol +++ b/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusLoadTestWithMetrics.sol @@ -149,16 +149,16 @@ contract VRFV2PlusLoadTestWithMetrics is VRFConsumerBaseV2Plus { uint256 _slowestResponseTime, uint256 _averageInMillions, uint256 _responseCount - ) internal returns (uint256 slowest, uint256 fastest, uint256 average) { + ) internal pure returns (uint256 slowest, uint256 fastest, uint256 average) { uint256 _requestDelayInMillions = _responseTime * 1_000_000; if (_responseTime > _slowestResponseTime) { _slowestResponseTime = _responseTime; } _fastestResponseTime = _responseTime < _fastestResponseTime ? _responseTime : _fastestResponseTime; - uint256 _averageInMillions = _responseCount > 0 + uint256 averageInMillions = _responseCount > 0 ? (_averageInMillions * _responseCount + _requestDelayInMillions) / (_responseCount + 1) : _requestDelayInMillions; - return (_slowestResponseTime, _fastestResponseTime, _averageInMillions); + return (_slowestResponseTime, _fastestResponseTime, averageInMillions); } } diff --git a/contracts/src/v0.8/vrf/testhelpers/VRFMockETHLINKAggregator.sol b/contracts/src/v0.8/vrf/testhelpers/VRFMockETHLINKAggregator.sol index 86c77202434..4052c0d0a2b 100644 --- a/contracts/src/v0.8/vrf/testhelpers/VRFMockETHLINKAggregator.sol +++ b/contracts/src/v0.8/vrf/testhelpers/VRFMockETHLINKAggregator.sol @@ -7,24 +7,24 @@ contract VRFMockETHLINKAggregator is AggregatorV3Interface { int256 public answer; uint256 private blockTimestampDeduction = 0; - constructor(int256 _answer) public { + constructor(int256 _answer) { answer = _answer; } - function decimals() external view override returns (uint8) { + function decimals() external pure override returns (uint8) { return 18; } - function description() external view override returns (string memory) { + function description() external pure override returns (string memory) { return "VRFMockETHLINKAggregator"; } - function version() external view override returns (uint256) { + function version() external pure override returns (uint256) { return 1; } function getRoundData( - uint80 _roundId + uint80 /*_roundId*/ ) external view diff --git a/contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol b/contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol index 44daade0b1e..7fbbd788bdd 100644 --- a/contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol +++ b/contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol @@ -410,7 +410,7 @@ contract VRFV2Plus is BaseTest { vm.roll(requestBlock); s_linkToken.transfer(address(s_testConsumer), 10 ether); s_testConsumer.createSubscriptionAndFund(10 ether); - uint256 subId = s_testConsumer.s_subId(); + subId = s_testConsumer.s_subId(); // Apply basic configs to contract. setConfig(); @@ -418,12 +418,8 @@ contract VRFV2Plus is BaseTest { // Request random words. vm.expectEmit(true, true, false, true); - (uint256 requestId, uint256 preSeed) = s_testCoordinator.computeRequestIdExternal( - vrfKeyHash, - address(s_testConsumer), - subId, - 2 - ); + uint256 preSeed; + (requestId, preSeed) = s_testCoordinator.computeRequestIdExternal(vrfKeyHash, address(s_testConsumer), subId, 2); emit RandomWordsRequested( vrfKeyHash, requestId, @@ -460,7 +456,7 @@ contract VRFV2Plus is BaseTest { -block-num 20 \ -sender 0x90A8820424CC8a819d14cBdE54D12fD3fbFa9bb2 */ - VRF.Proof memory proof = VRF.Proof({ + proof = VRF.Proof({ pk: [ 72488970228380509287422715226575535698893157273063074627791787432852706183111, 62070622898698443831883535403436258712770888294397026493185421712108624767191 @@ -483,7 +479,7 @@ contract VRFV2Plus is BaseTest { ], zInv: 100579074451139970455673776933943662313989441807178260211316504761358492254052 }); - VRFCoordinatorV2_5.RequestCommitment memory rc = VRFCoordinatorV2_5.RequestCommitment({ + rc = VRFCoordinatorV2_5.RequestCommitment({ blockNum: requestBlock, subId: subId, callbackGasLimit: 1000000, @@ -501,7 +497,7 @@ contract VRFV2Plus is BaseTest { uint32 requestBlock = 10; vm.roll(requestBlock); s_testConsumer.createSubscriptionAndFund(0); - uint256 subId = s_testConsumer.s_subId(); + subId = s_testConsumer.s_subId(); s_testCoordinator.fundSubscriptionWithNative{value: 10 ether}(subId); // Apply basic configs to contract. @@ -510,12 +506,8 @@ contract VRFV2Plus is BaseTest { // Request random words. vm.expectEmit(true, true, true, true); - (uint256 requestId, uint256 preSeed) = s_testCoordinator.computeRequestIdExternal( - vrfKeyHash, - address(s_testConsumer), - subId, - 2 - ); + uint256 preSeed; + (requestId, preSeed) = s_testCoordinator.computeRequestIdExternal(vrfKeyHash, address(s_testConsumer), subId, 2); emit RandomWordsRequested( vrfKeyHash, requestId, @@ -553,7 +545,7 @@ contract VRFV2Plus is BaseTest { -sender 0x90A8820424CC8a819d14cBdE54D12fD3fbFa9bb2 \ -native-payment true */ - VRF.Proof memory proof = VRF.Proof({ + proof = VRF.Proof({ pk: [ 72488970228380509287422715226575535698893157273063074627791787432852706183111, 62070622898698443831883535403436258712770888294397026493185421712108624767191 @@ -576,7 +568,7 @@ contract VRFV2Plus is BaseTest { ], zInv: 97568175302326019383632009699686265453584842953005404815285123863099260038246 }); - VRFCoordinatorV2_5.RequestCommitment memory rc = VRFCoordinatorV2_5.RequestCommitment({ + rc = VRFCoordinatorV2_5.RequestCommitment({ blockNum: requestBlock, subId: subId, callbackGasLimit: 1_000_000, diff --git a/core/gethwrappers/generated/vrf_mock_ethlink_aggregator/vrf_mock_ethlink_aggregator.go b/core/gethwrappers/generated/vrf_mock_ethlink_aggregator/vrf_mock_ethlink_aggregator.go index d6736acfb9b..f18ca149896 100644 --- a/core/gethwrappers/generated/vrf_mock_ethlink_aggregator/vrf_mock_ethlink_aggregator.go +++ b/core/gethwrappers/generated/vrf_mock_ethlink_aggregator/vrf_mock_ethlink_aggregator.go @@ -29,7 +29,7 @@ var ( ) var VRFMockETHLINKAggregatorMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"_answer\",\"type\":\"int256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"answer\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"description\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint80\",\"name\":\"_roundId\",\"type\":\"uint80\"}],\"name\":\"getRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"roundId\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"ans\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"startedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint80\",\"name\":\"answeredInRound\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"roundId\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"ans\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"startedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint80\",\"name\":\"answeredInRound\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_blockTimestampDeduction\",\"type\":\"uint256\"}],\"name\":\"setBlockTimestampDeduction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"_answer\",\"type\":\"int256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"answer\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"description\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint80\",\"name\":\"\",\"type\":\"uint80\"}],\"name\":\"getRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"roundId\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"ans\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"startedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint80\",\"name\":\"answeredInRound\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"roundId\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"ans\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"startedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint80\",\"name\":\"answeredInRound\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_blockTimestampDeduction\",\"type\":\"uint256\"}],\"name\":\"setBlockTimestampDeduction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", Bin: "0x6080604052600060015534801561001557600080fd5b506040516103383803806103388339810160408190526100349161003c565b600055610055565b60006020828403121561004e57600080fd5b5051919050565b6102d4806100646000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c806385bb7d691161005b57806385bb7d69146100e65780639a6fc8f5146100ef578063f0ad37df14610139578063feaf968c1461014e57600080fd5b8063313ce5671461008257806354fd4d50146100965780637284e416146100a7575b600080fd5b604051601281526020015b60405180910390f35b60015b60405190815260200161008d565b604080518082018252601881527f5652464d6f636b4554484c494e4b41676772656761746f7200000000000000006020820152905161008d9190610216565b61009960005481565b6101026100fd3660046101e3565b610156565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a00161008d565b61014c6101473660046101ca565b600155565b005b610102610186565b6000806000806000600160005461016b6101b5565b6101736101b5565b9299919850965090945060019350915050565b6000806000806000600160005461019b6101b5565b6101a36101b5565b92989197509550909350600192509050565b6000600154426101c59190610289565b905090565b6000602082840312156101dc57600080fd5b5035919050565b6000602082840312156101f557600080fd5b813569ffffffffffffffffffff8116811461020f57600080fd5b9392505050565b600060208083528351808285015260005b8181101561024357858101830151858201604001528201610227565b81811115610255576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000828210156102c2577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c6343000806000a", } @@ -235,11 +235,11 @@ func (_VRFMockETHLINKAggregator *VRFMockETHLINKAggregatorCallerSession) Descript return _VRFMockETHLINKAggregator.Contract.Description(&_VRFMockETHLINKAggregator.CallOpts) } -func (_VRFMockETHLINKAggregator *VRFMockETHLINKAggregatorCaller) GetRoundData(opts *bind.CallOpts, _roundId *big.Int) (GetRoundData, +func (_VRFMockETHLINKAggregator *VRFMockETHLINKAggregatorCaller) GetRoundData(opts *bind.CallOpts, arg0 *big.Int) (GetRoundData, error) { var out []interface{} - err := _VRFMockETHLINKAggregator.contract.Call(opts, &out, "getRoundData", _roundId) + err := _VRFMockETHLINKAggregator.contract.Call(opts, &out, "getRoundData", arg0) outstruct := new(GetRoundData) if err != nil { @@ -256,16 +256,16 @@ func (_VRFMockETHLINKAggregator *VRFMockETHLINKAggregatorCaller) GetRoundData(op } -func (_VRFMockETHLINKAggregator *VRFMockETHLINKAggregatorSession) GetRoundData(_roundId *big.Int) (GetRoundData, +func (_VRFMockETHLINKAggregator *VRFMockETHLINKAggregatorSession) GetRoundData(arg0 *big.Int) (GetRoundData, error) { - return _VRFMockETHLINKAggregator.Contract.GetRoundData(&_VRFMockETHLINKAggregator.CallOpts, _roundId) + return _VRFMockETHLINKAggregator.Contract.GetRoundData(&_VRFMockETHLINKAggregator.CallOpts, arg0) } -func (_VRFMockETHLINKAggregator *VRFMockETHLINKAggregatorCallerSession) GetRoundData(_roundId *big.Int) (GetRoundData, +func (_VRFMockETHLINKAggregator *VRFMockETHLINKAggregatorCallerSession) GetRoundData(arg0 *big.Int) (GetRoundData, error) { - return _VRFMockETHLINKAggregator.Contract.GetRoundData(&_VRFMockETHLINKAggregator.CallOpts, _roundId) + return _VRFMockETHLINKAggregator.Contract.GetRoundData(&_VRFMockETHLINKAggregator.CallOpts, arg0) } func (_VRFMockETHLINKAggregator *VRFMockETHLINKAggregatorCaller) LatestRoundData(opts *bind.CallOpts) (LatestRoundData, @@ -361,7 +361,7 @@ type VRFMockETHLINKAggregatorInterface interface { Description(opts *bind.CallOpts) (string, error) - GetRoundData(opts *bind.CallOpts, _roundId *big.Int) (GetRoundData, + GetRoundData(opts *bind.CallOpts, arg0 *big.Int) (GetRoundData, error) diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 89c92d2b4cb..545e5f6dfda 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -98,7 +98,7 @@ vrf_load_test_with_metrics: ../../contracts/solc/v0.8.6/VRFV2LoadTestWithMetrics vrf_log_emitter: ../../contracts/solc/v0.8.19/VRFLogEmitter/VRFLogEmitter.abi ../../contracts/solc/v0.8.19/VRFLogEmitter/VRFLogEmitter.bin 15f491d445ac4d0c712d1cbe4e5054c759b080bf20de7d54bfe2a82cde4dcf06 vrf_malicious_consumer_v2: ../../contracts/solc/v0.8.6/VRFMaliciousConsumerV2/VRFMaliciousConsumerV2.abi ../../contracts/solc/v0.8.6/VRFMaliciousConsumerV2/VRFMaliciousConsumerV2.bin 9755fa8ffc7f5f0b337d5d413d77b0c9f6cd6f68c31727d49acdf9d4a51bc522 vrf_malicious_consumer_v2_plus: ../../contracts/solc/v0.8.6/VRFMaliciousConsumerV2Plus/VRFMaliciousConsumerV2Plus.abi ../../contracts/solc/v0.8.6/VRFMaliciousConsumerV2Plus/VRFMaliciousConsumerV2Plus.bin e2a72638e11da807b6533d037e7e5aaeed695efd5035777b8e20d2f8973a574c -vrf_mock_ethlink_aggregator: ../../contracts/solc/v0.8.6/VRFMockETHLINKAggregator/VRFMockETHLINKAggregator.abi ../../contracts/solc/v0.8.6/VRFMockETHLINKAggregator/VRFMockETHLINKAggregator.bin a6e753984eeec8107e205ae517f74d4616bf23cffda50a25538ffc16ac4b036f +vrf_mock_ethlink_aggregator: ../../contracts/solc/v0.8.6/VRFMockETHLINKAggregator/VRFMockETHLINKAggregator.abi ../../contracts/solc/v0.8.6/VRFMockETHLINKAggregator/VRFMockETHLINKAggregator.bin 3657f8c552147eb55d7538fa7d8012c1a983d8c5184610de60600834a72e006b vrf_owner: ../../contracts/solc/v0.8.6/VRFOwner/VRFOwner.abi ../../contracts/solc/v0.8.6/VRFOwner/VRFOwner.bin eccfae5ee295b5850e22f61240c469f79752b8d9a3bac5d64aec7ac8def2f6cb vrf_owner_test_consumer: ../../contracts/solc/v0.8.6/VRFV2OwnerTestConsumer/VRFV2OwnerTestConsumer.abi ../../contracts/solc/v0.8.6/VRFV2OwnerTestConsumer/VRFV2OwnerTestConsumer.bin 6969de242efe8f366ae4097fc279d9375c8e2d0307aaa322e31f2ce6b8c1909a vrf_ownerless_consumer_example: ../../contracts/solc/v0.8.6/VRFOwnerlessConsumerExample/VRFOwnerlessConsumerExample.abi ../../contracts/solc/v0.8.6/VRFOwnerlessConsumerExample/VRFOwnerlessConsumerExample.bin 9893b3805863273917fb282eed32274e32aa3d5c2a67a911510133e1218132be diff --git a/core/gethwrappers/go_generate_vrfv2plus.go b/core/gethwrappers/go_generate_vrfv2plus.go index efd11050034..b8002dd91c0 100644 --- a/core/gethwrappers/go_generate_vrfv2plus.go +++ b/core/gethwrappers/go_generate_vrfv2plus.go @@ -19,3 +19,4 @@ package gethwrappers //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFV2PlusLoadTestWithMetrics/VRFV2PlusLoadTestWithMetrics.abi ../../contracts/solc/v0.8.6/VRFV2PlusLoadTestWithMetrics/VRFV2PlusLoadTestWithMetrics.bin VRFV2PlusLoadTestWithMetrics vrf_v2plus_load_test_with_metrics //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFCoordinatorV2PlusUpgradedVersion/VRFCoordinatorV2PlusUpgradedVersion.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2PlusUpgradedVersion/VRFCoordinatorV2PlusUpgradedVersion.bin VRFCoordinatorV2PlusUpgradedVersion vrf_v2plus_upgraded_version //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFV2PlusWrapperLoadTestConsumer/VRFV2PlusWrapperLoadTestConsumer.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapperLoadTestConsumer/VRFV2PlusWrapperLoadTestConsumer.bin VRFV2PlusWrapperLoadTestConsumer vrfv2plus_wrapper_load_test_consumer +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFMockETHLINKAggregator/VRFMockETHLINKAggregator.abi ../../contracts/solc/v0.8.6/VRFMockETHLINKAggregator/VRFMockETHLINKAggregator.bin VRFMockETHLINKAggregator vrf_mock_ethlink_aggregator From dc365c24ef074806ab02288d1b5dae37de690588 Mon Sep 17 00:00:00 2001 From: Lei Date: Tue, 5 Mar 2024 16:24:51 -0800 Subject: [PATCH 21/34] set foundation for v2.3 (#12306) --- ...nerate-automation-master-interface-v2_3.ts | 50 + .../native_solc_compile_all_automation | 9 +- contracts/src/v0.8/automation/README.md | 40 + .../automation/dev/chains/ChainModuleBase.sol | 2 +- .../interfaces/{v2_2 => }/IChainModule.sol | 0 .../v2_3/IAutomationRegistryMaster2_3.sol | 339 + .../dev/test/AutomationRegistry2_3.t.sol | 198 + .../dev/v2_2/AutomationRegistryBase2_2.sol | 2 +- .../dev/v2_2/AutomationRegistryLogicB2_2.sol | 2 +- .../dev/v2_3/AutomationRegistrar2_3.sol | 537 ++ .../dev/v2_3/AutomationRegistry2_3.sol | 416 + .../dev/v2_3/AutomationRegistryBase2_3.sol | 956 +++ .../dev/v2_3/AutomationRegistryLogicA2_3.sol | 431 ++ .../dev/v2_3/AutomationRegistryLogicB2_3.sol | 539 ++ .../dev/v2_3/AutomationUtils2_3.sol | 40 + .../src/v0.8/automation/dev/v2_3/LICENSE | 57 + .../automation/AutomationRegistrar2_3.test.ts | 1026 +++ .../automation/AutomationRegistry2_2.test.ts | 4 +- .../automation/AutomationRegistry2_3.test.ts | 5884 +++++++++++++++ contracts/test/v0.8/automation/helpers.ts | 36 + .../automation_registrar_wrapper2_3.go | 1685 +++++ ...automation_registry_logic_a_wrapper_2_3.go | 4992 ++++++++++++ ...automation_registry_logic_b_wrapper_2_3.go | 5933 +++++++++++++++ .../automation_registry_wrapper_2_3.go | 5300 +++++++++++++ .../automation_utils_2_3.go | 324 + ..._automation_registry_master_wrapper_2_3.go | 6687 +++++++++++++++++ ...rapper-dependency-versions-do-not-edit.txt | 6 + core/gethwrappers/go_generate.go | 6 + 28 files changed, 35496 insertions(+), 5 deletions(-) create mode 100644 contracts/scripts/generate-automation-master-interface-v2_3.ts create mode 100644 contracts/src/v0.8/automation/README.md rename contracts/src/v0.8/automation/dev/interfaces/{v2_2 => }/IChainModule.sol (100%) create mode 100644 contracts/src/v0.8/automation/dev/interfaces/v2_3/IAutomationRegistryMaster2_3.sol create mode 100644 contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol create mode 100644 contracts/src/v0.8/automation/dev/v2_3/AutomationRegistrar2_3.sol create mode 100644 contracts/src/v0.8/automation/dev/v2_3/AutomationRegistry2_3.sol create mode 100644 contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol create mode 100644 contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicA2_3.sol create mode 100644 contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicB2_3.sol create mode 100644 contracts/src/v0.8/automation/dev/v2_3/AutomationUtils2_3.sol create mode 100644 contracts/src/v0.8/automation/dev/v2_3/LICENSE create mode 100644 contracts/test/v0.8/automation/AutomationRegistrar2_3.test.ts create mode 100644 contracts/test/v0.8/automation/AutomationRegistry2_3.test.ts create mode 100644 core/gethwrappers/generated/automation_registrar_wrapper2_3/automation_registrar_wrapper2_3.go create mode 100644 core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_3/automation_registry_logic_a_wrapper_2_3.go create mode 100644 core/gethwrappers/generated/automation_registry_logic_b_wrapper_2_3/automation_registry_logic_b_wrapper_2_3.go create mode 100644 core/gethwrappers/generated/automation_registry_wrapper_2_3/automation_registry_wrapper_2_3.go create mode 100644 core/gethwrappers/generated/automation_utils_2_3/automation_utils_2_3.go create mode 100644 core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3/i_automation_registry_master_wrapper_2_3.go diff --git a/contracts/scripts/generate-automation-master-interface-v2_3.ts b/contracts/scripts/generate-automation-master-interface-v2_3.ts new file mode 100644 index 00000000000..436ae93c172 --- /dev/null +++ b/contracts/scripts/generate-automation-master-interface-v2_3.ts @@ -0,0 +1,50 @@ +/** + * @description this script generates a master interface for interacting with the automation registry + * @notice run this script with pnpm ts-node ./scripts/generate-automation-master-interface-v2_3.ts + */ +import { AutomationRegistry2_3__factory as Registry } from '../typechain/factories/AutomationRegistry2_3__factory' +import { AutomationRegistryLogicA2_3__factory as RegistryLogicA } from '../typechain/factories/AutomationRegistryLogicA2_3__factory' +import { AutomationRegistryLogicB2_3__factory as RegistryLogicB } from '../typechain/factories/AutomationRegistryLogicB2_3__factory' +import { utils } from 'ethers' +import fs from 'fs' +import { exec } from 'child_process' + +const dest = 'src/v0.8/automation/dev/interfaces/v2_3' +const srcDest = `${dest}/IAutomationRegistryMaster2_3.sol` +const tmpDest = `${dest}/tmp.txt` + +const combinedABI = [] +const abiSet = new Set() +const abis = [Registry.abi, RegistryLogicA.abi, RegistryLogicB.abi] + +for (const abi of abis) { + for (const entry of abi) { + const id = utils.id(JSON.stringify(entry)) + if (!abiSet.has(id)) { + abiSet.add(id) + if ( + entry.type === 'function' && + (entry.name === 'checkUpkeep' || + entry.name === 'checkCallback' || + entry.name === 'simulatePerformUpkeep') + ) { + entry.stateMutability = 'view' // override stateMutability for check / callback / simulate functions + } + combinedABI.push(entry) + } + } +} + +const checksum = utils.id(abis.join('')) + +fs.writeFileSync(`${tmpDest}`, JSON.stringify(combinedABI)) + +const cmd = ` +cat ${tmpDest} | pnpm abi-to-sol --solidity-version ^0.8.4 --license MIT > ${srcDest} IAutomationRegistryMaster; +echo "// abi-checksum: ${checksum}" | cat - ${srcDest} > ${tmpDest} && mv ${tmpDest} ${srcDest}; +pnpm prettier --write ${srcDest}; +` + +exec(cmd) + +console.log('generated new master interface for automation registry') diff --git a/contracts/scripts/native_solc_compile_all_automation b/contracts/scripts/native_solc_compile_all_automation index c508079813e..248462f421a 100755 --- a/contracts/scripts/native_solc_compile_all_automation +++ b/contracts/scripts/native_solc_compile_all_automation @@ -96,4 +96,11 @@ compileContract automation/dev/chains/ArbitrumModule.sol compileContract automation/dev/chains/ChainModuleBase.sol compileContract automation/dev/chains/OptimismModule.sol compileContract automation/dev/chains/ScrollModule.sol -compileContract automation/dev/interfaces/v2_2/IChainModule.sol \ No newline at end of file + +compileContract automation/dev/interfaces/IChainModule.sol +compileContract automation/dev/v2_3/AutomationRegistrar2_3.sol +compileContract automation/dev/v2_3/AutomationRegistry2_3.sol +compileContract automation/dev/v2_3/AutomationRegistryLogicA2_3.sol +compileContract automation/dev/v2_3/AutomationRegistryLogicB2_3.sol +compileContract automation/dev/v2_3/AutomationUtils2_3.sol +compileContract automation/dev/interfaces/v2_3/IAutomationRegistryMaster2_3.sol \ No newline at end of file diff --git a/contracts/src/v0.8/automation/README.md b/contracts/src/v0.8/automation/README.md new file mode 100644 index 00000000000..9714ccb921b --- /dev/null +++ b/contracts/src/v0.8/automation/README.md @@ -0,0 +1,40 @@ +# Automation Contract Structure + +The on-chain component of Chainlink automation is too large to fit into the [size requirements][size-limit-eip] of a single contract. It is also too large to fit into 2 contracts, a solution that works for most large projects. Therefore, we included this explanation of how the pieces fit together and various tradeoffs incurred. + +### Glossary + +**Master Contract** - also known as the “storage” contract. This is the contract whose state we care about. It is the entry-point into the chain of delegatecalls. (We avoid the term "proxy" because it is commonly associated with upgradability, and this system _is not upgradable_ even though it relies on some of the same mechanics.) + +**Logic Contract** - this a contract whose sole purpose is to hold code. We use the code at this address and execute it in the context of the master contract in order to increase our total capacity for on-chain code. + +### Overview + +We chain multiple logic contracts together using [fallback functions][fallback] and [delegatecall][delegatecall]. If a function definition is not found on one contract, we fall back to the next, always executing the function in the scope of the master contract. The actual implementation of this is based off of [OZ's Proxy contract][oz-proxy]. + +### Diagram + +```mermaid +graph LR + Master -- delegatecall --> la[Logic A] + la -- delegatecall --> lb[Logic B] + lb -. delegatecall .-> lx[Logic X] +``` + +### Special Considerations + +- functions on the master contract have the least gas overhead, therefore, our most price-sensitive functions live there +- functions on the master contract have first-class support from tools like etherscan and tenderly - functions that we (or users) call often to debug should live there +- etherscan supports executing logic contract functions that are once removed from the master - therefore we give secondary preference to the first logic contract for user and debugging functions +- functions on logic A through logic X (as of writing) have no support on etherscan and will essentially be "invisible" to everyone but advanced users - we will try to reserve this space for uncommon interactions that are mostly done progamatically +- We use Logic A, B, C... to avoid confusion with the version ex `AutomationRegistryLogicA2_1.sol` --> Logic Contract A verion 2.1 +- Storage locations for logic contract addresses MUST BE BYTECODE (this is done by marking them as "immutable") otherwise the chaining mechanism will break + +### Master Interface + +The Master Interface is a deduped combination of all the interfaces from all contracts in the chain. We generate this interface programatically using the script `generate-automation-master-interface.ts`. This process is not a hardened one. Users of this script should take great care to ensure it's efficacy. + +[size-limit-eip]: https://eips.ethereum.org/EIPS/eip-170 +[fallback]: https://docs.soliditylang.org/en/v0.8.12/contracts.html#fallback-function +[delegatecall]: https://docs.soliditylang.org/en/v0.8.12/introduction-to-smart-contracts.html?highlight=delegatecall#delegatecall-callcode-and-libraries +[oz-proxy]: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Proxy \ No newline at end of file diff --git a/contracts/src/v0.8/automation/dev/chains/ChainModuleBase.sol b/contracts/src/v0.8/automation/dev/chains/ChainModuleBase.sol index eccca624927..e9b082063bb 100644 --- a/contracts/src/v0.8/automation/dev/chains/ChainModuleBase.sol +++ b/contracts/src/v0.8/automation/dev/chains/ChainModuleBase.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {IChainModule} from "../interfaces/v2_2/IChainModule.sol"; +import {IChainModule} from "../interfaces/IChainModule.sol"; contract ChainModuleBase is IChainModule { uint256 private constant FIXED_GAS_OVERHEAD = 300; diff --git a/contracts/src/v0.8/automation/dev/interfaces/v2_2/IChainModule.sol b/contracts/src/v0.8/automation/dev/interfaces/IChainModule.sol similarity index 100% rename from contracts/src/v0.8/automation/dev/interfaces/v2_2/IChainModule.sol rename to contracts/src/v0.8/automation/dev/interfaces/IChainModule.sol diff --git a/contracts/src/v0.8/automation/dev/interfaces/v2_3/IAutomationRegistryMaster2_3.sol b/contracts/src/v0.8/automation/dev/interfaces/v2_3/IAutomationRegistryMaster2_3.sol new file mode 100644 index 00000000000..b9be96dee35 --- /dev/null +++ b/contracts/src/v0.8/automation/dev/interfaces/v2_3/IAutomationRegistryMaster2_3.sol @@ -0,0 +1,339 @@ +// abi-checksum: 0xfc319f2ddde95d2e0226c913b9e417495effc4c8c847d01fe07e3de68ea8839c +// SPDX-License-Identifier: MIT +// !! THIS FILE WAS AUTOGENERATED BY abi-to-sol v0.6.6. SEE SOURCE BELOW. !! +pragma solidity ^0.8.4; + +interface IAutomationRegistryMaster { + error ArrayHasNoEntries(); + error CannotCancel(); + error CheckDataExceedsLimit(); + error ConfigDigestMismatch(); + error DuplicateEntry(); + error DuplicateSigners(); + error GasLimitCanOnlyIncrease(); + error GasLimitOutsideRange(); + error IncorrectNumberOfFaultyOracles(); + error IncorrectNumberOfSignatures(); + error IncorrectNumberOfSigners(); + error IndexOutOfRange(); + error InvalidDataLength(); + error InvalidPayee(); + error InvalidRecipient(); + error InvalidReport(); + error InvalidSigner(); + error InvalidTransmitter(); + error InvalidTrigger(); + error InvalidTriggerType(); + error MaxCheckDataSizeCanOnlyIncrease(); + error MaxPerformDataSizeCanOnlyIncrease(); + error MigrationNotPermitted(); + error NotAContract(); + error OnlyActiveSigners(); + error OnlyActiveTransmitters(); + error OnlyCallableByAdmin(); + error OnlyCallableByLINKToken(); + error OnlyCallableByOwnerOrAdmin(); + error OnlyCallableByOwnerOrRegistrar(); + error OnlyCallableByPayee(); + error OnlyCallableByProposedAdmin(); + error OnlyCallableByProposedPayee(); + error OnlyCallableByUpkeepPrivilegeManager(); + error OnlyPausedUpkeep(); + error OnlySimulatedBackend(); + error OnlyUnpausedUpkeep(); + error ParameterLengthError(); + error PaymentGreaterThanAllLINK(); + error ReentrantCall(); + error RegistryPaused(); + error RepeatedSigner(); + error RepeatedTransmitter(); + error TargetCheckReverted(bytes reason); + error TooManyOracles(); + error TranscoderNotSet(); + error UpkeepAlreadyExists(); + error UpkeepCancelled(); + error UpkeepNotCanceled(); + error UpkeepNotNeeded(); + error ValueNotChanged(); + event AdminPrivilegeConfigSet(address indexed admin, bytes privilegeConfig); + event CancelledUpkeepReport(uint256 indexed id, bytes trigger); + event ChainSpecificModuleUpdated(address newModule); + event ConfigSet( + uint32 previousConfigBlockNumber, + bytes32 configDigest, + uint64 configCount, + address[] signers, + address[] transmitters, + uint8 f, + bytes onchainConfig, + uint64 offchainConfigVersion, + bytes offchainConfig + ); + event DedupKeyAdded(bytes32 indexed dedupKey); + event FundsAdded(uint256 indexed id, address indexed from, uint96 amount); + event FundsWithdrawn(uint256 indexed id, uint256 amount, address to); + event InsufficientFundsUpkeepReport(uint256 indexed id, bytes trigger); + event OwnerFundsWithdrawn(uint96 amount); + event OwnershipTransferRequested(address indexed from, address indexed to); + event OwnershipTransferred(address indexed from, address indexed to); + event Paused(address account); + event PayeesUpdated(address[] transmitters, address[] payees); + event PayeeshipTransferRequested(address indexed transmitter, address indexed from, address indexed to); + event PayeeshipTransferred(address indexed transmitter, address indexed from, address indexed to); + event PaymentWithdrawn(address indexed transmitter, uint256 indexed amount, address indexed to, address payee); + event ReorgedUpkeepReport(uint256 indexed id, bytes trigger); + event StaleUpkeepReport(uint256 indexed id, bytes trigger); + event Transmitted(bytes32 configDigest, uint32 epoch); + event Unpaused(address account); + event UpkeepAdminTransferRequested(uint256 indexed id, address indexed from, address indexed to); + event UpkeepAdminTransferred(uint256 indexed id, address indexed from, address indexed to); + event UpkeepCanceled(uint256 indexed id, uint64 indexed atBlockHeight); + event UpkeepCheckDataSet(uint256 indexed id, bytes newCheckData); + event UpkeepGasLimitSet(uint256 indexed id, uint96 gasLimit); + event UpkeepMigrated(uint256 indexed id, uint256 remainingBalance, address destination); + event UpkeepOffchainConfigSet(uint256 indexed id, bytes offchainConfig); + event UpkeepPaused(uint256 indexed id); + event UpkeepPerformed( + uint256 indexed id, + bool indexed success, + uint96 totalPayment, + uint256 gasUsed, + uint256 gasOverhead, + bytes trigger + ); + event UpkeepPrivilegeConfigSet(uint256 indexed id, bytes privilegeConfig); + event UpkeepReceived(uint256 indexed id, uint256 startingBalance, address importedFrom); + event UpkeepRegistered(uint256 indexed id, uint32 performGas, address admin); + event UpkeepTriggerConfigSet(uint256 indexed id, bytes triggerConfig); + event UpkeepUnpaused(uint256 indexed id); + fallback() external; + function acceptOwnership() external; + function fallbackTo() external view returns (address); + function latestConfigDetails() external view returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest); + function latestConfigDigestAndEpoch() external view returns (bool scanLogs, bytes32 configDigest, uint32 epoch); + function onTokenTransfer(address sender, uint256 amount, bytes memory data) external; + function owner() external view returns (address); + function setConfig( + address[] memory signers, + address[] memory transmitters, + uint8 f, + bytes memory onchainConfigBytes, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) external; + function setConfigTypeSafe( + address[] memory signers, + address[] memory transmitters, + uint8 f, + AutomationRegistryBase2_3.OnchainConfig memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) external; + function simulatePerformUpkeep( + uint256 id, + bytes memory performData + ) external view returns (bool success, uint256 gasUsed); + function transferOwnership(address to) external; + function transmit( + bytes32[3] memory reportContext, + bytes memory rawReport, + bytes32[] memory rs, + bytes32[] memory ss, + bytes32 rawVs + ) external; + function typeAndVersion() external view returns (string memory); + + function addFunds(uint256 id, uint96 amount) external; + function cancelUpkeep(uint256 id) external; + function checkCallback( + uint256 id, + bytes[] memory values, + bytes memory extraData + ) external view returns (bool upkeepNeeded, bytes memory performData, uint8 upkeepFailureReason, uint256 gasUsed); + function checkUpkeep( + uint256 id, + bytes memory triggerData + ) + external + view + returns ( + bool upkeepNeeded, + bytes memory performData, + uint8 upkeepFailureReason, + uint256 gasUsed, + uint256 gasLimit, + uint256 fastGasWei, + uint256 linkNative + ); + function checkUpkeep( + uint256 id + ) + external + view + returns ( + bool upkeepNeeded, + bytes memory performData, + uint8 upkeepFailureReason, + uint256 gasUsed, + uint256 gasLimit, + uint256 fastGasWei, + uint256 linkNative + ); + function executeCallback( + uint256 id, + bytes memory payload + ) external returns (bool upkeepNeeded, bytes memory performData, uint8 upkeepFailureReason, uint256 gasUsed); + function migrateUpkeeps(uint256[] memory ids, address destination) external; + function receiveUpkeeps(bytes memory encodedUpkeeps) external; + function registerUpkeep( + address target, + uint32 gasLimit, + address admin, + uint8 triggerType, + bytes memory checkData, + bytes memory triggerConfig, + bytes memory offchainConfig + ) external returns (uint256 id); + function registerUpkeep( + address target, + uint32 gasLimit, + address admin, + bytes memory checkData, + bytes memory offchainConfig + ) external returns (uint256 id); + function setUpkeepTriggerConfig(uint256 id, bytes memory triggerConfig) external; + + function acceptPayeeship(address transmitter) external; + function acceptUpkeepAdmin(uint256 id) external; + function getActiveUpkeepIDs(uint256 startIndex, uint256 maxCount) external view returns (uint256[] memory); + function getAdminPrivilegeConfig(address admin) external view returns (bytes memory); + function getAllowedReadOnlyAddress() external view returns (address); + function getAutomationForwarderLogic() external view returns (address); + function getBalance(uint256 id) external view returns (uint96 balance); + function getCancellationDelay() external pure returns (uint256); + function getChainModule() external view returns (address chainModule); + function getConditionalGasOverhead() external pure returns (uint256); + function getFastGasFeedAddress() external view returns (address); + function getForwarder(uint256 upkeepID) external view returns (address); + function getLinkAddress() external view returns (address); + function getLinkNativeFeedAddress() external view returns (address); + function getLogGasOverhead() external pure returns (uint256); + function getMaxPaymentForGas(uint8 triggerType, uint32 gasLimit) external view returns (uint96 maxPayment); + function getMinBalance(uint256 id) external view returns (uint96); + function getMinBalanceForUpkeep(uint256 id) external view returns (uint96 minBalance); + function getPeerRegistryMigrationPermission(address peer) external view returns (uint8); + function getPerPerformByteGasOverhead() external pure returns (uint256); + function getPerSignerGasOverhead() external pure returns (uint256); + function getReorgProtectionEnabled() external view returns (bool reorgProtectionEnabled); + function getSignerInfo(address query) external view returns (bool active, uint8 index); + function getState() + external + view + returns ( + AutomationRegistryBase2_3.State memory state, + AutomationRegistryBase2_3.OnchainConfigLegacy memory config, + address[] memory signers, + address[] memory transmitters, + uint8 f + ); + function getTransmitCalldataFixedBytesOverhead() external pure returns (uint256); + function getTransmitCalldataPerSignerBytesOverhead() external pure returns (uint256); + function getTransmitterInfo( + address query + ) external view returns (bool active, uint8 index, uint96 balance, uint96 lastCollected, address payee); + function getTriggerType(uint256 upkeepId) external pure returns (uint8); + function getUpkeep(uint256 id) external view returns (AutomationRegistryBase2_3.UpkeepInfo memory upkeepInfo); + function getUpkeepPrivilegeConfig(uint256 upkeepId) external view returns (bytes memory); + function getUpkeepTriggerConfig(uint256 upkeepId) external view returns (bytes memory); + function hasDedupKey(bytes32 dedupKey) external view returns (bool); + function pause() external; + function pauseUpkeep(uint256 id) external; + function recoverFunds() external; + function setAdminPrivilegeConfig(address admin, bytes memory newPrivilegeConfig) external; + function setPayees(address[] memory payees) external; + function setPeerRegistryMigrationPermission(address peer, uint8 permission) external; + function setUpkeepCheckData(uint256 id, bytes memory newCheckData) external; + function setUpkeepGasLimit(uint256 id, uint32 gasLimit) external; + function setUpkeepOffchainConfig(uint256 id, bytes memory config) external; + function setUpkeepPrivilegeConfig(uint256 upkeepId, bytes memory newPrivilegeConfig) external; + function transferPayeeship(address transmitter, address proposed) external; + function transferUpkeepAdmin(uint256 id, address proposed) external; + function unpause() external; + function unpauseUpkeep(uint256 id) external; + function upkeepTranscoderVersion() external pure returns (uint8); + function upkeepVersion() external pure returns (uint8); + function withdrawFunds(uint256 id, address to) external; + function withdrawOwnerFunds() external; + function withdrawPayment(address from, address to) external; +} + +interface AutomationRegistryBase2_3 { + struct OnchainConfig { + uint32 paymentPremiumPPB; + uint32 flatFeeMicroLink; + uint32 checkGasLimit; + uint24 stalenessSeconds; + uint16 gasCeilingMultiplier; + uint96 minUpkeepSpend; + uint32 maxPerformGas; + uint32 maxCheckDataSize; + uint32 maxPerformDataSize; + uint32 maxRevertDataSize; + uint256 fallbackGasPrice; + uint256 fallbackLinkPrice; + address transcoder; + address[] registrars; + address upkeepPrivilegeManager; + address chainModule; + bool reorgProtectionEnabled; + } + + struct State { + uint32 nonce; + uint96 ownerLinkBalance; + uint256 expectedLinkBalance; + uint96 totalPremium; + uint256 numUpkeeps; + uint32 configCount; + uint32 latestConfigBlockNumber; + bytes32 latestConfigDigest; + uint32 latestEpoch; + bool paused; + } + + struct OnchainConfigLegacy { + uint32 paymentPremiumPPB; + uint32 flatFeeMicroLink; + uint32 checkGasLimit; + uint24 stalenessSeconds; + uint16 gasCeilingMultiplier; + uint96 minUpkeepSpend; + uint32 maxPerformGas; + uint32 maxCheckDataSize; + uint32 maxPerformDataSize; + uint32 maxRevertDataSize; + uint256 fallbackGasPrice; + uint256 fallbackLinkPrice; + address transcoder; + address[] registrars; + address upkeepPrivilegeManager; + } + + struct UpkeepInfo { + address target; + uint32 performGas; + bytes checkData; + uint96 balance; + address admin; + uint64 maxValidBlocknumber; + uint32 lastPerformedBlockNumber; + uint96 amountSpent; + bool paused; + bytes offchainConfig; + } +} + +// THIS FILE WAS AUTOGENERATED FROM THE FOLLOWING ABI JSON: +/* +[{"inputs":[{"internalType":"contract AutomationRegistryLogicB2_3","name":"logicA","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ArrayHasNoEntries","type":"error"},{"inputs":[],"name":"CannotCancel","type":"error"},{"inputs":[],"name":"CheckDataExceedsLimit","type":"error"},{"inputs":[],"name":"ConfigDigestMismatch","type":"error"},{"inputs":[],"name":"DuplicateEntry","type":"error"},{"inputs":[],"name":"DuplicateSigners","type":"error"},{"inputs":[],"name":"GasLimitCanOnlyIncrease","type":"error"},{"inputs":[],"name":"GasLimitOutsideRange","type":"error"},{"inputs":[],"name":"IncorrectNumberOfFaultyOracles","type":"error"},{"inputs":[],"name":"IncorrectNumberOfSignatures","type":"error"},{"inputs":[],"name":"IncorrectNumberOfSigners","type":"error"},{"inputs":[],"name":"IndexOutOfRange","type":"error"},{"inputs":[],"name":"InvalidDataLength","type":"error"},{"inputs":[],"name":"InvalidPayee","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidReport","type":"error"},{"inputs":[],"name":"InvalidSigner","type":"error"},{"inputs":[],"name":"InvalidTransmitter","type":"error"},{"inputs":[],"name":"InvalidTrigger","type":"error"},{"inputs":[],"name":"InvalidTriggerType","type":"error"},{"inputs":[],"name":"MaxCheckDataSizeCanOnlyIncrease","type":"error"},{"inputs":[],"name":"MaxPerformDataSizeCanOnlyIncrease","type":"error"},{"inputs":[],"name":"MigrationNotPermitted","type":"error"},{"inputs":[],"name":"NotAContract","type":"error"},{"inputs":[],"name":"OnlyActiveSigners","type":"error"},{"inputs":[],"name":"OnlyActiveTransmitters","type":"error"},{"inputs":[],"name":"OnlyCallableByAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByLINKToken","type":"error"},{"inputs":[],"name":"OnlyCallableByOwnerOrAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByOwnerOrRegistrar","type":"error"},{"inputs":[],"name":"OnlyCallableByPayee","type":"error"},{"inputs":[],"name":"OnlyCallableByProposedAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByProposedPayee","type":"error"},{"inputs":[],"name":"OnlyCallableByUpkeepPrivilegeManager","type":"error"},{"inputs":[],"name":"OnlyPausedUpkeep","type":"error"},{"inputs":[],"name":"OnlySimulatedBackend","type":"error"},{"inputs":[],"name":"OnlyUnpausedUpkeep","type":"error"},{"inputs":[],"name":"ParameterLengthError","type":"error"},{"inputs":[],"name":"PaymentGreaterThanAllLINK","type":"error"},{"inputs":[],"name":"ReentrantCall","type":"error"},{"inputs":[],"name":"RegistryPaused","type":"error"},{"inputs":[],"name":"RepeatedSigner","type":"error"},{"inputs":[],"name":"RepeatedTransmitter","type":"error"},{"inputs":[{"internalType":"bytes","name":"reason","type":"bytes"}],"name":"TargetCheckReverted","type":"error"},{"inputs":[],"name":"TooManyOracles","type":"error"},{"inputs":[],"name":"TranscoderNotSet","type":"error"},{"inputs":[],"name":"UpkeepAlreadyExists","type":"error"},{"inputs":[],"name":"UpkeepCancelled","type":"error"},{"inputs":[],"name":"UpkeepNotCanceled","type":"error"},{"inputs":[],"name":"UpkeepNotNeeded","type":"error"},{"inputs":[],"name":"ValueNotChanged","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"bytes","name":"privilegeConfig","type":"bytes"}],"name":"AdminPrivilegeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"CancelledUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newModule","type":"address"}],"name":"ChainSpecificModuleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"previousConfigBlockNumber","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"configCount","type":"uint64"},{"indexed":false,"internalType":"address[]","name":"signers","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"uint8","name":"f","type":"uint8"},{"indexed":false,"internalType":"bytes","name":"onchainConfig","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"ConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"DedupKeyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint96","name":"amount","type":"uint96"}],"name":"FundsAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"FundsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"InsufficientFundsUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint96","name":"amount","type":"uint96"}],"name":"OwnerFundsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"payees","type":"address[]"}],"name":"PayeesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"payee","type":"address"}],"name":"PaymentWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"ReorgedUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"StaleUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"epoch","type":"uint32"}],"name":"Transmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"UpkeepAdminTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"UpkeepAdminTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"uint64","name":"atBlockHeight","type":"uint64"}],"name":"UpkeepCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"newCheckData","type":"bytes"}],"name":"UpkeepCheckDataSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint96","name":"gasLimit","type":"uint96"}],"name":"UpkeepGasLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"remainingBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"destination","type":"address"}],"name":"UpkeepMigrated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"UpkeepOffchainConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"UpkeepPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"bool","name":"success","type":"bool"},{"indexed":false,"internalType":"uint96","name":"totalPayment","type":"uint96"},{"indexed":false,"internalType":"uint256","name":"gasUsed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasOverhead","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"UpkeepPerformed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"privilegeConfig","type":"bytes"}],"name":"UpkeepPrivilegeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startingBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"importedFrom","type":"address"}],"name":"UpkeepReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"performGas","type":"uint32"},{"indexed":false,"internalType":"address","name":"admin","type":"address"}],"name":"UpkeepRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"UpkeepTriggerConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"UpkeepUnpaused","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fallbackTo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDetails","outputs":[{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"blockNumber","type":"uint32"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDigestAndEpoch","outputs":[{"internalType":"bool","name":"scanLogs","type":"bool"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"internalType":"uint32","name":"epoch","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onTokenTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"internalType":"bytes","name":"onchainConfigBytes","type":"bytes"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"components":[{"internalType":"uint32","name":"paymentPremiumPPB","type":"uint32"},{"internalType":"uint32","name":"flatFeeMicroLink","type":"uint32"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint96","name":"minUpkeepSpend","type":"uint96"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"},{"internalType":"contract IChainModule","name":"chainModule","type":"address"},{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"}],"internalType":"struct AutomationRegistryBase2_3.OnchainConfig","name":"onchainConfig","type":"tuple"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"setConfigTypeSafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"performData","type":"bytes"}],"name":"simulatePerformUpkeep","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[3]","name":"reportContext","type":"bytes32[3]"},{"internalType":"bytes","name":"rawReport","type":"bytes"},{"internalType":"bytes32[]","name":"rs","type":"bytes32[]"},{"internalType":"bytes32[]","name":"ss","type":"bytes32[]"},{"internalType":"bytes32","name":"rawVs","type":"bytes32"}],"name":"transmit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"typeAndVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract AutomationRegistryLogicB2_3","name":"logicB","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint96","name":"amount","type":"uint96"}],"name":"addFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"cancelUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes[]","name":"values","type":"bytes[]"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"checkCallback","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"triggerData","type":"bytes"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"fastGasWei","type":"uint256"},{"internalType":"uint256","name":"linkNative","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"fastGasWei","type":"uint256"},{"internalType":"uint256","name":"linkNative","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"executeCallback","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"address","name":"destination","type":"address"}],"name":"migrateUpkeeps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedUpkeeps","type":"bytes"}],"name":"receiveUpkeeps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"enum AutomationRegistryBase2_3.Trigger","name":"triggerType","type":"uint8"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"registerUpkeep","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"registerUpkeep","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"setUpkeepTriggerConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"link","type":"address"},{"internalType":"address","name":"linkNativeFeed","type":"address"},{"internalType":"address","name":"fastGasFeed","type":"address"},{"internalType":"address","name":"automationForwarderLogic","type":"address"},{"internalType":"address","name":"allowedReadOnlyAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"transmitter","type":"address"}],"name":"acceptPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"acceptUpkeepAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"maxCount","type":"uint256"}],"name":"getActiveUpkeepIDs","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"getAdminPrivilegeConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllowedReadOnlyAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAutomationForwarderLogic","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getBalance","outputs":[{"internalType":"uint96","name":"balance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCancellationDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getChainModule","outputs":[{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConditionalGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getFastGasFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepID","type":"uint256"}],"name":"getForwarder","outputs":[{"internalType":"contract IAutomationForwarder","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkNativeFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLogGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"enum AutomationRegistryBase2_3.Trigger","name":"triggerType","type":"uint8"},{"internalType":"uint32","name":"gasLimit","type":"uint32"}],"name":"getMaxPaymentForGas","outputs":[{"internalType":"uint96","name":"maxPayment","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalance","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalanceForUpkeep","outputs":[{"internalType":"uint96","name":"minBalance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"}],"name":"getPeerRegistryMigrationPermission","outputs":[{"internalType":"enum AutomationRegistryBase2_3.MigrationPermission","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPerPerformByteGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getPerSignerGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getReorgProtectionEnabled","outputs":[{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getSignerInfo","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getState","outputs":[{"components":[{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint96","name":"ownerLinkBalance","type":"uint96"},{"internalType":"uint256","name":"expectedLinkBalance","type":"uint256"},{"internalType":"uint96","name":"totalPremium","type":"uint96"},{"internalType":"uint256","name":"numUpkeeps","type":"uint256"},{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"latestConfigBlockNumber","type":"uint32"},{"internalType":"bytes32","name":"latestConfigDigest","type":"bytes32"},{"internalType":"uint32","name":"latestEpoch","type":"uint32"},{"internalType":"bool","name":"paused","type":"bool"}],"internalType":"struct AutomationRegistryBase2_3.State","name":"state","type":"tuple"},{"components":[{"internalType":"uint32","name":"paymentPremiumPPB","type":"uint32"},{"internalType":"uint32","name":"flatFeeMicroLink","type":"uint32"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint96","name":"minUpkeepSpend","type":"uint96"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"}],"internalType":"struct AutomationRegistryBase2_3.OnchainConfigLegacy","name":"config","type":"tuple"},{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTransmitCalldataFixedBytesOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getTransmitCalldataPerSignerBytesOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getTransmitterInfo","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"uint96","name":"lastCollected","type":"uint96"},{"internalType":"address","name":"payee","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getTriggerType","outputs":[{"internalType":"enum AutomationRegistryBase2_3.Trigger","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getUpkeep","outputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"performGas","type":"uint32"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"uint64","name":"maxValidBlocknumber","type":"uint64"},{"internalType":"uint32","name":"lastPerformedBlockNumber","type":"uint32"},{"internalType":"uint96","name":"amountSpent","type":"uint96"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"internalType":"struct AutomationRegistryBase2_3.UpkeepInfo","name":"upkeepInfo","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getUpkeepPrivilegeConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getUpkeepTriggerConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"hasDedupKey","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"pauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"recoverFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"bytes","name":"newPrivilegeConfig","type":"bytes"}],"name":"setAdminPrivilegeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"payees","type":"address[]"}],"name":"setPayees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"},{"internalType":"enum AutomationRegistryBase2_3.MigrationPermission","name":"permission","type":"uint8"}],"name":"setPeerRegistryMigrationPermission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"newCheckData","type":"bytes"}],"name":"setUpkeepCheckData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint32","name":"gasLimit","type":"uint32"}],"name":"setUpkeepGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"config","type":"bytes"}],"name":"setUpkeepOffchainConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"},{"internalType":"bytes","name":"newPrivilegeConfig","type":"bytes"}],"name":"setUpkeepPrivilegeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"transmitter","type":"address"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferUpkeepAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"unpauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"upkeepTranscoderVersion","outputs":[{"internalType":"enum UpkeepFormat","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"upkeepVersion","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawOwnerFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawPayment","outputs":[],"stateMutability":"nonpayable","type":"function"}] +*/ diff --git a/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol b/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol new file mode 100644 index 00000000000..89bea70af86 --- /dev/null +++ b/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol @@ -0,0 +1,198 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +import {AutomationForwarderLogic} from "../../AutomationForwarderLogic.sol"; +import {BaseTest} from "./BaseTest.t.sol"; +import {AutomationRegistry2_3} from "../v2_3/AutomationRegistry2_3.sol"; +import {AutomationRegistryBase2_3} from "../v2_3/AutomationRegistryBase2_3.sol"; +import {AutomationRegistryLogicA2_3} from "../v2_3/AutomationRegistryLogicA2_3.sol"; +import {AutomationRegistryLogicB2_3} from "../v2_3/AutomationRegistryLogicB2_3.sol"; +import {IAutomationRegistryMaster} from "../interfaces/v2_3/IAutomationRegistryMaster2_3.sol"; +import {ChainModuleBase} from "../chains/ChainModuleBase.sol"; + +contract AutomationRegistry2_3_SetUp is BaseTest { + address internal constant LINK_ETH_FEED = 0x1111111111111111111111111111111111111110; + address internal constant FAST_GAS_FEED = 0x1111111111111111111111111111111111111112; + address internal constant LINK_TOKEN = 0x1111111111111111111111111111111111111113; + address internal constant ZERO_ADDRESS = address(0); + + // Signer private keys used for these test + uint256 internal constant PRIVATE0 = 0x7b2e97fe057e6de99d6872a2ef2abf52c9b4469bc848c2465ac3fcd8d336e81d; + uint256 internal constant PRIVATE1 = 0xab56160806b05ef1796789248e1d7f34a6465c5280899159d645218cd216cee6; + uint256 internal constant PRIVATE2 = 0x6ec7caa8406a49b76736602810e0a2871959fbbb675e23a8590839e4717f1f7f; + uint256 internal constant PRIVATE3 = 0x80f14b11da94ae7f29d9a7713ea13dc838e31960a5c0f2baf45ed458947b730a; + + uint64 internal constant OFFCHAIN_CONFIG_VERSION = 30; // 2 for OCR2 + uint8 internal constant F = 1; + + address[] internal s_valid_signers; + address[] internal s_valid_transmitters; + address[] internal s_registrars; + + IAutomationRegistryMaster internal registryMaster; + + function setUp() public override { + s_valid_transmitters = new address[](4); + for (uint160 i = 0; i < 4; ++i) { + s_valid_transmitters[i] = address(4 + i); + } + + s_valid_signers = new address[](4); + s_valid_signers[0] = vm.addr(PRIVATE0); //0xc110458BE52CaA6bB68E66969C3218A4D9Db0211 + s_valid_signers[1] = vm.addr(PRIVATE1); //0xc110a19c08f1da7F5FfB281dc93630923F8E3719 + s_valid_signers[2] = vm.addr(PRIVATE2); //0xc110fdF6e8fD679C7Cc11602d1cd829211A18e9b + s_valid_signers[3] = vm.addr(PRIVATE3); //0xc11028017c9b445B6bF8aE7da951B5cC28B326C0 + + s_registrars = new address[](1); + s_registrars[0] = 0x3a0eDE26aa188BFE00b9A0C9A431A1a0CA5f7966; + + AutomationForwarderLogic forwarderLogic = new AutomationForwarderLogic(); + AutomationRegistryLogicB2_3 logicB2_3 = new AutomationRegistryLogicB2_3( + LINK_TOKEN, + LINK_ETH_FEED, + FAST_GAS_FEED, + address(forwarderLogic), + ZERO_ADDRESS + ); + AutomationRegistryLogicA2_3 logicA2_3 = new AutomationRegistryLogicA2_3(logicB2_3); + registryMaster = IAutomationRegistryMaster( + address(new AutomationRegistry2_3(AutomationRegistryLogicB2_3(address(logicA2_3)))) + ); + } +} + +contract AutomationRegistry2_3_LatestConfigDetails is AutomationRegistry2_3_SetUp { + function testGet() public { + (uint32 configCount, uint32 blockNumber, bytes32 configDigest) = registryMaster.latestConfigDetails(); + assertEq(configCount, 0); + assertEq(blockNumber, 0); + assertEq(configDigest, ""); + } +} + +contract AutomationRegistry2_3_CheckUpkeep is AutomationRegistry2_3_SetUp { + function testPreventExecutionOnCheckUpkeep() public { + uint256 id = 1; + bytes memory triggerData = abi.encodePacked("trigger_data"); + + // The tx.origin is the DEFAULT_SENDER (0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38) of foundry + // Expecting a revert since the tx.origin is not address(0) + vm.expectRevert(abi.encodeWithSelector(IAutomationRegistryMaster.OnlySimulatedBackend.selector)); + registryMaster.checkUpkeep(id, triggerData); + } +} + +contract AutomationRegistry2_3_SetConfig is AutomationRegistry2_3_SetUp { + event ConfigSet( + uint32 previousConfigBlockNumber, + bytes32 configDigest, + uint64 configCount, + address[] signers, + address[] transmitters, + uint8 f, + bytes onchainConfig, + uint64 offchainConfigVersion, + bytes offchainConfig + ); + + function testSetConfigSuccess() public { + (uint32 configCount, , ) = registryMaster.latestConfigDetails(); + assertEq(configCount, 0); + ChainModuleBase module = new ChainModuleBase(); + + AutomationRegistryBase2_3.OnchainConfig memory cfg = AutomationRegistryBase2_3.OnchainConfig({ + paymentPremiumPPB: 10_000, + flatFeeMicroLink: 40_000, + checkGasLimit: 5_000_000, + stalenessSeconds: 90_000, + gasCeilingMultiplier: 0, + minUpkeepSpend: 0, + maxPerformGas: 10_000_000, + maxCheckDataSize: 5_000, + maxPerformDataSize: 5_000, + maxRevertDataSize: 5_000, + fallbackGasPrice: 20_000_000_000, + fallbackLinkPrice: 200_000_000_000, + transcoder: 0xB1e66855FD67f6e85F0f0fA38cd6fBABdf00923c, + registrars: s_registrars, + upkeepPrivilegeManager: 0xD9c855F08A7e460691F41bBDDe6eC310bc0593D8, + chainModule: module, + reorgProtectionEnabled: true + }); + bytes memory onchainConfigBytes = abi.encode(cfg); + + uint256 a = 1234; + address b = address(0); + bytes memory offchainConfigBytes = abi.encode(a, b); + bytes32 configDigest = _configDigestFromConfigData( + block.chainid, + address(registryMaster), + ++configCount, + s_valid_signers, + s_valid_transmitters, + F, + onchainConfigBytes, + OFFCHAIN_CONFIG_VERSION, + offchainConfigBytes + ); + + vm.expectEmit(); + emit ConfigSet( + 0, + configDigest, + configCount, + s_valid_signers, + s_valid_transmitters, + F, + onchainConfigBytes, + OFFCHAIN_CONFIG_VERSION, + offchainConfigBytes + ); + + registryMaster.setConfig( + s_valid_signers, + s_valid_transmitters, + F, + onchainConfigBytes, + OFFCHAIN_CONFIG_VERSION, + offchainConfigBytes + ); + + (, , address[] memory signers, address[] memory transmitters, uint8 f) = registryMaster.getState(); + + assertEq(signers, s_valid_signers); + assertEq(transmitters, s_valid_transmitters); + assertEq(f, F); + } + + function _configDigestFromConfigData( + uint256 chainId, + address contractAddress, + uint64 configCount, + address[] memory signers, + address[] memory transmitters, + uint8 f, + bytes memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) internal pure returns (bytes32) { + uint256 h = uint256( + keccak256( + abi.encode( + chainId, + contractAddress, + configCount, + signers, + transmitters, + f, + onchainConfig, + offchainConfigVersion, + offchainConfig + ) + ) + ); + uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00 + uint256 prefix = 0x0001 << (256 - 16); // 0x000100..00 + return bytes32((prefix & prefixMask) | (h & ~prefixMask)); + } +} diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryBase2_2.sol b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryBase2_2.sol index a198daef4f1..d415e0e3e1f 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryBase2_2.sol +++ b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryBase2_2.sol @@ -11,7 +11,7 @@ import {AggregatorV3Interface} from "../../../shared/interfaces/AggregatorV3Inte import {LinkTokenInterface} from "../../../shared/interfaces/LinkTokenInterface.sol"; import {KeeperCompatibleInterface} from "../../interfaces/KeeperCompatibleInterface.sol"; import {UpkeepFormat} from "../../interfaces/UpkeepTranscoderInterface.sol"; -import {IChainModule} from "../interfaces/v2_2/IChainModule.sol"; +import {IChainModule} from "../interfaces/IChainModule.sol"; /** * @notice Base Keeper Registry contract, contains shared logic between diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicB2_2.sol b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicB2_2.sol index b18f6b66b2f..6ce56577819 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicB2_2.sol +++ b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicB2_2.sol @@ -6,7 +6,7 @@ import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contra import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; import {UpkeepFormat} from "../../interfaces/UpkeepTranscoderInterface.sol"; import {IAutomationForwarder} from "../../interfaces/IAutomationForwarder.sol"; -import {IChainModule} from "../interfaces/v2_2/IChainModule.sol"; +import {IChainModule} from "../interfaces/IChainModule.sol"; contract AutomationRegistryLogicB2_2 is AutomationRegistryBase2_2 { using Address for address; diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistrar2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistrar2_3.sol new file mode 100644 index 00000000000..e1f53fe07e9 --- /dev/null +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistrar2_3.sol @@ -0,0 +1,537 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +import {LinkTokenInterface} from "../../../shared/interfaces/LinkTokenInterface.sol"; +import {IAutomationRegistryMaster} from "../interfaces/v2_3/IAutomationRegistryMaster2_3.sol"; +import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol"; +import {ConfirmedOwner} from "../../../shared/access/ConfirmedOwner.sol"; +import {IERC677Receiver} from "../../../shared/interfaces/IERC677Receiver.sol"; + +/** + * @notice Contract to accept requests for upkeep registrations + * @dev There are 2 registration workflows in this contract + * Flow 1. auto approve OFF / manual registration - UI calls `register` function on this contract, this contract owner at a later time then manually + * calls `approve` to register upkeep and emit events to inform UI and others interested. + * Flow 2. auto approve ON / real time registration - UI calls `register` function as before, which calls the `registerUpkeep` function directly on + * keeper registry and then emits approved event to finish the flow automatically without manual intervention. + * The idea is to have same interface(functions,events) for UI or anyone using this contract irrespective of auto approve being enabled or not. + * they can just listen to `RegistrationRequested` & `RegistrationApproved` events and know the status on registrations. + */ +contract AutomationRegistrar2_3 is TypeAndVersionInterface, ConfirmedOwner, IERC677Receiver { + /** + * DISABLED: No auto approvals, all new upkeeps should be approved manually. + * ENABLED_SENDER_ALLOWLIST: Auto approvals for allowed senders subject to max allowed. Manual for rest. + * ENABLED_ALL: Auto approvals for all new upkeeps subject to max allowed. + */ + enum AutoApproveType { + DISABLED, + ENABLED_SENDER_ALLOWLIST, + ENABLED_ALL + } + + bytes4 private constant REGISTER_REQUEST_SELECTOR = this.register.selector; + + mapping(bytes32 => PendingRequest) private s_pendingRequests; + mapping(uint8 => TriggerRegistrationStorage) private s_triggerRegistrations; + + LinkTokenInterface public immutable LINK; + + /** + * @notice versions: + * - KeeperRegistrar 2.3.0: Update for compatability with registry 2.3.0 + * Add native billing and ERC20 billing support + * - KeeperRegistrar 2.1.0: Update for compatability with registry 2.1.0 + * Add auto approval levels by type + * - KeeperRegistrar 2.0.0: Remove source from register + * Breaks our example of "Register an Upkeep using your own deployed contract" + * - KeeperRegistrar 1.1.0: Add functionality for sender allowlist in auto approve + * : Remove rate limit and add max allowed for auto approve + * - KeeperRegistrar 1.0.0: initial release + */ + string public constant override typeAndVersion = "AutomationRegistrar 2.3.0"; + + /** + * @notice TriggerRegistrationStorage stores the auto-approval levels for upkeeps by type + * @member autoApproveType the auto approval setting (see enum) + * @member autoApproveMaxAllowed the max number of upkeeps that can be auto approved of this type + * @member approvedCount the count of upkeeps auto approved of this type + */ + struct TriggerRegistrationStorage { + AutoApproveType autoApproveType; + uint32 autoApproveMaxAllowed; + uint32 approvedCount; + } + + /** + * @notice InitialTriggerConfig configures the auto-approval levels for upkeeps by trigger type + * @dev this struct is only used in the constructor to set the initial values for various trigger configs + * @member triggerType the upkeep type to configure + * @member autoApproveType the auto approval setting (see enum) + * @member autoApproveMaxAllowed the max number of upkeeps that can be auto approved of this type + */ + struct InitialTriggerConfig { + uint8 triggerType; + AutoApproveType autoApproveType; + uint32 autoApproveMaxAllowed; + } + + struct RegistrarConfig { + IAutomationRegistryMaster AutomationRegistry; + uint96 minLINKJuels; + } + + struct PendingRequest { + address admin; + uint96 balance; + } + + struct RegistrationParams { + string name; + bytes encryptedEmail; + address upkeepContract; + uint32 gasLimit; + address adminAddress; + uint8 triggerType; + bytes checkData; + bytes triggerConfig; + bytes offchainConfig; + uint96 amount; + } + + RegistrarConfig private s_config; + // Only applicable if s_config.configType is ENABLED_SENDER_ALLOWLIST + mapping(address => bool) private s_autoApproveAllowedSenders; + + event RegistrationRequested( + bytes32 indexed hash, + string name, + bytes encryptedEmail, + address indexed upkeepContract, + uint32 gasLimit, + address adminAddress, + uint8 triggerType, + bytes triggerConfig, + bytes offchainConfig, + bytes checkData, + uint96 amount + ); + + event RegistrationApproved(bytes32 indexed hash, string displayName, uint256 indexed upkeepId); + + event RegistrationRejected(bytes32 indexed hash); + + event AutoApproveAllowedSenderSet(address indexed senderAddress, bool allowed); + + event ConfigChanged(address AutomationRegistry, uint96 minLINKJuels); + + event TriggerConfigSet(uint8 triggerType, AutoApproveType autoApproveType, uint32 autoApproveMaxAllowed); + + error InvalidAdminAddress(); + error RequestNotFound(); + error HashMismatch(); + error OnlyAdminOrOwner(); + error InsufficientPayment(); + error RegistrationRequestFailed(); + error OnlyLink(); + error AmountMismatch(); + error SenderMismatch(); + error FunctionNotPermitted(); + error LinkTransferFailed(address to); + error InvalidDataLength(); + + /** + * @param LINKAddress Address of Link token + * @param AutomationRegistry keeper registry address + * @param minLINKJuels minimum LINK that new registrations should fund their upkeep with + * @param triggerConfigs the initial config for individual triggers + */ + constructor( + address LINKAddress, + address AutomationRegistry, + uint96 minLINKJuels, + InitialTriggerConfig[] memory triggerConfigs + ) ConfirmedOwner(msg.sender) { + LINK = LinkTokenInterface(LINKAddress); + setConfig(AutomationRegistry, minLINKJuels); + for (uint256 idx = 0; idx < triggerConfigs.length; idx++) { + setTriggerConfig( + triggerConfigs[idx].triggerType, + triggerConfigs[idx].autoApproveType, + triggerConfigs[idx].autoApproveMaxAllowed + ); + } + } + + //EXTERNAL + + /** + * @notice register can only be called through transferAndCall on LINK contract + * @param name string of the upkeep to be registered + * @param encryptedEmail email address of upkeep contact + * @param upkeepContract address to perform upkeep on + * @param gasLimit amount of gas to provide the target contract when performing upkeep + * @param adminAddress address to cancel upkeep and withdraw remaining funds + * @param triggerType the type of trigger for the upkeep + * @param checkData data passed to the contract when checking for upkeep + * @param triggerConfig the config for the trigger + * @param offchainConfig offchainConfig for upkeep in bytes + * @param amount quantity of LINK upkeep is funded with (specified in Juels) + * @param sender address of the sender making the request + */ + function register( + string memory name, + bytes calldata encryptedEmail, + address upkeepContract, + uint32 gasLimit, + address adminAddress, + uint8 triggerType, + bytes memory checkData, + bytes memory triggerConfig, + bytes memory offchainConfig, + uint96 amount, + address sender + ) external onlyLINK { + _register( + RegistrationParams({ + name: name, + encryptedEmail: encryptedEmail, + upkeepContract: upkeepContract, + gasLimit: gasLimit, + adminAddress: adminAddress, + triggerType: triggerType, + checkData: checkData, + triggerConfig: triggerConfig, + offchainConfig: offchainConfig, + amount: amount + }), + sender + ); + } + + /** + * @notice Allows external users to register upkeeps; assumes amount is approved for transfer by the contract + * @param requestParams struct of all possible registration parameters + */ + function registerUpkeep(RegistrationParams calldata requestParams) external returns (uint256) { + if (requestParams.amount < s_config.minLINKJuels) { + revert InsufficientPayment(); + } + + LINK.transferFrom(msg.sender, address(this), requestParams.amount); + + return _register(requestParams, msg.sender); + } + + /** + * @dev register upkeep on AutomationRegistry contract and emit RegistrationApproved event + */ + function approve( + string memory name, + address upkeepContract, + uint32 gasLimit, + address adminAddress, + uint8 triggerType, + bytes calldata checkData, + bytes memory triggerConfig, + bytes calldata offchainConfig, + bytes32 hash + ) external onlyOwner { + PendingRequest memory request = s_pendingRequests[hash]; + if (request.admin == address(0)) { + revert RequestNotFound(); + } + bytes32 expectedHash = keccak256( + abi.encode(upkeepContract, gasLimit, adminAddress, triggerType, checkData, triggerConfig, offchainConfig) + ); + if (hash != expectedHash) { + revert HashMismatch(); + } + delete s_pendingRequests[hash]; + _approve( + RegistrationParams({ + name: name, + encryptedEmail: "", + upkeepContract: upkeepContract, + gasLimit: gasLimit, + adminAddress: adminAddress, + triggerType: triggerType, + checkData: checkData, + triggerConfig: triggerConfig, + offchainConfig: offchainConfig, + amount: request.balance + }), + expectedHash + ); + } + + /** + * @notice cancel will remove a registration request and return the refunds to the request.admin + * @param hash the request hash + */ + function cancel(bytes32 hash) external { + PendingRequest memory request = s_pendingRequests[hash]; + if (!(msg.sender == request.admin || msg.sender == owner())) { + revert OnlyAdminOrOwner(); + } + if (request.admin == address(0)) { + revert RequestNotFound(); + } + delete s_pendingRequests[hash]; + bool success = LINK.transfer(request.admin, request.balance); + if (!success) { + revert LinkTransferFailed(request.admin); + } + emit RegistrationRejected(hash); + } + + /** + * @notice owner calls this function to set contract config + * @param AutomationRegistry new keeper registry address + * @param minLINKJuels minimum LINK that new registrations should fund their upkeep with + */ + function setConfig(address AutomationRegistry, uint96 minLINKJuels) public onlyOwner { + s_config = RegistrarConfig({ + minLINKJuels: minLINKJuels, + AutomationRegistry: IAutomationRegistryMaster(AutomationRegistry) + }); + emit ConfigChanged(AutomationRegistry, minLINKJuels); + } + + /** + * @notice owner calls to set the config for this upkeep type + * @param triggerType the upkeep type to configure + * @param autoApproveType the auto approval setting (see enum) + * @param autoApproveMaxAllowed the max number of upkeeps that can be auto approved of this type + */ + function setTriggerConfig( + uint8 triggerType, + AutoApproveType autoApproveType, + uint32 autoApproveMaxAllowed + ) public onlyOwner { + s_triggerRegistrations[triggerType].autoApproveType = autoApproveType; + s_triggerRegistrations[triggerType].autoApproveMaxAllowed = autoApproveMaxAllowed; + emit TriggerConfigSet(triggerType, autoApproveType, autoApproveMaxAllowed); + } + + /** + * @notice owner calls this function to set allowlist status for senderAddress + * @param senderAddress senderAddress to set the allowlist status for + * @param allowed true if senderAddress needs to be added to allowlist, false if needs to be removed + */ + function setAutoApproveAllowedSender(address senderAddress, bool allowed) external onlyOwner { + s_autoApproveAllowedSenders[senderAddress] = allowed; + + emit AutoApproveAllowedSenderSet(senderAddress, allowed); + } + + /** + * @notice read the allowlist status of senderAddress + * @param senderAddress address to read the allowlist status for + */ + function getAutoApproveAllowedSender(address senderAddress) external view returns (bool) { + return s_autoApproveAllowedSenders[senderAddress]; + } + + /** + * @notice read the current registration configuration + */ + function getConfig() external view returns (address AutomationRegistry, uint256 minLINKJuels) { + RegistrarConfig memory config = s_config; + return (address(config.AutomationRegistry), config.minLINKJuels); + } + + /** + * @notice read the config for this upkeep type + * @param triggerType upkeep type to read config for + */ + function getTriggerRegistrationDetails(uint8 triggerType) external view returns (TriggerRegistrationStorage memory) { + return s_triggerRegistrations[triggerType]; + } + + /** + * @notice gets the admin address and the current balance of a registration request + */ + function getPendingRequest(bytes32 hash) external view returns (address, uint96) { + PendingRequest memory request = s_pendingRequests[hash]; + return (request.admin, request.balance); + } + + /** + * @notice Called when LINK is sent to the contract via `transferAndCall` + * @param sender Address of the sender transfering LINK + * @param amount Amount of LINK sent (specified in Juels) + * @param data Payload of the transaction + */ + function onTokenTransfer( + address sender, + uint256 amount, + bytes calldata data + ) + external + override + onlyLINK + permittedFunctionsForLINK(data) + isActualAmount(amount, data) + isActualSender(sender, data) + { + if (amount < s_config.minLINKJuels) { + revert InsufficientPayment(); + } + (bool success, ) = address(this).delegatecall(data); + // calls register + if (!success) { + revert RegistrationRequestFailed(); + } + } + + // ================================================================ + // | PRIVATE | + // ================================================================ + + /** + * @dev verify registration request and emit RegistrationRequested event + */ + function _register(RegistrationParams memory params, address sender) private returns (uint256) { + if (params.adminAddress == address(0)) { + revert InvalidAdminAddress(); + } + bytes32 hash = keccak256( + abi.encode( + params.upkeepContract, + params.gasLimit, + params.adminAddress, + params.triggerType, + params.checkData, + params.triggerConfig, + params.offchainConfig + ) + ); + + emit RegistrationRequested( + hash, + params.name, + params.encryptedEmail, + params.upkeepContract, + params.gasLimit, + params.adminAddress, + params.triggerType, + params.triggerConfig, + params.offchainConfig, + params.checkData, + params.amount + ); + + uint256 upkeepId; + if (_shouldAutoApprove(s_triggerRegistrations[params.triggerType], sender)) { + s_triggerRegistrations[params.triggerType].approvedCount++; + upkeepId = _approve(params, hash); + } else { + uint96 newBalance = s_pendingRequests[hash].balance + params.amount; + s_pendingRequests[hash] = PendingRequest({admin: params.adminAddress, balance: newBalance}); + } + + return upkeepId; + } + + /** + * @dev register upkeep on AutomationRegistry contract and emit RegistrationApproved event + */ + function _approve(RegistrationParams memory params, bytes32 hash) private returns (uint256) { + IAutomationRegistryMaster AutomationRegistry = s_config.AutomationRegistry; + uint256 upkeepId = AutomationRegistry.registerUpkeep( + params.upkeepContract, + params.gasLimit, + params.adminAddress, + params.triggerType, + params.checkData, + params.triggerConfig, + params.offchainConfig + ); + bool success = LINK.transferAndCall(address(AutomationRegistry), params.amount, abi.encode(upkeepId)); + if (!success) { + revert LinkTransferFailed(address(AutomationRegistry)); + } + emit RegistrationApproved(hash, params.name, upkeepId); + return upkeepId; + } + + /** + * @dev verify sender allowlist if needed and check max limit + */ + function _shouldAutoApprove(TriggerRegistrationStorage memory config, address sender) private view returns (bool) { + if (config.autoApproveType == AutoApproveType.DISABLED) { + return false; + } + if (config.autoApproveType == AutoApproveType.ENABLED_SENDER_ALLOWLIST && (!s_autoApproveAllowedSenders[sender])) { + return false; + } + if (config.approvedCount < config.autoApproveMaxAllowed) { + return true; + } + return false; + } + + // ================================================================ + // | MODIFIERS | + // ================================================================ + + /** + * @dev Reverts if not sent from the LINK token + */ + modifier onlyLINK() { + if (msg.sender != address(LINK)) { + revert OnlyLink(); + } + _; + } + + /** + * @dev Reverts if the given data does not begin with the `register` function selector + * @param _data The data payload of the request + */ + modifier permittedFunctionsForLINK(bytes memory _data) { + bytes4 funcSelector; + assembly { + // solhint-disable-next-line avoid-low-level-calls + funcSelector := mload(add(_data, 32)) // First 32 bytes contain length of data + } + if (funcSelector != REGISTER_REQUEST_SELECTOR) { + revert FunctionNotPermitted(); + } + _; + } + + /** + * @dev Reverts if the actual amount passed does not match the expected amount + * @param expected amount that should match the actual amount + * @param data bytes + */ + modifier isActualAmount(uint256 expected, bytes calldata data) { + // decode register function arguments to get actual amount + (, , , , , , , , , uint96 amount, ) = abi.decode( + data[4:], + (string, bytes, address, uint32, address, uint8, bytes, bytes, bytes, uint96, address) + ); + if (expected != amount) { + revert AmountMismatch(); + } + _; + } + + /** + * @dev Reverts if the actual sender address does not match the expected sender address + * @param expected address that should match the actual sender address + * @param data bytes + */ + modifier isActualSender(address expected, bytes calldata data) { + // decode register function arguments to get actual sender + (, , , , , , , , , , address sender) = abi.decode( + data[4:], + (string, bytes, address, uint32, address, uint8, bytes, bytes, bytes, uint96, address) + ); + if (expected != sender) { + revert SenderMismatch(); + } + _; + } +} diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistry2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistry2_3.sol new file mode 100644 index 00000000000..925ef21a48b --- /dev/null +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistry2_3.sol @@ -0,0 +1,416 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; +import {AutomationRegistryBase2_3} from "./AutomationRegistryBase2_3.sol"; +import {AutomationRegistryLogicB2_3} from "./AutomationRegistryLogicB2_3.sol"; +import {Chainable} from "../../Chainable.sol"; +import {IERC677Receiver} from "../../../shared/interfaces/IERC677Receiver.sol"; +import {OCR2Abstract} from "../../../shared/ocr2/OCR2Abstract.sol"; + +/** + * @notice Registry for adding work for Chainlink nodes to perform on client + * contracts. Clients must support the AutomationCompatibleInterface interface. + */ +contract AutomationRegistry2_3 is AutomationRegistryBase2_3, OCR2Abstract, Chainable, IERC677Receiver { + using Address for address; + using EnumerableSet for EnumerableSet.UintSet; + using EnumerableSet for EnumerableSet.AddressSet; + + /** + * @notice versions: + * AutomationRegistry 2.3.0: supports native and ERC20 billing + * AutomationRegistry 2.2.0: moves chain-specific integration code into a separate module + * KeeperRegistry 2.1.0: introduces support for log triggers + * removes the need for "wrapped perform data" + * KeeperRegistry 2.0.2: pass revert bytes as performData when target contract reverts + * fixes issue with arbitrum block number + * does an early return in case of stale report instead of revert + * KeeperRegistry 2.0.1: implements workaround for buggy migrate function in 1.X + * KeeperRegistry 2.0.0: implement OCR interface + * KeeperRegistry 1.3.0: split contract into Proxy and Logic + * account for Arbitrum and Optimism L1 gas fee + * allow users to configure upkeeps + * KeeperRegistry 1.2.0: allow funding within performUpkeep + * allow configurable registry maxPerformGas + * add function to let admin change upkeep gas limit + * add minUpkeepSpend requirement + * upgrade to solidity v0.8 + * KeeperRegistry 1.1.0: added flatFeeMicroLink + * KeeperRegistry 1.0.0: initial release + */ + string public constant override typeAndVersion = "AutomationRegistry 2.3.0"; + + /** + * @param logicA the address of the first logic contract, but cast as logicB in order to call logicB functions + */ + constructor( + AutomationRegistryLogicB2_3 logicA + ) + AutomationRegistryBase2_3( + logicA.getLinkAddress(), + logicA.getLinkNativeFeedAddress(), + logicA.getFastGasFeedAddress(), + logicA.getAutomationForwarderLogic(), + logicA.getAllowedReadOnlyAddress() + ) + Chainable(address(logicA)) + {} + + /** + * @notice holds the variables used in the transmit function, necessary to avoid stack too deep errors + */ + struct TransmitVars { + uint16 numUpkeepsPassedChecks; + uint256 totalCalldataWeight; + uint96 totalReimbursement; + uint96 totalPremium; + } + + // ================================================================ + // | ACTIONS | + // ================================================================ + + /** + * @inheritdoc OCR2Abstract + */ + function transmit( + bytes32[3] calldata reportContext, + bytes calldata rawReport, + bytes32[] calldata rs, + bytes32[] calldata ss, + bytes32 rawVs + ) external override { + uint256 gasOverhead = gasleft(); + HotVars memory hotVars = s_hotVars; + + if (hotVars.paused) revert RegistryPaused(); + if (!s_transmitters[msg.sender].active) revert OnlyActiveTransmitters(); + + // Verify signatures + if (s_latestConfigDigest != reportContext[0]) revert ConfigDigestMismatch(); + if (rs.length != hotVars.f + 1 || rs.length != ss.length) revert IncorrectNumberOfSignatures(); + _verifyReportSignature(reportContext, rawReport, rs, ss, rawVs); + + Report memory report = _decodeReport(rawReport); + + uint40 epochAndRound = uint40(uint256(reportContext[1])); + uint32 epoch = uint32(epochAndRound >> 8); + + _handleReport(hotVars, report, gasOverhead); + + if (epoch > hotVars.latestEpoch) { + s_hotVars.latestEpoch = epoch; + } + } + + function _handleReport(HotVars memory hotVars, Report memory report, uint256 gasOverhead) private { + UpkeepTransmitInfo[] memory upkeepTransmitInfo = new UpkeepTransmitInfo[](report.upkeepIds.length); + TransmitVars memory transmitVars = TransmitVars({ + numUpkeepsPassedChecks: 0, + totalCalldataWeight: 0, + totalReimbursement: 0, + totalPremium: 0 + }); + + uint256 blocknumber = hotVars.chainModule.blockNumber(); + uint256 l1Fee = hotVars.chainModule.getCurrentL1Fee(); + + for (uint256 i = 0; i < report.upkeepIds.length; i++) { + upkeepTransmitInfo[i].upkeep = s_upkeep[report.upkeepIds[i]]; + upkeepTransmitInfo[i].triggerType = _getTriggerType(report.upkeepIds[i]); + + (upkeepTransmitInfo[i].earlyChecksPassed, upkeepTransmitInfo[i].dedupID) = _prePerformChecks( + report.upkeepIds[i], + blocknumber, + report.triggers[i], + upkeepTransmitInfo[i], + hotVars + ); + + if (upkeepTransmitInfo[i].earlyChecksPassed) { + transmitVars.numUpkeepsPassedChecks += 1; + } else { + continue; + } + + // Actually perform the target upkeep + (upkeepTransmitInfo[i].performSuccess, upkeepTransmitInfo[i].gasUsed) = _performUpkeep( + upkeepTransmitInfo[i].upkeep.forwarder, + report.gasLimits[i], + report.performDatas[i] + ); + + // To split L1 fee across the upkeeps, assign a weight to this upkeep based on the length + // of the perform data and calldata overhead + upkeepTransmitInfo[i].calldataWeight = + report.performDatas[i].length + + TRANSMIT_CALLDATA_FIXED_BYTES_OVERHEAD + + (TRANSMIT_CALLDATA_PER_SIGNER_BYTES_OVERHEAD * (hotVars.f + 1)); + transmitVars.totalCalldataWeight += upkeepTransmitInfo[i].calldataWeight; + + // Deduct that gasUsed by upkeep from our running counter + gasOverhead -= upkeepTransmitInfo[i].gasUsed; + + // Store last perform block number / deduping key for upkeep + _updateTriggerMarker(report.upkeepIds[i], blocknumber, upkeepTransmitInfo[i]); + } + // No upkeeps to be performed in this report + if (transmitVars.numUpkeepsPassedChecks == 0) { + return; + } + + // This is the overall gas overhead that will be split across performed upkeeps + // Take upper bound of 16 gas per callData bytes + gasOverhead = (gasOverhead - gasleft()) + (16 * msg.data.length) + ACCOUNTING_FIXED_GAS_OVERHEAD; + gasOverhead = gasOverhead / transmitVars.numUpkeepsPassedChecks + ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD; + + { + uint96 reimbursement; + uint96 premium; + for (uint256 i = 0; i < report.upkeepIds.length; i++) { + if (upkeepTransmitInfo[i].earlyChecksPassed) { + (reimbursement, premium) = _postPerformPayment( + hotVars, + report.upkeepIds[i], + upkeepTransmitInfo[i].gasUsed, + report.fastGasWei, + report.linkNative, + gasOverhead, + (l1Fee * upkeepTransmitInfo[i].calldataWeight) / transmitVars.totalCalldataWeight + ); + transmitVars.totalPremium += premium; + transmitVars.totalReimbursement += reimbursement; + + emit UpkeepPerformed( + report.upkeepIds[i], + upkeepTransmitInfo[i].performSuccess, + reimbursement + premium, + upkeepTransmitInfo[i].gasUsed, + gasOverhead, + report.triggers[i] + ); + } + } + } + // record payments + s_transmitters[msg.sender].balance += transmitVars.totalReimbursement; + s_hotVars.totalPremium += transmitVars.totalPremium; + } + + /** + * @notice simulates the upkeep with the perform data returned from checkUpkeep + * @param id identifier of the upkeep to execute the data with. + * @param performData calldata parameter to be passed to the target upkeep. + * @return success whether the call reverted or not + * @return gasUsed the amount of gas the target contract consumed + */ + function simulatePerformUpkeep( + uint256 id, + bytes calldata performData + ) external returns (bool success, uint256 gasUsed) { + _preventExecution(); + + if (s_hotVars.paused) revert RegistryPaused(); + Upkeep memory upkeep = s_upkeep[id]; + (success, gasUsed) = _performUpkeep(upkeep.forwarder, upkeep.performGas, performData); + return (success, gasUsed); + } + + /** + * @notice uses LINK's transferAndCall to LINK and add funding to an upkeep + * @dev safe to cast uint256 to uint96 as total LINK supply is under UINT96MAX + * @param sender the account which transferred the funds + * @param amount number of LINK transfer + */ + function onTokenTransfer(address sender, uint256 amount, bytes calldata data) external override { + if (msg.sender != address(i_link)) revert OnlyCallableByLINKToken(); + if (data.length != 32) revert InvalidDataLength(); + uint256 id = abi.decode(data, (uint256)); + if (s_upkeep[id].maxValidBlocknumber != UINT32_MAX) revert UpkeepCancelled(); + s_upkeep[id].balance = s_upkeep[id].balance + uint96(amount); + s_expectedLinkBalance = s_expectedLinkBalance + amount; + emit FundsAdded(id, sender, uint96(amount)); + } + + // ================================================================ + // | SETTERS | + // ================================================================ + + /** + * @inheritdoc OCR2Abstract + * @dev prefer the type-safe version of setConfig (below) whenever possible. The OnchainConfig could differ between registry versions + */ + function setConfig( + address[] memory signers, + address[] memory transmitters, + uint8 f, + bytes memory onchainConfigBytes, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) external override { + setConfigTypeSafe( + signers, + transmitters, + f, + abi.decode(onchainConfigBytes, (OnchainConfig)), + offchainConfigVersion, + offchainConfig + ); + } + + function setConfigTypeSafe( + address[] memory signers, + address[] memory transmitters, + uint8 f, + OnchainConfig memory onchainConfig, + uint64 offchainConfigVersion, + bytes memory offchainConfig + ) public onlyOwner { + if (signers.length > MAX_NUM_ORACLES) revert TooManyOracles(); + if (f == 0) revert IncorrectNumberOfFaultyOracles(); + if (signers.length != transmitters.length || signers.length <= 3 * f) revert IncorrectNumberOfSigners(); + + // move all pooled payments out of the pool to each transmitter's balance + uint96 totalPremium = s_hotVars.totalPremium; + uint96 oldLength = uint96(s_transmittersList.length); + for (uint256 i = 0; i < oldLength; i++) { + _updateTransmitterBalanceFromPool(s_transmittersList[i], totalPremium, oldLength); + } + + // remove any old signer/transmitter addresses + address signerAddress; + address transmitterAddress; + for (uint256 i = 0; i < oldLength; i++) { + signerAddress = s_signersList[i]; + transmitterAddress = s_transmittersList[i]; + delete s_signers[signerAddress]; + // Do not delete the whole transmitter struct as it has balance information stored + s_transmitters[transmitterAddress].active = false; + } + delete s_signersList; + delete s_transmittersList; + + // add new signer/transmitter addresses + { + Transmitter memory transmitter; + address temp; + for (uint256 i = 0; i < signers.length; i++) { + if (s_signers[signers[i]].active) revert RepeatedSigner(); + if (signers[i] == ZERO_ADDRESS) revert InvalidSigner(); + s_signers[signers[i]] = Signer({active: true, index: uint8(i)}); + + temp = transmitters[i]; + if (temp == ZERO_ADDRESS) revert InvalidTransmitter(); + transmitter = s_transmitters[temp]; + if (transmitter.active) revert RepeatedTransmitter(); + transmitter.active = true; + transmitter.index = uint8(i); + // new transmitters start afresh from current totalPremium + // some spare change of premium from previous pool will be forfeited + transmitter.lastCollected = totalPremium; + s_transmitters[temp] = transmitter; + } + } + s_signersList = signers; + s_transmittersList = transmitters; + + s_hotVars = HotVars({ + f: f, + paymentPremiumPPB: onchainConfig.paymentPremiumPPB, + flatFeeMicroLink: onchainConfig.flatFeeMicroLink, + stalenessSeconds: onchainConfig.stalenessSeconds, + gasCeilingMultiplier: onchainConfig.gasCeilingMultiplier, + paused: s_hotVars.paused, + reentrancyGuard: s_hotVars.reentrancyGuard, + totalPremium: totalPremium, + latestEpoch: 0, // DON restarts epoch + reorgProtectionEnabled: onchainConfig.reorgProtectionEnabled, + chainModule: onchainConfig.chainModule + }); + + s_storage = Storage({ + checkGasLimit: onchainConfig.checkGasLimit, + minUpkeepSpend: onchainConfig.minUpkeepSpend, + maxPerformGas: onchainConfig.maxPerformGas, + transcoder: onchainConfig.transcoder, + maxCheckDataSize: onchainConfig.maxCheckDataSize, + maxPerformDataSize: onchainConfig.maxPerformDataSize, + maxRevertDataSize: onchainConfig.maxRevertDataSize, + upkeepPrivilegeManager: onchainConfig.upkeepPrivilegeManager, + nonce: s_storage.nonce, + configCount: s_storage.configCount, + latestConfigBlockNumber: s_storage.latestConfigBlockNumber, + ownerLinkBalance: s_storage.ownerLinkBalance + }); + s_fallbackGasPrice = onchainConfig.fallbackGasPrice; + s_fallbackLinkPrice = onchainConfig.fallbackLinkPrice; + + uint32 previousConfigBlockNumber = s_storage.latestConfigBlockNumber; + s_storage.latestConfigBlockNumber = uint32(onchainConfig.chainModule.blockNumber()); + s_storage.configCount += 1; + + bytes memory onchainConfigBytes = abi.encode(onchainConfig); + + s_latestConfigDigest = _configDigestFromConfigData( + block.chainid, + address(this), + s_storage.configCount, + signers, + transmitters, + f, + onchainConfigBytes, + offchainConfigVersion, + offchainConfig + ); + + for (uint256 idx = 0; idx < s_registrars.length(); idx++) { + s_registrars.remove(s_registrars.at(idx)); + } + + for (uint256 idx = 0; idx < onchainConfig.registrars.length; idx++) { + s_registrars.add(onchainConfig.registrars[idx]); + } + + emit ConfigSet( + previousConfigBlockNumber, + s_latestConfigDigest, + s_storage.configCount, + signers, + transmitters, + f, + onchainConfigBytes, + offchainConfigVersion, + offchainConfig + ); + } + + // ================================================================ + // | GETTERS | + // ================================================================ + + /** + * @inheritdoc OCR2Abstract + */ + function latestConfigDetails() + external + view + override + returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest) + { + return (s_storage.configCount, s_storage.latestConfigBlockNumber, s_latestConfigDigest); + } + + /** + * @inheritdoc OCR2Abstract + */ + function latestConfigDigestAndEpoch() + external + view + override + returns (bool scanLogs, bytes32 configDigest, uint32 epoch) + { + return (false, s_latestConfigDigest, s_hotVars.latestEpoch); + } +} diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol new file mode 100644 index 00000000000..4874bbcb948 --- /dev/null +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol @@ -0,0 +1,956 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; +import {StreamsLookupCompatibleInterface} from "../../interfaces/StreamsLookupCompatibleInterface.sol"; +import {ILogAutomation, Log} from "../../interfaces/ILogAutomation.sol"; +import {IAutomationForwarder} from "../../interfaces/IAutomationForwarder.sol"; +import {ConfirmedOwner} from "../../../shared/access/ConfirmedOwner.sol"; +import {AggregatorV3Interface} from "../../../shared/interfaces/AggregatorV3Interface.sol"; +import {LinkTokenInterface} from "../../../shared/interfaces/LinkTokenInterface.sol"; +import {KeeperCompatibleInterface} from "../../interfaces/KeeperCompatibleInterface.sol"; +import {UpkeepFormat} from "../../interfaces/UpkeepTranscoderInterface.sol"; +import {IChainModule} from "../interfaces/IChainModule.sol"; + +/** + * @notice Base Keeper Registry contract, contains shared logic between + * AutomationRegistry and AutomationRegistryLogic + * @dev all errors, events, and internal functions should live here + */ +abstract contract AutomationRegistryBase2_3 is ConfirmedOwner { + using Address for address; + using EnumerableSet for EnumerableSet.UintSet; + using EnumerableSet for EnumerableSet.AddressSet; + + address internal constant ZERO_ADDRESS = address(0); + address internal constant IGNORE_ADDRESS = 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF; + bytes4 internal constant CHECK_SELECTOR = KeeperCompatibleInterface.checkUpkeep.selector; + bytes4 internal constant PERFORM_SELECTOR = KeeperCompatibleInterface.performUpkeep.selector; + bytes4 internal constant CHECK_CALLBACK_SELECTOR = StreamsLookupCompatibleInterface.checkCallback.selector; + bytes4 internal constant CHECK_LOG_SELECTOR = ILogAutomation.checkLog.selector; + uint256 internal constant PERFORM_GAS_MIN = 2_300; + uint256 internal constant CANCELLATION_DELAY = 50; + uint256 internal constant PERFORM_GAS_CUSHION = 5_000; + uint256 internal constant PPB_BASE = 1_000_000_000; + uint32 internal constant UINT32_MAX = type(uint32).max; + uint96 internal constant LINK_TOTAL_SUPPLY = 1e27; + // The first byte of the mask can be 0, because we only ever have 31 oracles + uint256 internal constant ORACLE_MASK = 0x0001010101010101010101010101010101010101010101010101010101010101; + /** + * @dev UPKEEP_TRANSCODER_VERSION_BASE is temporary necessity for backwards compatibility with + * MigratableAutomationRegistryInterfaceV1 - it should be removed in future versions in favor of + * UPKEEP_VERSION_BASE and MigratableAutomationRegistryInterfaceV2 + */ + UpkeepFormat internal constant UPKEEP_TRANSCODER_VERSION_BASE = UpkeepFormat.V1; + uint8 internal constant UPKEEP_VERSION_BASE = 3; + + // Next block of constants are only used in maxPayment estimation during checkUpkeep simulation + // These values are calibrated using hardhat tests which simulates various cases and verifies that + // the variables result in accurate estimation + uint256 internal constant REGISTRY_CONDITIONAL_OVERHEAD = 60_000; // Fixed gas overhead for conditional upkeeps + uint256 internal constant REGISTRY_LOG_OVERHEAD = 85_000; // Fixed gas overhead for log upkeeps + uint256 internal constant REGISTRY_PER_SIGNER_GAS_OVERHEAD = 5_600; // Value scales with f + uint256 internal constant REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD = 24; // Per perform data byte overhead + + // The overhead (in bytes) in addition to perform data for upkeep sent in calldata + // This includes overhead for all struct encoding as well as report signatures + // There is a fixed component and a per signer component. This is calculated exactly by doing abi encoding + uint256 internal constant TRANSMIT_CALLDATA_FIXED_BYTES_OVERHEAD = 932; + uint256 internal constant TRANSMIT_CALLDATA_PER_SIGNER_BYTES_OVERHEAD = 64; + + // Next block of constants are used in actual payment calculation. We calculate the exact gas used within the + // tx itself, but since payment processing itself takes gas, and it needs the overhead as input, we use fixed constants + // to account for gas used in payment processing. These values are calibrated using hardhat tests which simulates various cases and verifies that + // the variables result in accurate estimation + uint256 internal constant ACCOUNTING_FIXED_GAS_OVERHEAD = 22_000; // Fixed overhead per tx + uint256 internal constant ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD = 7_000; // Overhead per upkeep performed in batch + + LinkTokenInterface internal immutable i_link; + AggregatorV3Interface internal immutable i_linkNativeFeed; + AggregatorV3Interface internal immutable i_fastGasFeed; + address internal immutable i_automationForwarderLogic; + address internal immutable i_allowedReadOnlyAddress; + + /** + * @dev - The storage is gas optimised for one and only one function - transmit. All the storage accessed in transmit + * is stored compactly. Rest of the storage layout is not of much concern as transmit is the only hot path + */ + + // Upkeep storage + EnumerableSet.UintSet internal s_upkeepIDs; + mapping(uint256 => Upkeep) internal s_upkeep; // accessed during transmit + mapping(uint256 => address) internal s_upkeepAdmin; + mapping(uint256 => address) internal s_proposedAdmin; + mapping(uint256 => bytes) internal s_checkData; + mapping(bytes32 => bool) internal s_dedupKeys; + // Registry config and state + EnumerableSet.AddressSet internal s_registrars; + mapping(address => Transmitter) internal s_transmitters; + mapping(address => Signer) internal s_signers; + address[] internal s_signersList; // s_signersList contains the signing address of each oracle + address[] internal s_transmittersList; // s_transmittersList contains the transmission address of each oracle + mapping(address => address) internal s_transmitterPayees; // s_payees contains the mapping from transmitter to payee. + mapping(address => address) internal s_proposedPayee; // proposed payee for a transmitter + bytes32 internal s_latestConfigDigest; // Read on transmit path in case of signature verification + HotVars internal s_hotVars; // Mixture of config and state, used in transmit + Storage internal s_storage; // Mixture of config and state, not used in transmit + uint256 internal s_fallbackGasPrice; + uint256 internal s_fallbackLinkPrice; + uint256 internal s_expectedLinkBalance; // Used in case of erroneous LINK transfers to contract + mapping(address => MigrationPermission) internal s_peerRegistryMigrationPermission; // Permissions for migration to and fro + mapping(uint256 => bytes) internal s_upkeepTriggerConfig; // upkeep triggers + mapping(uint256 => bytes) internal s_upkeepOffchainConfig; // general config set by users for each upkeep + mapping(uint256 => bytes) internal s_upkeepPrivilegeConfig; // general config set by an administrative role for an upkeep + mapping(address => bytes) internal s_adminPrivilegeConfig; // general config set by an administrative role for an admin + + error ArrayHasNoEntries(); + error CannotCancel(); + error CheckDataExceedsLimit(); + error ConfigDigestMismatch(); + error DuplicateEntry(); + error DuplicateSigners(); + error GasLimitCanOnlyIncrease(); + error GasLimitOutsideRange(); + error IncorrectNumberOfFaultyOracles(); + error IncorrectNumberOfSignatures(); + error IncorrectNumberOfSigners(); + error IndexOutOfRange(); + error InvalidDataLength(); + error InvalidTrigger(); + error InvalidPayee(); + error InvalidRecipient(); + error InvalidReport(); + error InvalidSigner(); + error InvalidTransmitter(); + error InvalidTriggerType(); + error MaxCheckDataSizeCanOnlyIncrease(); + error MaxPerformDataSizeCanOnlyIncrease(); + error MigrationNotPermitted(); + error NotAContract(); + error OnlyActiveSigners(); + error OnlyActiveTransmitters(); + error OnlyCallableByAdmin(); + error OnlyCallableByLINKToken(); + error OnlyCallableByOwnerOrAdmin(); + error OnlyCallableByOwnerOrRegistrar(); + error OnlyCallableByPayee(); + error OnlyCallableByProposedAdmin(); + error OnlyCallableByProposedPayee(); + error OnlyCallableByUpkeepPrivilegeManager(); + error OnlyPausedUpkeep(); + error OnlySimulatedBackend(); + error OnlyUnpausedUpkeep(); + error ParameterLengthError(); + error PaymentGreaterThanAllLINK(); + error ReentrantCall(); + error RegistryPaused(); + error RepeatedSigner(); + error RepeatedTransmitter(); + error TargetCheckReverted(bytes reason); + error TooManyOracles(); + error TranscoderNotSet(); + error UpkeepAlreadyExists(); + error UpkeepCancelled(); + error UpkeepNotCanceled(); + error UpkeepNotNeeded(); + error ValueNotChanged(); + + enum MigrationPermission { + NONE, + OUTGOING, + INCOMING, + BIDIRECTIONAL + } + + enum Trigger { + CONDITION, + LOG + } + + enum UpkeepFailureReason { + NONE, + UPKEEP_CANCELLED, + UPKEEP_PAUSED, + TARGET_CHECK_REVERTED, + UPKEEP_NOT_NEEDED, + PERFORM_DATA_EXCEEDS_LIMIT, + INSUFFICIENT_BALANCE, + CALLBACK_REVERTED, + REVERT_DATA_EXCEEDS_LIMIT, + REGISTRY_PAUSED + } + + /** + * @notice OnchainConfigLegacy of the registry + * @dev only used in params and return values + * @member paymentPremiumPPB payment premium rate oracles receive on top of + * being reimbursed for gas, measured in parts per billion + * @member flatFeeMicroLink flat fee paid to oracles for performing upkeeps, + * priced in MicroLink; can be used in conjunction with or independently of + * paymentPremiumPPB + * @member checkGasLimit gas limit when checking for upkeep + * @member stalenessSeconds number of seconds that is allowed for feed data to + * be stale before switching to the fallback pricing + * @member gasCeilingMultiplier multiplier to apply to the fast gas feed price + * when calculating the payment ceiling for keepers + * @member minUpkeepSpend minimum LINK that an upkeep must spend before cancelling + * @member maxPerformGas max performGas allowed for an upkeep on this registry + * @member maxCheckDataSize max length of checkData bytes + * @member maxPerformDataSize max length of performData bytes + * @member maxRevertDataSize max length of revertData bytes + * @member fallbackGasPrice gas price used if the gas price feed is stale + * @member fallbackLinkPrice LINK price used if the LINK price feed is stale + * @member transcoder address of the transcoder contract + * @member registrars addresses of the registrar contracts + * @member upkeepPrivilegeManager address which can set privilege for upkeeps + */ + struct OnchainConfigLegacy { + uint32 paymentPremiumPPB; + uint32 flatFeeMicroLink; // min 0.000001 LINK, max 4294 LINK + uint32 checkGasLimit; + uint24 stalenessSeconds; + uint16 gasCeilingMultiplier; + uint96 minUpkeepSpend; + uint32 maxPerformGas; + uint32 maxCheckDataSize; + uint32 maxPerformDataSize; + uint32 maxRevertDataSize; + uint256 fallbackGasPrice; + uint256 fallbackLinkPrice; + address transcoder; + address[] registrars; + address upkeepPrivilegeManager; + } + + /** + * @notice OnchainConfig of the registry + * @dev used only in setConfig() + * @member paymentPremiumPPB payment premium rate oracles receive on top of + * being reimbursed for gas, measured in parts per billion + * @member flatFeeMicroLink flat fee paid to oracles for performing upkeeps, + * priced in MicroLink; can be used in conjunction with or independently of + * paymentPremiumPPB + * @member checkGasLimit gas limit when checking for upkeep + * @member stalenessSeconds number of seconds that is allowed for feed data to + * be stale before switching to the fallback pricing + * @member gasCeilingMultiplier multiplier to apply to the fast gas feed price + * when calculating the payment ceiling for keepers + * @member minUpkeepSpend minimum LINK that an upkeep must spend before cancelling + * @member maxPerformGas max performGas allowed for an upkeep on this registry + * @member maxCheckDataSize max length of checkData bytes + * @member maxPerformDataSize max length of performData bytes + * @member maxRevertDataSize max length of revertData bytes + * @member fallbackGasPrice gas price used if the gas price feed is stale + * @member fallbackLinkPrice LINK price used if the LINK price feed is stale + * @member transcoder address of the transcoder contract + * @member registrars addresses of the registrar contracts + * @member upkeepPrivilegeManager address which can set privilege for upkeeps + * @member reorgProtectionEnabled if this registry enables re-org protection checks + * @member chainModule the chain specific module + */ + struct OnchainConfig { + uint32 paymentPremiumPPB; + uint32 flatFeeMicroLink; // min 0.000001 LINK, max 4294 LINK + uint32 checkGasLimit; + uint24 stalenessSeconds; + uint16 gasCeilingMultiplier; + uint96 minUpkeepSpend; + uint32 maxPerformGas; + uint32 maxCheckDataSize; + uint32 maxPerformDataSize; + uint32 maxRevertDataSize; + uint256 fallbackGasPrice; + uint256 fallbackLinkPrice; + address transcoder; + address[] registrars; + address upkeepPrivilegeManager; + IChainModule chainModule; + bool reorgProtectionEnabled; + } + + /** + * @notice state of the registry + * @dev only used in params and return values + * @dev this will likely be deprecated in a future version of the registry in favor of individual getters + * @member nonce used for ID generation + * @member ownerLinkBalance withdrawable balance of LINK by contract owner + * @member expectedLinkBalance the expected balance of LINK of the registry + * @member totalPremium the total premium collected on registry so far + * @member numUpkeeps total number of upkeeps on the registry + * @member configCount ordinal number of current config, out of all configs applied to this contract so far + * @member latestConfigBlockNumber last block at which this config was set + * @member latestConfigDigest domain-separation tag for current config + * @member latestEpoch for which a report was transmitted + * @member paused freeze on execution scoped to the entire registry + */ + struct State { + uint32 nonce; + uint96 ownerLinkBalance; + uint256 expectedLinkBalance; + uint96 totalPremium; + uint256 numUpkeeps; + uint32 configCount; + uint32 latestConfigBlockNumber; + bytes32 latestConfigDigest; + uint32 latestEpoch; + bool paused; + } + + /** + * @notice relevant state of an upkeep which is used in transmit function + * @member paused if this upkeep has been paused + * @member performGas the gas limit of upkeep execution + * @member maxValidBlocknumber until which block this upkeep is valid + * @member forwarder the forwarder contract to use for this upkeep + * @member amountSpent the amount this upkeep has spent + * @member balance the balance of this upkeep + * @member lastPerformedBlockNumber the last block number when this upkeep was performed + */ + struct Upkeep { + bool paused; + uint32 performGas; + uint32 maxValidBlocknumber; + IAutomationForwarder forwarder; + // 0 bytes left in 1st EVM word - not written to in transmit + uint96 amountSpent; + uint96 balance; + uint32 lastPerformedBlockNumber; + // 2 bytes left in 2nd EVM word - written in transmit path + } + + /** + * @notice all information about an upkeep + * @dev only used in return values + * @dev this will likely be deprecated in a future version of the registry + * @member target the contract which needs to be serviced + * @member performGas the gas limit of upkeep execution + * @member checkData the checkData bytes for this upkeep + * @member balance the balance of this upkeep + * @member admin for this upkeep + * @member maxValidBlocknumber until which block this upkeep is valid + * @member lastPerformedBlockNumber the last block number when this upkeep was performed + * @member amountSpent the amount this upkeep has spent + * @member paused if this upkeep has been paused + * @member offchainConfig the off-chain config of this upkeep + */ + struct UpkeepInfo { + address target; + uint32 performGas; + bytes checkData; + uint96 balance; + address admin; + uint64 maxValidBlocknumber; + uint32 lastPerformedBlockNumber; + uint96 amountSpent; + bool paused; + bytes offchainConfig; + } + + /// @dev Config + State storage struct which is on hot transmit path + struct HotVars { + uint96 totalPremium; // ─────────╮ total historical payment to oracles for premium + uint32 paymentPremiumPPB; // │ premium percentage charged to user over tx cost + uint32 flatFeeMicroLink; // │ flat fee charged to user for every perform + uint32 latestEpoch; // │ latest epoch for which a report was transmitted + uint24 stalenessSeconds; // │ Staleness tolerance for feeds + uint16 gasCeilingMultiplier; // │ multiplier on top of fast gas feed for upper bound + uint8 f; // │ maximum number of faulty oracles + bool paused; // │ pause switch for all upkeeps in the registry + bool reentrancyGuard; // ────────╯ guard against reentrancy + bool reorgProtectionEnabled; // if this registry should enable re-org protection mechanism + IChainModule chainModule; // the interface of chain specific module + } + + /// @dev Config + State storage struct which is not on hot transmit path + struct Storage { + uint96 minUpkeepSpend; // Minimum amount an upkeep must spend + address transcoder; // Address of transcoder contract used in migrations + // 1 EVM word full + uint96 ownerLinkBalance; // Balance of owner, accumulates minUpkeepSpend in case it is not spent + uint32 checkGasLimit; // Gas limit allowed in checkUpkeep + uint32 maxPerformGas; // Max gas an upkeep can use on this registry + uint32 nonce; // Nonce for each upkeep created + uint32 configCount; // incremented each time a new config is posted, The count + // is incorporated into the config digest to prevent replay attacks. + uint32 latestConfigBlockNumber; // makes it easier for offchain systems to extract config from logs + // 2 EVM word full + uint32 maxCheckDataSize; // max length of checkData bytes + uint32 maxPerformDataSize; // max length of performData bytes + uint32 maxRevertDataSize; // max length of revertData bytes + address upkeepPrivilegeManager; // address which can set privilege for upkeeps + // 3 EVM word full + } + + /// @dev Report transmitted by OCR to transmit function + struct Report { + uint256 fastGasWei; + uint256 linkNative; + uint256[] upkeepIds; + uint256[] gasLimits; + bytes[] triggers; + bytes[] performDatas; + } + + /** + * @dev This struct is used to maintain run time information about an upkeep in transmit function + * @member upkeep the upkeep struct + * @member earlyChecksPassed whether the upkeep passed early checks before perform + * @member performSuccess whether the perform was successful + * @member triggerType the type of trigger + * @member gasUsed gasUsed by this upkeep in perform + * @member calldataWeight weight assigned to this upkeep for its contribution to calldata. It is used to split L1 fee + * @member dedupID unique ID used to dedup an upkeep/trigger combo + */ + struct UpkeepTransmitInfo { + Upkeep upkeep; + bool earlyChecksPassed; + bool performSuccess; + Trigger triggerType; + uint256 gasUsed; + uint256 calldataWeight; + bytes32 dedupID; + } + + struct Transmitter { + bool active; + uint8 index; // Index of oracle in s_signersList/s_transmittersList + uint96 balance; + uint96 lastCollected; + } + + struct Signer { + bool active; + // Index of oracle in s_signersList/s_transmittersList + uint8 index; + } + + /** + * @notice the trigger structure conditional trigger type + */ + struct ConditionalTrigger { + uint32 blockNum; + bytes32 blockHash; + } + + /** + * @notice the trigger structure of log upkeeps + * @dev NOTE that blockNum / blockHash describe the block used for the callback, + * not necessarily the block number that the log was emitted in!!!! + */ + struct LogTrigger { + bytes32 logBlockHash; + bytes32 txHash; + uint32 logIndex; + uint32 blockNum; + bytes32 blockHash; + } + + event AdminPrivilegeConfigSet(address indexed admin, bytes privilegeConfig); + event CancelledUpkeepReport(uint256 indexed id, bytes trigger); + event ChainSpecificModuleUpdated(address newModule); + event DedupKeyAdded(bytes32 indexed dedupKey); + event FundsAdded(uint256 indexed id, address indexed from, uint96 amount); + event FundsWithdrawn(uint256 indexed id, uint256 amount, address to); + event InsufficientFundsUpkeepReport(uint256 indexed id, bytes trigger); + event OwnerFundsWithdrawn(uint96 amount); + event Paused(address account); + event PayeesUpdated(address[] transmitters, address[] payees); + event PayeeshipTransferRequested(address indexed transmitter, address indexed from, address indexed to); + event PayeeshipTransferred(address indexed transmitter, address indexed from, address indexed to); + event PaymentWithdrawn(address indexed transmitter, uint256 indexed amount, address indexed to, address payee); + event ReorgedUpkeepReport(uint256 indexed id, bytes trigger); + event StaleUpkeepReport(uint256 indexed id, bytes trigger); + event UpkeepAdminTransferred(uint256 indexed id, address indexed from, address indexed to); + event UpkeepAdminTransferRequested(uint256 indexed id, address indexed from, address indexed to); + event UpkeepCanceled(uint256 indexed id, uint64 indexed atBlockHeight); + event UpkeepCheckDataSet(uint256 indexed id, bytes newCheckData); + event UpkeepGasLimitSet(uint256 indexed id, uint96 gasLimit); + event UpkeepMigrated(uint256 indexed id, uint256 remainingBalance, address destination); + event UpkeepOffchainConfigSet(uint256 indexed id, bytes offchainConfig); + event UpkeepPaused(uint256 indexed id); + event UpkeepPerformed( + uint256 indexed id, + bool indexed success, + uint96 totalPayment, + uint256 gasUsed, + uint256 gasOverhead, + bytes trigger + ); + event UpkeepPrivilegeConfigSet(uint256 indexed id, bytes privilegeConfig); + event UpkeepReceived(uint256 indexed id, uint256 startingBalance, address importedFrom); + event UpkeepRegistered(uint256 indexed id, uint32 performGas, address admin); + event UpkeepTriggerConfigSet(uint256 indexed id, bytes triggerConfig); + event UpkeepUnpaused(uint256 indexed id); + event Unpaused(address account); + + /** + * @param link address of the LINK Token + * @param linkNativeFeed address of the LINK/Native price feed + * @param fastGasFeed address of the Fast Gas price feed + * @param automationForwarderLogic the address of automation forwarder logic + * @param allowedReadOnlyAddress the address of the allowed read only address + */ + constructor( + address link, + address linkNativeFeed, + address fastGasFeed, + address automationForwarderLogic, + address allowedReadOnlyAddress + ) ConfirmedOwner(msg.sender) { + i_link = LinkTokenInterface(link); + i_linkNativeFeed = AggregatorV3Interface(linkNativeFeed); + i_fastGasFeed = AggregatorV3Interface(fastGasFeed); + i_automationForwarderLogic = automationForwarderLogic; + i_allowedReadOnlyAddress = allowedReadOnlyAddress; + } + + // ================================================================ + // | INTERNAL FUNCTIONS ONLY | + // ================================================================ + + /** + * @dev creates a new upkeep with the given fields + * @param id the id of the upkeep + * @param upkeep the upkeep to create + * @param admin address to cancel upkeep and withdraw remaining funds + * @param checkData data which is passed to user's checkUpkeep + * @param triggerConfig the trigger config for this upkeep + * @param offchainConfig the off-chain config of this upkeep + */ + function _createUpkeep( + uint256 id, + Upkeep memory upkeep, + address admin, + bytes memory checkData, + bytes memory triggerConfig, + bytes memory offchainConfig + ) internal { + if (s_hotVars.paused) revert RegistryPaused(); + if (checkData.length > s_storage.maxCheckDataSize) revert CheckDataExceedsLimit(); + if (upkeep.performGas < PERFORM_GAS_MIN || upkeep.performGas > s_storage.maxPerformGas) + revert GasLimitOutsideRange(); + if (address(s_upkeep[id].forwarder) != address(0)) revert UpkeepAlreadyExists(); + s_upkeep[id] = upkeep; + s_upkeepAdmin[id] = admin; + s_checkData[id] = checkData; + s_expectedLinkBalance = s_expectedLinkBalance + upkeep.balance; + s_upkeepTriggerConfig[id] = triggerConfig; + s_upkeepOffchainConfig[id] = offchainConfig; + s_upkeepIDs.add(id); + } + + /** + * @dev creates an ID for the upkeep based on the upkeep's type + * @dev the format of the ID looks like this: + * ****00000000000X**************** + * 4 bytes of entropy + * 11 bytes of zeros + * 1 identifying byte for the trigger type + * 16 bytes of entropy + * @dev this maintains the same level of entropy as eth addresses, so IDs will still be unique + * @dev we add the "identifying" part in the middle so that it is mostly hidden from users who usually only + * see the first 4 and last 4 hex values ex 0x1234...ABCD + */ + function _createID(Trigger triggerType) internal view returns (uint256) { + bytes1 empty; + IChainModule chainModule = s_hotVars.chainModule; + bytes memory idBytes = abi.encodePacked( + keccak256(abi.encode(chainModule.blockHash((chainModule.blockNumber() - 1)), address(this), s_storage.nonce)) + ); + for (uint256 idx = 4; idx < 15; idx++) { + idBytes[idx] = empty; + } + idBytes[15] = bytes1(uint8(triggerType)); + return uint256(bytes32(idBytes)); + } + + /** + * @dev retrieves feed data for fast gas/native and link/native prices. if the feed + * data is stale it uses the configured fallback price. Once a price is picked + * for gas it takes the min of gas price in the transaction or the fast gas + * price in order to reduce costs for the upkeep clients. + */ + function _getFeedData(HotVars memory hotVars) internal view returns (uint256 gasWei, uint256 linkNative) { + uint32 stalenessSeconds = hotVars.stalenessSeconds; + bool staleFallback = stalenessSeconds > 0; + uint256 timestamp; + int256 feedValue; + (, feedValue, , timestamp, ) = i_fastGasFeed.latestRoundData(); + if ( + feedValue <= 0 || block.timestamp < timestamp || (staleFallback && stalenessSeconds < block.timestamp - timestamp) + ) { + gasWei = s_fallbackGasPrice; + } else { + gasWei = uint256(feedValue); + } + (, feedValue, , timestamp, ) = i_linkNativeFeed.latestRoundData(); + if ( + feedValue <= 0 || block.timestamp < timestamp || (staleFallback && stalenessSeconds < block.timestamp - timestamp) + ) { + linkNative = s_fallbackLinkPrice; + } else { + linkNative = uint256(feedValue); + } + return (gasWei, linkNative); + } + + /** + * @dev calculates LINK paid for gas spent plus a configure premium percentage + * @param gasLimit the amount of gas used + * @param gasOverhead the amount of gas overhead + * @param l1CostWei the amount to be charged for L1 fee in wei + * @param fastGasWei the fast gas price + * @param linkNative the exchange ratio between LINK and Native token + * @param isExecution if this is triggered by a perform upkeep function + */ + function _calculatePaymentAmount( + HotVars memory hotVars, + uint256 gasLimit, + uint256 gasOverhead, + uint256 l1CostWei, + uint256 fastGasWei, + uint256 linkNative, + bool isExecution + ) internal view returns (uint96, uint96) { + uint256 gasWei = fastGasWei * hotVars.gasCeilingMultiplier; + // in case it's actual execution use actual gas price, capped by fastGasWei * gasCeilingMultiplier + if (isExecution && tx.gasprice < gasWei) { + gasWei = tx.gasprice; + } + uint256 gasPayment = ((gasWei * (gasLimit + gasOverhead) + l1CostWei) * 1e18) / linkNative; + uint256 premium = (((gasWei * gasLimit) + l1CostWei) * 1e9 * hotVars.paymentPremiumPPB) / + linkNative + + uint256(hotVars.flatFeeMicroLink) * + 1e12; + // LINK_TOTAL_SUPPLY < UINT96_MAX + if (gasPayment + premium > LINK_TOTAL_SUPPLY) revert PaymentGreaterThanAllLINK(); + return (uint96(gasPayment), uint96(premium)); + } + + /** + * @dev calculates the max LINK payment for an upkeep. Called during checkUpkeep simulation and assumes + * maximum gas overhead, L1 fee + */ + function _getMaxLinkPayment( + HotVars memory hotVars, + Trigger triggerType, + uint32 performGas, + uint256 fastGasWei, + uint256 linkNative + ) internal view returns (uint96) { + uint256 maxGasOverhead; + if (triggerType == Trigger.CONDITION) { + maxGasOverhead = REGISTRY_CONDITIONAL_OVERHEAD; + } else if (triggerType == Trigger.LOG) { + maxGasOverhead = REGISTRY_LOG_OVERHEAD; + } else { + revert InvalidTriggerType(); + } + uint256 maxCalldataSize = s_storage.maxPerformDataSize + + TRANSMIT_CALLDATA_FIXED_BYTES_OVERHEAD + + (TRANSMIT_CALLDATA_PER_SIGNER_BYTES_OVERHEAD * (hotVars.f + 1)); + (uint256 chainModuleFixedOverhead, uint256 chainModulePerByteOverhead) = s_hotVars.chainModule.getGasOverhead(); + maxGasOverhead += + (REGISTRY_PER_SIGNER_GAS_OVERHEAD * (hotVars.f + 1)) + + ((REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD + chainModulePerByteOverhead) * maxCalldataSize) + + chainModuleFixedOverhead; + + uint256 maxL1Fee = hotVars.gasCeilingMultiplier * hotVars.chainModule.getMaxL1Fee(maxCalldataSize); + + (uint96 reimbursement, uint96 premium) = _calculatePaymentAmount( + hotVars, + performGas, + maxGasOverhead, + maxL1Fee, + fastGasWei, + linkNative, + false //isExecution + ); + + return reimbursement + premium; + } + + /** + * @dev move a transmitter's balance from total pool to withdrawable balance + */ + function _updateTransmitterBalanceFromPool( + address transmitterAddress, + uint96 totalPremium, + uint96 payeeCount + ) internal returns (uint96) { + Transmitter memory transmitter = s_transmitters[transmitterAddress]; + + if (transmitter.active) { + uint96 uncollected = totalPremium - transmitter.lastCollected; + uint96 due = uncollected / payeeCount; + transmitter.balance += due; + transmitter.lastCollected += due * payeeCount; + s_transmitters[transmitterAddress] = transmitter; + } + + return transmitter.balance; + } + + /** + * @dev gets the trigger type from an upkeepID (trigger type is encoded in the middle of the ID) + */ + function _getTriggerType(uint256 upkeepId) internal pure returns (Trigger) { + bytes32 rawID = bytes32(upkeepId); + bytes1 empty = bytes1(0); + for (uint256 idx = 4; idx < 15; idx++) { + if (rawID[idx] != empty) { + // old IDs that were created before this standard and migrated to this registry + return Trigger.CONDITION; + } + } + return Trigger(uint8(rawID[15])); + } + + function _checkPayload( + uint256 upkeepId, + Trigger triggerType, + bytes memory triggerData + ) internal view returns (bytes memory) { + if (triggerType == Trigger.CONDITION) { + return abi.encodeWithSelector(CHECK_SELECTOR, s_checkData[upkeepId]); + } else if (triggerType == Trigger.LOG) { + Log memory log = abi.decode(triggerData, (Log)); + return abi.encodeWithSelector(CHECK_LOG_SELECTOR, log, s_checkData[upkeepId]); + } + revert InvalidTriggerType(); + } + + /** + * @dev _decodeReport decodes a serialized report into a Report struct + */ + function _decodeReport(bytes calldata rawReport) internal pure returns (Report memory) { + Report memory report = abi.decode(rawReport, (Report)); + uint256 expectedLength = report.upkeepIds.length; + if ( + report.gasLimits.length != expectedLength || + report.triggers.length != expectedLength || + report.performDatas.length != expectedLength + ) { + revert InvalidReport(); + } + return report; + } + + /** + * @dev Does some early sanity checks before actually performing an upkeep + * @return bool whether the upkeep should be performed + * @return bytes32 dedupID for preventing duplicate performances of this trigger + */ + function _prePerformChecks( + uint256 upkeepId, + uint256 blocknumber, + bytes memory rawTrigger, + UpkeepTransmitInfo memory transmitInfo, + HotVars memory hotVars + ) internal returns (bool, bytes32) { + bytes32 dedupID; + if (transmitInfo.triggerType == Trigger.CONDITION) { + if (!_validateConditionalTrigger(upkeepId, blocknumber, rawTrigger, transmitInfo, hotVars)) + return (false, dedupID); + } else if (transmitInfo.triggerType == Trigger.LOG) { + bool valid; + (valid, dedupID) = _validateLogTrigger(upkeepId, blocknumber, rawTrigger, hotVars); + if (!valid) return (false, dedupID); + } else { + revert InvalidTriggerType(); + } + if (transmitInfo.upkeep.maxValidBlocknumber <= blocknumber) { + // Can happen when an upkeep got cancelled after report was generated. + // However we have a CANCELLATION_DELAY of 50 blocks so shouldn't happen in practice + emit CancelledUpkeepReport(upkeepId, rawTrigger); + return (false, dedupID); + } + return (true, dedupID); + } + + /** + * @dev Does some early sanity checks before actually performing an upkeep + */ + function _validateConditionalTrigger( + uint256 upkeepId, + uint256 blocknumber, + bytes memory rawTrigger, + UpkeepTransmitInfo memory transmitInfo, + HotVars memory hotVars + ) internal returns (bool) { + ConditionalTrigger memory trigger = abi.decode(rawTrigger, (ConditionalTrigger)); + if (trigger.blockNum < transmitInfo.upkeep.lastPerformedBlockNumber) { + // Can happen when another report performed this upkeep after this report was generated + emit StaleUpkeepReport(upkeepId, rawTrigger); + return false; + } + if ( + (hotVars.reorgProtectionEnabled && + (trigger.blockHash != bytes32("") && hotVars.chainModule.blockHash(trigger.blockNum) != trigger.blockHash)) || + trigger.blockNum >= blocknumber + ) { + // There are two cases of reorged report + // 1. trigger block number is in future: this is an edge case during extreme deep reorgs of chain + // which is always protected against + // 2. blockHash at trigger block number was same as trigger time. This is an optional check which is + // applied if DON sends non empty trigger.blockHash. Note: It only works for last 256 blocks on chain + // when it is sent + emit ReorgedUpkeepReport(upkeepId, rawTrigger); + return false; + } + return true; + } + + function _validateLogTrigger( + uint256 upkeepId, + uint256 blocknumber, + bytes memory rawTrigger, + HotVars memory hotVars + ) internal returns (bool, bytes32) { + LogTrigger memory trigger = abi.decode(rawTrigger, (LogTrigger)); + bytes32 dedupID = keccak256(abi.encodePacked(upkeepId, trigger.logBlockHash, trigger.txHash, trigger.logIndex)); + if ( + (hotVars.reorgProtectionEnabled && + (trigger.blockHash != bytes32("") && hotVars.chainModule.blockHash(trigger.blockNum) != trigger.blockHash)) || + trigger.blockNum >= blocknumber + ) { + // Reorg protection is same as conditional trigger upkeeps + emit ReorgedUpkeepReport(upkeepId, rawTrigger); + return (false, dedupID); + } + if (s_dedupKeys[dedupID]) { + emit StaleUpkeepReport(upkeepId, rawTrigger); + return (false, dedupID); + } + return (true, dedupID); + } + + /** + * @dev Verify signatures attached to report + */ + function _verifyReportSignature( + bytes32[3] calldata reportContext, + bytes calldata report, + bytes32[] calldata rs, + bytes32[] calldata ss, + bytes32 rawVs + ) internal view { + bytes32 h = keccak256(abi.encode(keccak256(report), reportContext)); + // i-th byte counts number of sigs made by i-th signer + uint256 signedCount = 0; + + Signer memory signer; + address signerAddress; + for (uint256 i = 0; i < rs.length; i++) { + signerAddress = ecrecover(h, uint8(rawVs[i]) + 27, rs[i], ss[i]); + signer = s_signers[signerAddress]; + if (!signer.active) revert OnlyActiveSigners(); + unchecked { + signedCount += 1 << (8 * signer.index); + } + } + + if (signedCount & ORACLE_MASK != signedCount) revert DuplicateSigners(); + } + + /** + * @dev updates a storage marker for this upkeep to prevent duplicate and out of order performances + * @dev for conditional triggers we set the latest block number, for log triggers we store a dedupID + */ + function _updateTriggerMarker( + uint256 upkeepID, + uint256 blocknumber, + UpkeepTransmitInfo memory upkeepTransmitInfo + ) internal { + if (upkeepTransmitInfo.triggerType == Trigger.CONDITION) { + s_upkeep[upkeepID].lastPerformedBlockNumber = uint32(blocknumber); + } else if (upkeepTransmitInfo.triggerType == Trigger.LOG) { + s_dedupKeys[upkeepTransmitInfo.dedupID] = true; + emit DedupKeyAdded(upkeepTransmitInfo.dedupID); + } + } + + /** + * @dev calls the Upkeep target with the performData param passed in by the + * transmitter and the exact gas required by the Upkeep + */ + function _performUpkeep( + IAutomationForwarder forwarder, + uint256 performGas, + bytes memory performData + ) internal nonReentrant returns (bool success, uint256 gasUsed) { + performData = abi.encodeWithSelector(PERFORM_SELECTOR, performData); + return forwarder.forward(performGas, performData); + } + + /** + * @dev does postPerform payment processing for an upkeep. Deducts upkeep's balance and increases + * amount spent. + */ + function _postPerformPayment( + HotVars memory hotVars, + uint256 upkeepId, + uint256 gasUsed, + uint256 fastGasWei, + uint256 linkNative, + uint256 gasOverhead, + uint256 l1Fee + ) internal returns (uint96 gasReimbursement, uint96 premium) { + (gasReimbursement, premium) = _calculatePaymentAmount( + hotVars, + gasUsed, + gasOverhead, + l1Fee, + fastGasWei, + linkNative, + true // isExecution + ); + + uint96 balance = s_upkeep[upkeepId].balance; + uint96 payment = gasReimbursement + premium; + + // this shouldn't happen, but in rare edge cases, we charge the full balance in case the user + // can't cover the amount owed + if (balance < gasReimbursement) { + payment = balance; + gasReimbursement = balance; + premium = 0; + } else if (balance < payment) { + payment = balance; + premium = payment - gasReimbursement; + } + + s_upkeep[upkeepId].balance -= payment; + s_upkeep[upkeepId].amountSpent += payment; + + return (gasReimbursement, premium); + } + + /** + * @dev ensures the upkeep is not cancelled and the caller is the upkeep admin + */ + function _requireAdminAndNotCancelled(uint256 upkeepId) internal view { + if (msg.sender != s_upkeepAdmin[upkeepId]) revert OnlyCallableByAdmin(); + if (s_upkeep[upkeepId].maxValidBlocknumber != UINT32_MAX) revert UpkeepCancelled(); + } + + /** + * @dev replicates Open Zeppelin's ReentrancyGuard but optimized to fit our storage + */ + modifier nonReentrant() { + if (s_hotVars.reentrancyGuard) revert ReentrantCall(); + s_hotVars.reentrancyGuard = true; + _; + s_hotVars.reentrancyGuard = false; + } + + /** + * @notice only allows a pre-configured address to initiate offchain read + */ + function _preventExecution() internal view { + if (tx.origin != i_allowedReadOnlyAddress) { + revert OnlySimulatedBackend(); + } + } +} diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicA2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicA2_3.sol new file mode 100644 index 00000000000..721ea35171e --- /dev/null +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicA2_3.sol @@ -0,0 +1,431 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; +import {AutomationRegistryBase2_3} from "./AutomationRegistryBase2_3.sol"; +import {AutomationRegistryLogicB2_3} from "./AutomationRegistryLogicB2_3.sol"; +import {Chainable} from "../../Chainable.sol"; +import {AutomationForwarder} from "../../AutomationForwarder.sol"; +import {IAutomationForwarder} from "../../interfaces/IAutomationForwarder.sol"; +import {UpkeepTranscoderInterfaceV2} from "../../interfaces/UpkeepTranscoderInterfaceV2.sol"; +import {MigratableKeeperRegistryInterfaceV2} from "../../interfaces/MigratableKeeperRegistryInterfaceV2.sol"; + +/** + * @notice Logic contract, works in tandem with AutomationRegistry as a proxy + */ +contract AutomationRegistryLogicA2_3 is AutomationRegistryBase2_3, Chainable { + using Address for address; + using EnumerableSet for EnumerableSet.UintSet; + using EnumerableSet for EnumerableSet.AddressSet; + + /** + * @param logicB the address of the second logic contract + */ + constructor( + AutomationRegistryLogicB2_3 logicB + ) + AutomationRegistryBase2_3( + logicB.getLinkAddress(), + logicB.getLinkNativeFeedAddress(), + logicB.getFastGasFeedAddress(), + logicB.getAutomationForwarderLogic(), + logicB.getAllowedReadOnlyAddress() + ) + Chainable(address(logicB)) + {} + + /** + * @notice called by the automation DON to check if work is needed + * @param id the upkeep ID to check for work needed + * @param triggerData extra contextual data about the trigger (not used in all code paths) + * @dev this one of the core functions called in the hot path + * @dev there is a 2nd checkUpkeep function (below) that is being maintained for backwards compatibility + * @dev there is an incongruency on what gets returned during failure modes + * ex sometimes we include price data, sometimes we omit it depending on the failure + */ + function checkUpkeep( + uint256 id, + bytes memory triggerData + ) + public + returns ( + bool upkeepNeeded, + bytes memory performData, + UpkeepFailureReason upkeepFailureReason, + uint256 gasUsed, + uint256 gasLimit, + uint256 fastGasWei, + uint256 linkNative + ) + { + _preventExecution(); + + Trigger triggerType = _getTriggerType(id); + HotVars memory hotVars = s_hotVars; + Upkeep memory upkeep = s_upkeep[id]; + + if (hotVars.paused) return (false, bytes(""), UpkeepFailureReason.REGISTRY_PAUSED, 0, upkeep.performGas, 0, 0); + if (upkeep.maxValidBlocknumber != UINT32_MAX) + return (false, bytes(""), UpkeepFailureReason.UPKEEP_CANCELLED, 0, upkeep.performGas, 0, 0); + if (upkeep.paused) return (false, bytes(""), UpkeepFailureReason.UPKEEP_PAUSED, 0, upkeep.performGas, 0, 0); + + (fastGasWei, linkNative) = _getFeedData(hotVars); + uint96 maxLinkPayment = _getMaxLinkPayment(hotVars, triggerType, upkeep.performGas, fastGasWei, linkNative); + if (upkeep.balance < maxLinkPayment) { + return (false, bytes(""), UpkeepFailureReason.INSUFFICIENT_BALANCE, 0, upkeep.performGas, 0, 0); + } + + bytes memory callData = _checkPayload(id, triggerType, triggerData); + + gasUsed = gasleft(); + (bool success, bytes memory result) = upkeep.forwarder.getTarget().call{gas: s_storage.checkGasLimit}(callData); + gasUsed = gasUsed - gasleft(); + + if (!success) { + // User's target check reverted. We capture the revert data here and pass it within performData + if (result.length > s_storage.maxRevertDataSize) { + return ( + false, + bytes(""), + UpkeepFailureReason.REVERT_DATA_EXCEEDS_LIMIT, + gasUsed, + upkeep.performGas, + fastGasWei, + linkNative + ); + } + return ( + upkeepNeeded, + result, + UpkeepFailureReason.TARGET_CHECK_REVERTED, + gasUsed, + upkeep.performGas, + fastGasWei, + linkNative + ); + } + + (upkeepNeeded, performData) = abi.decode(result, (bool, bytes)); + if (!upkeepNeeded) + return ( + false, + bytes(""), + UpkeepFailureReason.UPKEEP_NOT_NEEDED, + gasUsed, + upkeep.performGas, + fastGasWei, + linkNative + ); + + if (performData.length > s_storage.maxPerformDataSize) + return ( + false, + bytes(""), + UpkeepFailureReason.PERFORM_DATA_EXCEEDS_LIMIT, + gasUsed, + upkeep.performGas, + fastGasWei, + linkNative + ); + + return (upkeepNeeded, performData, upkeepFailureReason, gasUsed, upkeep.performGas, fastGasWei, linkNative); + } + + /** + * @notice see other checkUpkeep function for description + * @dev this function may be deprecated in a future version of chainlink automation + */ + function checkUpkeep( + uint256 id + ) + external + returns ( + bool upkeepNeeded, + bytes memory performData, + UpkeepFailureReason upkeepFailureReason, + uint256 gasUsed, + uint256 gasLimit, + uint256 fastGasWei, + uint256 linkNative + ) + { + return checkUpkeep(id, bytes("")); + } + + /** + * @dev checkCallback is used specifically for automation data streams lookups (see StreamsLookupCompatibleInterface.sol) + * @param id the upkeepID to execute a callback for + * @param values the values returned from the data streams lookup + * @param extraData the user-provided extra context data + */ + function checkCallback( + uint256 id, + bytes[] memory values, + bytes calldata extraData + ) + external + returns (bool upkeepNeeded, bytes memory performData, UpkeepFailureReason upkeepFailureReason, uint256 gasUsed) + { + bytes memory payload = abi.encodeWithSelector(CHECK_CALLBACK_SELECTOR, values, extraData); + return executeCallback(id, payload); + } + + /** + * @notice this is a generic callback executor that forwards a call to a user's contract with the configured + * gas limit + * @param id the upkeepID to execute a callback for + * @param payload the data (including function selector) to call on the upkeep target contract + */ + function executeCallback( + uint256 id, + bytes memory payload + ) + public + returns (bool upkeepNeeded, bytes memory performData, UpkeepFailureReason upkeepFailureReason, uint256 gasUsed) + { + _preventExecution(); + + Upkeep memory upkeep = s_upkeep[id]; + gasUsed = gasleft(); + (bool success, bytes memory result) = upkeep.forwarder.getTarget().call{gas: s_storage.checkGasLimit}(payload); + gasUsed = gasUsed - gasleft(); + if (!success) { + return (false, bytes(""), UpkeepFailureReason.CALLBACK_REVERTED, gasUsed); + } + (upkeepNeeded, performData) = abi.decode(result, (bool, bytes)); + if (!upkeepNeeded) { + return (false, bytes(""), UpkeepFailureReason.UPKEEP_NOT_NEEDED, gasUsed); + } + if (performData.length > s_storage.maxPerformDataSize) { + return (false, bytes(""), UpkeepFailureReason.PERFORM_DATA_EXCEEDS_LIMIT, gasUsed); + } + return (upkeepNeeded, performData, upkeepFailureReason, gasUsed); + } + + /** + * @notice adds a new upkeep + * @param target address to perform upkeep on + * @param gasLimit amount of gas to provide the target contract when + * performing upkeep + * @param admin address to cancel upkeep and withdraw remaining funds + * @param triggerType the trigger for the upkeep + * @param checkData data passed to the contract when checking for upkeep + * @param triggerConfig the config for the trigger + * @param offchainConfig arbitrary offchain config for the upkeep + */ + function registerUpkeep( + address target, + uint32 gasLimit, + address admin, + Trigger triggerType, + bytes calldata checkData, + bytes memory triggerConfig, + bytes memory offchainConfig + ) public returns (uint256 id) { + if (msg.sender != owner() && !s_registrars.contains(msg.sender)) revert OnlyCallableByOwnerOrRegistrar(); + if (!target.isContract()) revert NotAContract(); + id = _createID(triggerType); + IAutomationForwarder forwarder = IAutomationForwarder( + address(new AutomationForwarder(target, address(this), i_automationForwarderLogic)) + ); + _createUpkeep( + id, + Upkeep({ + performGas: gasLimit, + balance: 0, + maxValidBlocknumber: UINT32_MAX, + lastPerformedBlockNumber: 0, + amountSpent: 0, + paused: false, + forwarder: forwarder + }), + admin, + checkData, + triggerConfig, + offchainConfig + ); + s_storage.nonce++; + emit UpkeepRegistered(id, gasLimit, admin); + emit UpkeepCheckDataSet(id, checkData); + emit UpkeepTriggerConfigSet(id, triggerConfig); + emit UpkeepOffchainConfigSet(id, offchainConfig); + return (id); + } + + /** + * @notice this function registers a conditional upkeep, using a backwards compatible function signature + * @dev this function is backwards compatible with versions <=2.0, but may be removed in a future version + */ + function registerUpkeep( + address target, + uint32 gasLimit, + address admin, + bytes calldata checkData, + bytes calldata offchainConfig + ) external returns (uint256 id) { + return registerUpkeep(target, gasLimit, admin, Trigger.CONDITION, checkData, bytes(""), offchainConfig); + } + + /** + * @notice cancels an upkeep + * @param id the upkeepID to cancel + * @dev if a user cancels an upkeep, their funds are locked for CANCELLATION_DELAY blocks to + * allow any pending performUpkeep txs time to get confirmed + */ + function cancelUpkeep(uint256 id) external { + Upkeep memory upkeep = s_upkeep[id]; + bool isOwner = msg.sender == owner(); + + uint256 height = s_hotVars.chainModule.blockNumber(); + if (upkeep.maxValidBlocknumber == 0) revert CannotCancel(); + if (upkeep.maxValidBlocknumber != UINT32_MAX) revert UpkeepCancelled(); + if (!isOwner && msg.sender != s_upkeepAdmin[id]) revert OnlyCallableByOwnerOrAdmin(); + + if (!isOwner) { + height = height + CANCELLATION_DELAY; + } + s_upkeep[id].maxValidBlocknumber = uint32(height); + s_upkeepIDs.remove(id); + + // charge the cancellation fee if the minUpkeepSpend is not met + uint96 minUpkeepSpend = s_storage.minUpkeepSpend; + uint96 cancellationFee = 0; + // cancellationFee is supposed to be min(max(minUpkeepSpend - amountSpent,0), amountLeft) + if (upkeep.amountSpent < minUpkeepSpend) { + cancellationFee = minUpkeepSpend - upkeep.amountSpent; + if (cancellationFee > upkeep.balance) { + cancellationFee = upkeep.balance; + } + } + s_upkeep[id].balance = upkeep.balance - cancellationFee; + s_storage.ownerLinkBalance = s_storage.ownerLinkBalance + cancellationFee; + + emit UpkeepCanceled(id, uint64(height)); + } + + /** + * @notice adds fund to an upkeep + * @param id the upkeepID + * @param amount the amount of LINK to fund, in jules (jules = "wei" of LINK) + */ + function addFunds(uint256 id, uint96 amount) external { + Upkeep memory upkeep = s_upkeep[id]; + if (upkeep.maxValidBlocknumber != UINT32_MAX) revert UpkeepCancelled(); + s_upkeep[id].balance = upkeep.balance + amount; + s_expectedLinkBalance = s_expectedLinkBalance + amount; + i_link.transferFrom(msg.sender, address(this), amount); + emit FundsAdded(id, msg.sender, amount); + } + + /** + * @notice migrates upkeeps from one registry to another + * @param ids the upkeepIDs to migrate + * @param destination the destination registry address + * @dev a transcoder must be set in order to enable migration + * @dev migration permissions must be set on *both* sending and receiving registries + * @dev only an upkeep admin can migrate their upkeeps + */ + function migrateUpkeeps(uint256[] calldata ids, address destination) external { + if ( + s_peerRegistryMigrationPermission[destination] != MigrationPermission.OUTGOING && + s_peerRegistryMigrationPermission[destination] != MigrationPermission.BIDIRECTIONAL + ) revert MigrationNotPermitted(); + if (s_storage.transcoder == ZERO_ADDRESS) revert TranscoderNotSet(); + if (ids.length == 0) revert ArrayHasNoEntries(); + uint256 id; + Upkeep memory upkeep; + uint256 totalBalanceRemaining; + address[] memory admins = new address[](ids.length); + Upkeep[] memory upkeeps = new Upkeep[](ids.length); + bytes[] memory checkDatas = new bytes[](ids.length); + bytes[] memory triggerConfigs = new bytes[](ids.length); + bytes[] memory offchainConfigs = new bytes[](ids.length); + for (uint256 idx = 0; idx < ids.length; idx++) { + id = ids[idx]; + upkeep = s_upkeep[id]; + _requireAdminAndNotCancelled(id); + upkeep.forwarder.updateRegistry(destination); + upkeeps[idx] = upkeep; + admins[idx] = s_upkeepAdmin[id]; + checkDatas[idx] = s_checkData[id]; + triggerConfigs[idx] = s_upkeepTriggerConfig[id]; + offchainConfigs[idx] = s_upkeepOffchainConfig[id]; + totalBalanceRemaining = totalBalanceRemaining + upkeep.balance; + delete s_upkeep[id]; + delete s_checkData[id]; + delete s_upkeepTriggerConfig[id]; + delete s_upkeepOffchainConfig[id]; + // nullify existing proposed admin change if an upkeep is being migrated + delete s_proposedAdmin[id]; + s_upkeepIDs.remove(id); + emit UpkeepMigrated(id, upkeep.balance, destination); + } + s_expectedLinkBalance = s_expectedLinkBalance - totalBalanceRemaining; + bytes memory encodedUpkeeps = abi.encode( + ids, + upkeeps, + new address[](ids.length), + admins, + checkDatas, + triggerConfigs, + offchainConfigs + ); + MigratableKeeperRegistryInterfaceV2(destination).receiveUpkeeps( + UpkeepTranscoderInterfaceV2(s_storage.transcoder).transcodeUpkeeps( + UPKEEP_VERSION_BASE, + MigratableKeeperRegistryInterfaceV2(destination).upkeepVersion(), + encodedUpkeeps + ) + ); + i_link.transfer(destination, totalBalanceRemaining); + } + + /** + * @notice received upkeeps migrated from another registry + * @param encodedUpkeeps the raw upkeep data to import + * @dev this function is never called directly, it is only called by another registry's migrate function + */ + function receiveUpkeeps(bytes calldata encodedUpkeeps) external { + if ( + s_peerRegistryMigrationPermission[msg.sender] != MigrationPermission.INCOMING && + s_peerRegistryMigrationPermission[msg.sender] != MigrationPermission.BIDIRECTIONAL + ) revert MigrationNotPermitted(); + ( + uint256[] memory ids, + Upkeep[] memory upkeeps, + address[] memory targets, + address[] memory upkeepAdmins, + bytes[] memory checkDatas, + bytes[] memory triggerConfigs, + bytes[] memory offchainConfigs + ) = abi.decode(encodedUpkeeps, (uint256[], Upkeep[], address[], address[], bytes[], bytes[], bytes[])); + for (uint256 idx = 0; idx < ids.length; idx++) { + if (address(upkeeps[idx].forwarder) == ZERO_ADDRESS) { + upkeeps[idx].forwarder = IAutomationForwarder( + address(new AutomationForwarder(targets[idx], address(this), i_automationForwarderLogic)) + ); + } + _createUpkeep( + ids[idx], + upkeeps[idx], + upkeepAdmins[idx], + checkDatas[idx], + triggerConfigs[idx], + offchainConfigs[idx] + ); + emit UpkeepReceived(ids[idx], upkeeps[idx].balance, msg.sender); + } + } + + /** + * @notice sets the upkeep trigger config + * @param id the upkeepID to change the trigger for + * @param triggerConfig the new trigger config + */ + function setUpkeepTriggerConfig(uint256 id, bytes calldata triggerConfig) external { + _requireAdminAndNotCancelled(id); + s_upkeepTriggerConfig[id] = triggerConfig; + emit UpkeepTriggerConfigSet(id, triggerConfig); + } +} diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicB2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicB2_3.sol new file mode 100644 index 00000000000..1f8655967cf --- /dev/null +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicB2_3.sol @@ -0,0 +1,539 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +import {AutomationRegistryBase2_3} from "./AutomationRegistryBase2_3.sol"; +import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; +import {UpkeepFormat} from "../../interfaces/UpkeepTranscoderInterface.sol"; +import {IAutomationForwarder} from "../../interfaces/IAutomationForwarder.sol"; +import {IChainModule} from "../interfaces/IChainModule.sol"; + +contract AutomationRegistryLogicB2_3 is AutomationRegistryBase2_3 { + using Address for address; + using EnumerableSet for EnumerableSet.UintSet; + using EnumerableSet for EnumerableSet.AddressSet; + + /** + * @dev see AutomationRegistry master contract for constructor description + */ + constructor( + address link, + address linkNativeFeed, + address fastGasFeed, + address automationForwarderLogic, + address allowedReadOnlyAddress + ) AutomationRegistryBase2_3(link, linkNativeFeed, fastGasFeed, automationForwarderLogic, allowedReadOnlyAddress) {} + + // ================================================================ + // | UPKEEP MANAGEMENT | + // ================================================================ + + /** + * @notice transfers the address of an admin for an upkeep + */ + function transferUpkeepAdmin(uint256 id, address proposed) external { + _requireAdminAndNotCancelled(id); + if (proposed == msg.sender) revert ValueNotChanged(); + + if (s_proposedAdmin[id] != proposed) { + s_proposedAdmin[id] = proposed; + emit UpkeepAdminTransferRequested(id, msg.sender, proposed); + } + } + + /** + * @notice accepts the transfer of an upkeep admin + */ + function acceptUpkeepAdmin(uint256 id) external { + Upkeep memory upkeep = s_upkeep[id]; + if (upkeep.maxValidBlocknumber != UINT32_MAX) revert UpkeepCancelled(); + if (s_proposedAdmin[id] != msg.sender) revert OnlyCallableByProposedAdmin(); + address past = s_upkeepAdmin[id]; + s_upkeepAdmin[id] = msg.sender; + s_proposedAdmin[id] = ZERO_ADDRESS; + + emit UpkeepAdminTransferred(id, past, msg.sender); + } + + /** + * @notice pauses an upkeep - an upkeep will be neither checked nor performed while paused + */ + function pauseUpkeep(uint256 id) external { + _requireAdminAndNotCancelled(id); + Upkeep memory upkeep = s_upkeep[id]; + if (upkeep.paused) revert OnlyUnpausedUpkeep(); + s_upkeep[id].paused = true; + s_upkeepIDs.remove(id); + emit UpkeepPaused(id); + } + + /** + * @notice unpauses an upkeep + */ + function unpauseUpkeep(uint256 id) external { + _requireAdminAndNotCancelled(id); + Upkeep memory upkeep = s_upkeep[id]; + if (!upkeep.paused) revert OnlyPausedUpkeep(); + s_upkeep[id].paused = false; + s_upkeepIDs.add(id); + emit UpkeepUnpaused(id); + } + + /** + * @notice updates the checkData for an upkeep + */ + function setUpkeepCheckData(uint256 id, bytes calldata newCheckData) external { + _requireAdminAndNotCancelled(id); + if (newCheckData.length > s_storage.maxCheckDataSize) revert CheckDataExceedsLimit(); + s_checkData[id] = newCheckData; + emit UpkeepCheckDataSet(id, newCheckData); + } + + /** + * @notice updates the gas limit for an upkeep + */ + function setUpkeepGasLimit(uint256 id, uint32 gasLimit) external { + if (gasLimit < PERFORM_GAS_MIN || gasLimit > s_storage.maxPerformGas) revert GasLimitOutsideRange(); + _requireAdminAndNotCancelled(id); + s_upkeep[id].performGas = gasLimit; + + emit UpkeepGasLimitSet(id, gasLimit); + } + + /** + * @notice updates the offchain config for an upkeep + */ + function setUpkeepOffchainConfig(uint256 id, bytes calldata config) external { + _requireAdminAndNotCancelled(id); + s_upkeepOffchainConfig[id] = config; + emit UpkeepOffchainConfigSet(id, config); + } + + /** + * @notice withdraws LINK funds from an upkeep + * @dev note that an upkeep must be cancelled first!! + */ + function withdrawFunds(uint256 id, address to) external nonReentrant { + if (to == ZERO_ADDRESS) revert InvalidRecipient(); + Upkeep memory upkeep = s_upkeep[id]; + if (s_upkeepAdmin[id] != msg.sender) revert OnlyCallableByAdmin(); + if (upkeep.maxValidBlocknumber > s_hotVars.chainModule.blockNumber()) revert UpkeepNotCanceled(); + uint96 amountToWithdraw = s_upkeep[id].balance; + s_expectedLinkBalance = s_expectedLinkBalance - amountToWithdraw; + s_upkeep[id].balance = 0; + i_link.transfer(to, amountToWithdraw); + emit FundsWithdrawn(id, amountToWithdraw, to); + } + + // ================================================================ + // | NODE MANAGEMENT | + // ================================================================ + + /** + * @notice transfers the address of payee for a transmitter + */ + function transferPayeeship(address transmitter, address proposed) external { + if (s_transmitterPayees[transmitter] != msg.sender) revert OnlyCallableByPayee(); + if (proposed == msg.sender) revert ValueNotChanged(); + + if (s_proposedPayee[transmitter] != proposed) { + s_proposedPayee[transmitter] = proposed; + emit PayeeshipTransferRequested(transmitter, msg.sender, proposed); + } + } + + /** + * @notice accepts the transfer of the payee + */ + function acceptPayeeship(address transmitter) external { + if (s_proposedPayee[transmitter] != msg.sender) revert OnlyCallableByProposedPayee(); + address past = s_transmitterPayees[transmitter]; + s_transmitterPayees[transmitter] = msg.sender; + s_proposedPayee[transmitter] = ZERO_ADDRESS; + + emit PayeeshipTransferred(transmitter, past, msg.sender); + } + + /** + * @notice withdraws LINK received as payment for work performed + */ + function withdrawPayment(address from, address to) external { + if (to == ZERO_ADDRESS) revert InvalidRecipient(); + if (s_transmitterPayees[from] != msg.sender) revert OnlyCallableByPayee(); + uint96 balance = _updateTransmitterBalanceFromPool(from, s_hotVars.totalPremium, uint96(s_transmittersList.length)); + s_transmitters[from].balance = 0; + s_expectedLinkBalance = s_expectedLinkBalance - balance; + i_link.transfer(to, balance); + emit PaymentWithdrawn(from, balance, to, msg.sender); + } + + // ================================================================ + // | OWNER / MANAGER ACTIONS | + // ================================================================ + + /** + * @notice sets the privilege config for an upkeep + */ + function setUpkeepPrivilegeConfig(uint256 upkeepId, bytes calldata newPrivilegeConfig) external { + if (msg.sender != s_storage.upkeepPrivilegeManager) { + revert OnlyCallableByUpkeepPrivilegeManager(); + } + s_upkeepPrivilegeConfig[upkeepId] = newPrivilegeConfig; + emit UpkeepPrivilegeConfigSet(upkeepId, newPrivilegeConfig); + } + + /** + * @notice withdraws the owner's LINK balance + */ + function withdrawOwnerFunds() external onlyOwner { + uint96 amount = s_storage.ownerLinkBalance; + s_expectedLinkBalance = s_expectedLinkBalance - amount; + s_storage.ownerLinkBalance = 0; + emit OwnerFundsWithdrawn(amount); + i_link.transfer(msg.sender, amount); + } + + /** + * @notice allows the owner to withdraw any LINK accidentally sent to the contract + */ + function recoverFunds() external onlyOwner { + uint256 total = i_link.balanceOf(address(this)); + i_link.transfer(msg.sender, total - s_expectedLinkBalance); + } + + /** + * @notice sets the payees for the transmitters + */ + function setPayees(address[] calldata payees) external onlyOwner { + if (s_transmittersList.length != payees.length) revert ParameterLengthError(); + for (uint256 i = 0; i < s_transmittersList.length; i++) { + address transmitter = s_transmittersList[i]; + address oldPayee = s_transmitterPayees[transmitter]; + address newPayee = payees[i]; + if ( + (newPayee == ZERO_ADDRESS) || (oldPayee != ZERO_ADDRESS && oldPayee != newPayee && newPayee != IGNORE_ADDRESS) + ) revert InvalidPayee(); + if (newPayee != IGNORE_ADDRESS) { + s_transmitterPayees[transmitter] = newPayee; + } + } + emit PayeesUpdated(s_transmittersList, payees); + } + + /** + * @notice sets the migration permission for a peer registry + * @dev this must be done before upkeeps can be migrated to/from another registry + */ + function setPeerRegistryMigrationPermission(address peer, MigrationPermission permission) external onlyOwner { + s_peerRegistryMigrationPermission[peer] = permission; + } + + /** + * @notice pauses the entire registry + */ + function pause() external onlyOwner { + s_hotVars.paused = true; + emit Paused(msg.sender); + } + + /** + * @notice unpauses the entire registry + */ + function unpause() external onlyOwner { + s_hotVars.paused = false; + emit Unpaused(msg.sender); + } + + /** + * @notice sets a generic bytes field used to indicate the privilege that this admin address had + * @param admin the address to set privilege for + * @param newPrivilegeConfig the privileges that this admin has + */ + function setAdminPrivilegeConfig(address admin, bytes calldata newPrivilegeConfig) external { + if (msg.sender != s_storage.upkeepPrivilegeManager) { + revert OnlyCallableByUpkeepPrivilegeManager(); + } + s_adminPrivilegeConfig[admin] = newPrivilegeConfig; + emit AdminPrivilegeConfigSet(admin, newPrivilegeConfig); + } + + // ================================================================ + // | GETTERS | + // ================================================================ + + function getConditionalGasOverhead() external pure returns (uint256) { + return REGISTRY_CONDITIONAL_OVERHEAD; + } + + function getLogGasOverhead() external pure returns (uint256) { + return REGISTRY_LOG_OVERHEAD; + } + + function getPerPerformByteGasOverhead() external pure returns (uint256) { + return REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD; + } + + function getPerSignerGasOverhead() external pure returns (uint256) { + return REGISTRY_PER_SIGNER_GAS_OVERHEAD; + } + + function getTransmitCalldataFixedBytesOverhead() external pure returns (uint256) { + return TRANSMIT_CALLDATA_FIXED_BYTES_OVERHEAD; + } + + function getTransmitCalldataPerSignerBytesOverhead() external pure returns (uint256) { + return TRANSMIT_CALLDATA_PER_SIGNER_BYTES_OVERHEAD; + } + + function getCancellationDelay() external pure returns (uint256) { + return CANCELLATION_DELAY; + } + + function getLinkAddress() external view returns (address) { + return address(i_link); + } + + function getLinkNativeFeedAddress() external view returns (address) { + return address(i_linkNativeFeed); + } + + function getFastGasFeedAddress() external view returns (address) { + return address(i_fastGasFeed); + } + + function getAutomationForwarderLogic() external view returns (address) { + return i_automationForwarderLogic; + } + + function getAllowedReadOnlyAddress() external view returns (address) { + return i_allowedReadOnlyAddress; + } + + function upkeepTranscoderVersion() public pure returns (UpkeepFormat) { + return UPKEEP_TRANSCODER_VERSION_BASE; + } + + function upkeepVersion() public pure returns (uint8) { + return UPKEEP_VERSION_BASE; + } + + /** + * @notice read all of the details about an upkeep + * @dev this function may be deprecated in a future version of automation in favor of individual + * getters for each field + */ + function getUpkeep(uint256 id) external view returns (UpkeepInfo memory upkeepInfo) { + Upkeep memory reg = s_upkeep[id]; + address target = address(reg.forwarder) == address(0) ? address(0) : reg.forwarder.getTarget(); + upkeepInfo = UpkeepInfo({ + target: target, + performGas: reg.performGas, + checkData: s_checkData[id], + balance: reg.balance, + admin: s_upkeepAdmin[id], + maxValidBlocknumber: reg.maxValidBlocknumber, + lastPerformedBlockNumber: reg.lastPerformedBlockNumber, + amountSpent: reg.amountSpent, + paused: reg.paused, + offchainConfig: s_upkeepOffchainConfig[id] + }); + return upkeepInfo; + } + + /** + * @notice retrieve active upkeep IDs. Active upkeep is defined as an upkeep which is not paused and not canceled. + * @param startIndex starting index in list + * @param maxCount max count to retrieve (0 = unlimited) + * @dev the order of IDs in the list is **not guaranteed**, therefore, if making successive calls, one + * should consider keeping the blockheight constant to ensure a holistic picture of the contract state + */ + function getActiveUpkeepIDs(uint256 startIndex, uint256 maxCount) external view returns (uint256[] memory) { + uint256 numUpkeeps = s_upkeepIDs.length(); + if (startIndex >= numUpkeeps) revert IndexOutOfRange(); + uint256 endIndex = startIndex + maxCount; + endIndex = endIndex > numUpkeeps || maxCount == 0 ? numUpkeeps : endIndex; + uint256[] memory ids = new uint256[](endIndex - startIndex); + for (uint256 idx = 0; idx < ids.length; idx++) { + ids[idx] = s_upkeepIDs.at(idx + startIndex); + } + return ids; + } + + /** + * @notice returns the upkeep's trigger type + */ + function getTriggerType(uint256 upkeepId) external pure returns (Trigger) { + return _getTriggerType(upkeepId); + } + + /** + * @notice returns the trigger config for an upkeeep + */ + function getUpkeepTriggerConfig(uint256 upkeepId) public view returns (bytes memory) { + return s_upkeepTriggerConfig[upkeepId]; + } + + /** + * @notice read the current info about any transmitter address + */ + function getTransmitterInfo( + address query + ) external view returns (bool active, uint8 index, uint96 balance, uint96 lastCollected, address payee) { + Transmitter memory transmitter = s_transmitters[query]; + + uint96 pooledShare = 0; + if (transmitter.active) { + uint96 totalDifference = s_hotVars.totalPremium - transmitter.lastCollected; + pooledShare = totalDifference / uint96(s_transmittersList.length); + } + + return ( + transmitter.active, + transmitter.index, + (transmitter.balance + pooledShare), + transmitter.lastCollected, + s_transmitterPayees[query] + ); + } + + /** + * @notice read the current info about any signer address + */ + function getSignerInfo(address query) external view returns (bool active, uint8 index) { + Signer memory signer = s_signers[query]; + return (signer.active, signer.index); + } + + /** + * @notice read the current state of the registry + * @dev this function is deprecated + */ + function getState() + external + view + returns ( + State memory state, + OnchainConfigLegacy memory config, + address[] memory signers, + address[] memory transmitters, + uint8 f + ) + { + state = State({ + nonce: s_storage.nonce, + ownerLinkBalance: s_storage.ownerLinkBalance, + expectedLinkBalance: s_expectedLinkBalance, + totalPremium: s_hotVars.totalPremium, + numUpkeeps: s_upkeepIDs.length(), + configCount: s_storage.configCount, + latestConfigBlockNumber: s_storage.latestConfigBlockNumber, + latestConfigDigest: s_latestConfigDigest, + latestEpoch: s_hotVars.latestEpoch, + paused: s_hotVars.paused + }); + + config = OnchainConfigLegacy({ + paymentPremiumPPB: s_hotVars.paymentPremiumPPB, + flatFeeMicroLink: s_hotVars.flatFeeMicroLink, + checkGasLimit: s_storage.checkGasLimit, + stalenessSeconds: s_hotVars.stalenessSeconds, + gasCeilingMultiplier: s_hotVars.gasCeilingMultiplier, + minUpkeepSpend: s_storage.minUpkeepSpend, + maxPerformGas: s_storage.maxPerformGas, + maxCheckDataSize: s_storage.maxCheckDataSize, + maxPerformDataSize: s_storage.maxPerformDataSize, + maxRevertDataSize: s_storage.maxRevertDataSize, + fallbackGasPrice: s_fallbackGasPrice, + fallbackLinkPrice: s_fallbackLinkPrice, + transcoder: s_storage.transcoder, + registrars: s_registrars.values(), + upkeepPrivilegeManager: s_storage.upkeepPrivilegeManager + }); + + return (state, config, s_signersList, s_transmittersList, s_hotVars.f); + } + + /** + * @notice get the chain module + */ + function getChainModule() external view returns (IChainModule chainModule) { + return s_hotVars.chainModule; + } + + /** + * @notice if this registry has reorg protection enabled + */ + function getReorgProtectionEnabled() external view returns (bool reorgProtectionEnabled) { + return s_hotVars.reorgProtectionEnabled; + } + + /** + * @notice calculates the minimum balance required for an upkeep to remain eligible + * @param id the upkeep id to calculate minimum balance for + */ + function getBalance(uint256 id) external view returns (uint96 balance) { + return s_upkeep[id].balance; + } + + /** + * @notice calculates the minimum balance required for an upkeep to remain eligible + * @param id the upkeep id to calculate minimum balance for + */ + function getMinBalance(uint256 id) external view returns (uint96) { + return getMinBalanceForUpkeep(id); + } + + /** + * @notice calculates the minimum balance required for an upkeep to remain eligible + * @param id the upkeep id to calculate minimum balance for + * @dev this will be deprecated in a future version in favor of getMinBalance + */ + function getMinBalanceForUpkeep(uint256 id) public view returns (uint96 minBalance) { + return getMaxPaymentForGas(_getTriggerType(id), s_upkeep[id].performGas); + } + + /** + * @notice calculates the maximum payment for a given gas limit + * @param gasLimit the gas to calculate payment for + */ + function getMaxPaymentForGas(Trigger triggerType, uint32 gasLimit) public view returns (uint96 maxPayment) { + HotVars memory hotVars = s_hotVars; + (uint256 fastGasWei, uint256 linkNative) = _getFeedData(hotVars); + return _getMaxLinkPayment(hotVars, triggerType, gasLimit, fastGasWei, linkNative); + } + + /** + * @notice retrieves the migration permission for a peer registry + */ + function getPeerRegistryMigrationPermission(address peer) external view returns (MigrationPermission) { + return s_peerRegistryMigrationPermission[peer]; + } + + /** + * @notice returns the upkeep privilege config + */ + function getUpkeepPrivilegeConfig(uint256 upkeepId) external view returns (bytes memory) { + return s_upkeepPrivilegeConfig[upkeepId]; + } + + /** + * @notice returns the upkeep privilege config + */ + function getAdminPrivilegeConfig(address admin) external view returns (bytes memory) { + return s_adminPrivilegeConfig[admin]; + } + + /** + * @notice returns the upkeep's forwarder contract + */ + function getForwarder(uint256 upkeepID) external view returns (IAutomationForwarder) { + return s_upkeep[upkeepID].forwarder; + } + + /** + * @notice returns the upkeep's forwarder contract + */ + function hasDedupKey(bytes32 dedupKey) external view returns (bool) { + return s_dedupKeys[dedupKey]; + } +} diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationUtils2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationUtils2_3.sol new file mode 100644 index 00000000000..70794339bc3 --- /dev/null +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationUtils2_3.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +import {AutomationRegistryBase2_3} from "./AutomationRegistryBase2_3.sol"; +import {Log} from "../../interfaces/ILogAutomation.sol"; + +/** + * @notice this file exposes structs that are otherwise internal to the automation registry + * doing this allows those structs to be encoded and decoded with type safety in offchain code + * and tests because generated wrappers are made available + */ + +/** + * @notice structure of trigger for log triggers + */ +struct LogTriggerConfig { + address contractAddress; + uint8 filterSelector; // denotes which topics apply to filter ex 000, 101, 111...only last 3 bits apply + bytes32 topic0; + bytes32 topic1; + bytes32 topic2; + bytes32 topic3; +} + +contract AutomationUtils2_3 { + /** + * @dev this can be removed as OnchainConfig is now exposed directly from the registry + */ + function _onChainConfig(AutomationRegistryBase2_3.OnchainConfig memory) external {} // 0x2ff92a81 + + function _report(AutomationRegistryBase2_3.Report memory) external {} // 0xe65d6546 + + function _logTriggerConfig(LogTriggerConfig memory) external {} // 0x21f373d7 + + function _logTrigger(AutomationRegistryBase2_3.LogTrigger memory) external {} // 0x1c8d8260 + + function _conditionalTrigger(AutomationRegistryBase2_3.ConditionalTrigger memory) external {} // 0x4b6df294 + + function _log(Log memory) external {} // 0xe9720a49 +} diff --git a/contracts/src/v0.8/automation/dev/v2_3/LICENSE b/contracts/src/v0.8/automation/dev/v2_3/LICENSE new file mode 100644 index 00000000000..515985ac0a7 --- /dev/null +++ b/contracts/src/v0.8/automation/dev/v2_3/LICENSE @@ -0,0 +1,57 @@ +Business Source License 1.1 + +License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved. +"Business Source License" is a trademark of MariaDB Corporation Ab. + +--- + +Parameters + +Licensor: SmartContract Chainlink Limited SEZC + +Licensed Work: Automation v2.3 +The Licensed Work is (c) 2024 SmartContract Chainlink Limited SEZC + +Additional Use Grant(s): +You may make use of Automation v2.1, v2.2, v2.3 (which is available subject to the license here the “Licensed Work”) solely for purposes listed below: +https://github.com/smartcontractkit/chainlink-automation/tree/main/Automation_Grants.md + +Change Date: March 1, 2024 + +Change License: MIT + +--- + +Terms + +The Licensor hereby grants you the right to copy, modify, create derivative works, redistribute, and make non-production use of the Licensed Work. The Licensor may make an Additional Use Grant, above, permitting limited production use. + +Effective on the Change Date, or the fourth anniversary of the first publicly available distribution of a specific version of the Licensed Work under this License, whichever comes first, the Licensor hereby grants you rights under the terms of the Change License, and the rights granted in the paragraph above terminate. + +If your use of the Licensed Work does not comply with the requirements currently in effect as described in this License, you must purchase a commercial license from the Licensor, its affiliated entities, or authorized resellers, or you must refrain from using the Licensed Work. + +All copies of the original and modified Licensed Work, and derivative works of the Licensed Work, are subject to this License. This License applies separately for each version of the Licensed Work and the Change Date may vary for each version of the Licensed Work released by Licensor. + +You must conspicuously display this License on each original or modified copy of the Licensed Work. If you receive the Licensed Work in original or modified form from a third party, the terms and conditions set forth in this License apply to your use of that work. + +Any use of the Licensed Work in violation of this License will automatically terminate your rights under this License for the current and all other versions of the Licensed Work. + +This License does not grant you any right in any trademark or logo of Licensor or its affiliates (provided that you may use a trademark or logo of Licensor as expressly required by this License). + +TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE. + +MariaDB hereby grants you permission to use this License’s text to license your works, and to refer to it using the trademark "Business Source License", as long as you comply with the Covenants of Licensor below. + +--- + +Covenants of Licensor + +In consideration of the right to use this License’s text and the "Business Source License" name and trademark, Licensor covenants to MariaDB, and to all other recipients of the licensed work to be provided by Licensor: + +1. To specify as the Change License the GPL Version 2.0 or any later version, or a license that is compatible with GPL Version 2.0 or a later version, where "compatible" means that software provided under the Change License can be included in a program with software provided under GPL Version 2.0 or a later version. Licensor may specify additional Change Licenses without limitation. + +2. To either: (a) specify an additional grant of rights to use that does not impose any additional restriction on the right granted in this License, as the Additional Use Grant; or (b) insert the text "None". + +3. To specify a Change Date. + +4. Not to modify this License in any other way. \ No newline at end of file diff --git a/contracts/test/v0.8/automation/AutomationRegistrar2_3.test.ts b/contracts/test/v0.8/automation/AutomationRegistrar2_3.test.ts new file mode 100644 index 00000000000..91a192e0d0c --- /dev/null +++ b/contracts/test/v0.8/automation/AutomationRegistrar2_3.test.ts @@ -0,0 +1,1026 @@ +import { ethers } from 'hardhat' +import { ContractFactory, Contract } from 'ethers' +import { assert, expect } from 'chai' +import { evmRevert } from '../../test-helpers/matchers' +import { getUsers, Personas } from '../../test-helpers/setup' +import { BigNumber, Signer } from 'ethers' +import { MockV3Aggregator__factory as MockV3AggregatorFactory } from '../../../typechain/factories/MockV3Aggregator__factory' +import { UpkeepMock__factory as UpkeepMockFactory } from '../../../typechain/factories/UpkeepMock__factory' +import { ChainModuleBase__factory as ChainModuleBaseFactory } from '../../../typechain/factories/ChainModuleBase__factory' +import { MockV3Aggregator } from '../../../typechain/MockV3Aggregator' +import { UpkeepMock } from '../../../typechain/UpkeepMock' +import { toWei } from '../../test-helpers/helpers' +import { ChainModuleBase } from '../../../typechain/ChainModuleBase' +import { AutomationRegistrar2_3 as Registrar } from '../../../typechain/AutomationRegistrar2_3' +import { deployRegistry23 } from './helpers' +import { + // AutomationRegistryLogicB2_2__factory as AutomationRegistryLogicBFactory, + IAutomationRegistryMaster as IAutomationRegistry, +} from '../../../typechain' + +// copied from KeeperRegistryBase2_3.sol +enum Trigger { + CONDITION, + LOG, +} +const zeroAddress = ethers.constants.AddressZero + +let linkTokenFactory: ContractFactory +let mockV3AggregatorFactory: MockV3AggregatorFactory +let upkeepMockFactory: UpkeepMockFactory + +let personas: Personas + +before(async () => { + personas = (await getUsers()).personas + + linkTokenFactory = await ethers.getContractFactory( + 'src/v0.4/LinkToken.sol:LinkToken', + ) + mockV3AggregatorFactory = (await ethers.getContractFactory( + 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', + )) as unknown as MockV3AggregatorFactory + upkeepMockFactory = await ethers.getContractFactory('UpkeepMock') +}) + +const errorMsgs = { + onlyOwner: 'revert Only callable by owner', + onlyAdmin: 'OnlyAdminOrOwner()', + hashPayload: 'HashMismatch()', + requestNotFound: 'RequestNotFound()', +} + +describe('AutomationRegistrar2_3', () => { + const upkeepName = 'SampleUpkeep' + + const linkEth = BigNumber.from(300000000) + const gasWei = BigNumber.from(100) + const performGas = BigNumber.from(100000) + const paymentPremiumPPB = BigNumber.from(250000000) + const flatFeeMicroLink = BigNumber.from(0) + const maxAllowedAutoApprove = 5 + const trigger = '0xdeadbeef' + const offchainConfig = '0x01234567' + + const emptyBytes = '0x00' + const stalenessSeconds = BigNumber.from(43820) + const gasCeilingMultiplier = BigNumber.from(1) + const checkGasLimit = BigNumber.from(20000000) + const fallbackGasPrice = BigNumber.from(200) + const fallbackLinkPrice = BigNumber.from(200000000) + const maxCheckDataSize = BigNumber.from(10000) + const maxPerformDataSize = BigNumber.from(10000) + const maxRevertDataSize = BigNumber.from(1000) + const maxPerformGas = BigNumber.from(5000000) + const minUpkeepSpend = BigNumber.from('1000000000000000000') + const amount = BigNumber.from('5000000000000000000') + const amount1 = BigNumber.from('6000000000000000000') + const transcoder = ethers.constants.AddressZero + const upkeepManager = ethers.Wallet.createRandom().address + + // Enum values are not auto exported in ABI so have to manually declare + const autoApproveType_DISABLED = 0 + const autoApproveType_ENABLED_SENDER_ALLOWLIST = 1 + const autoApproveType_ENABLED_ALL = 2 + + let owner: Signer + let admin: Signer + let someAddress: Signer + let registrarOwner: Signer + let stranger: Signer + let requestSender: Signer + + let linkToken: Contract + let linkEthFeed: MockV3Aggregator + let gasPriceFeed: MockV3Aggregator + let mock: UpkeepMock + let registry: IAutomationRegistry + let registrar: Registrar + let chainModuleBase: ChainModuleBase + let chainModuleBaseFactory: ChainModuleBaseFactory + + beforeEach(async () => { + owner = personas.Default + admin = personas.Neil + someAddress = personas.Ned + registrarOwner = personas.Nelly + stranger = personas.Nancy + requestSender = personas.Norbert + + linkToken = await linkTokenFactory.connect(owner).deploy() + gasPriceFeed = await mockV3AggregatorFactory + .connect(owner) + .deploy(0, gasWei) + linkEthFeed = await mockV3AggregatorFactory + .connect(owner) + .deploy(9, linkEth) + + chainModuleBaseFactory = await ethers.getContractFactory('ChainModuleBase') + chainModuleBase = await chainModuleBaseFactory.connect(owner).deploy() + + registry = await deployRegistry23( + owner, + linkToken.address, + linkEthFeed.address, + gasPriceFeed.address, + zeroAddress, + ) + + mock = await upkeepMockFactory.deploy() + + const registrarFactory = await ethers.getContractFactory( + 'AutomationRegistrar2_3', + ) + registrar = await registrarFactory + .connect(registrarOwner) + .deploy(linkToken.address, registry.address, minUpkeepSpend, [ + { + triggerType: Trigger.CONDITION, + autoApproveType: autoApproveType_DISABLED, + autoApproveMaxAllowed: 0, + }, + { + triggerType: Trigger.LOG, + autoApproveType: autoApproveType_DISABLED, + autoApproveMaxAllowed: 0, + }, + ]) + + await linkToken + .connect(owner) + .transfer(await requestSender.getAddress(), toWei('1000')) + + const keepers = [ + await personas.Carol.getAddress(), + await personas.Nancy.getAddress(), + await personas.Ned.getAddress(), + await personas.Neil.getAddress(), + ] + const onchainConfig = { + paymentPremiumPPB, + flatFeeMicroLink, + checkGasLimit, + stalenessSeconds, + gasCeilingMultiplier, + minUpkeepSpend, + maxCheckDataSize, + maxPerformDataSize, + maxRevertDataSize, + maxPerformGas, + fallbackGasPrice, + fallbackLinkPrice, + transcoder, + registrars: [registrar.address], + upkeepPrivilegeManager: upkeepManager, + chainModule: chainModuleBase.address, + reorgProtectionEnabled: true, + } + await registry + .connect(owner) + .setConfigTypeSafe(keepers, keepers, 1, onchainConfig, 1, '0x') + }) + + describe('#typeAndVersion', () => { + it('uses the correct type and version', async () => { + const typeAndVersion = await registrar.typeAndVersion() + assert.equal(typeAndVersion, 'AutomationRegistrar 2.3.0') + }) + }) + + describe('#register', () => { + it('reverts if not called by the LINK token', async () => { + await evmRevert( + registrar + .connect(someAddress) + .register( + upkeepName, + emptyBytes, + mock.address, + performGas, + await admin.getAddress(), + 0, + emptyBytes, + trigger, + offchainConfig, + amount, + await requestSender.getAddress(), + ), + 'OnlyLink()', + ) + }) + + it('reverts if the amount passed in data mismatches actual amount sent', async () => { + await registrar + .connect(registrarOwner) + .setTriggerConfig( + Trigger.CONDITION, + autoApproveType_ENABLED_ALL, + maxAllowedAutoApprove, + ) + + const abiEncodedBytes = registrar.interface.encodeFunctionData( + 'register', + [ + upkeepName, + emptyBytes, + mock.address, + performGas, + await admin.getAddress(), + 0, + emptyBytes, + trigger, + offchainConfig, + amount1, + await requestSender.getAddress(), + ], + ) + + await evmRevert( + linkToken + .connect(requestSender) + .transferAndCall(registrar.address, amount, abiEncodedBytes), + 'AmountMismatch()', + ) + }) + + it('reverts if the sender passed in data mismatches actual sender', async () => { + const abiEncodedBytes = registrar.interface.encodeFunctionData( + 'register', + [ + upkeepName, + emptyBytes, + mock.address, + performGas, + await admin.getAddress(), + 0, + emptyBytes, + trigger, + offchainConfig, + amount, + await admin.getAddress(), // Should have been requestSender.getAddress() + ], + ) + await evmRevert( + linkToken + .connect(requestSender) + .transferAndCall(registrar.address, amount, abiEncodedBytes), + 'SenderMismatch()', + ) + }) + + it('reverts if the admin address is 0x0000...', async () => { + const abiEncodedBytes = registrar.interface.encodeFunctionData( + 'register', + [ + upkeepName, + emptyBytes, + mock.address, + performGas, + '0x0000000000000000000000000000000000000000', + 0, + emptyBytes, + trigger, + offchainConfig, + amount, + await requestSender.getAddress(), + ], + ) + + await evmRevert( + linkToken + .connect(requestSender) + .transferAndCall(registrar.address, amount, abiEncodedBytes), + 'RegistrationRequestFailed()', + ) + }) + + it('Auto Approve ON - registers an upkeep on KeeperRegistry instantly and emits both RegistrationRequested and RegistrationApproved events', async () => { + //set auto approve ON with high threshold limits + await registrar + .connect(registrarOwner) + .setTriggerConfig( + Trigger.CONDITION, + autoApproveType_ENABLED_ALL, + maxAllowedAutoApprove, + ) + + //register with auto approve ON + const abiEncodedBytes = registrar.interface.encodeFunctionData( + 'register', + [ + upkeepName, + emptyBytes, + mock.address, + performGas, + await admin.getAddress(), + 0, + emptyBytes, + trigger, + offchainConfig, + amount, + await requestSender.getAddress(), + ], + ) + const tx = await linkToken + .connect(requestSender) + .transferAndCall(registrar.address, amount, abiEncodedBytes) + + const [id] = await registry.getActiveUpkeepIDs(0, 1) + + //confirm if a new upkeep has been registered and the details are the same as the one just registered + const newupkeep = await registry.getUpkeep(id) + assert.equal(newupkeep.target, mock.address) + assert.equal(newupkeep.admin, await admin.getAddress()) + assert.equal(newupkeep.checkData, emptyBytes) + assert.equal(newupkeep.balance.toString(), amount.toString()) + assert.equal(newupkeep.performGas, performGas.toNumber()) + assert.equal(newupkeep.offchainConfig, offchainConfig) + + await expect(tx).to.emit(registrar, 'RegistrationRequested') + await expect(tx).to.emit(registrar, 'RegistrationApproved') + }) + + it('Auto Approve OFF - does not registers an upkeep on KeeperRegistry, emits only RegistrationRequested event', async () => { + //get upkeep count before attempting registration + const beforeCount = (await registry.getState()).state.numUpkeeps + + //set auto approve OFF, threshold limits dont matter in this case + await registrar + .connect(registrarOwner) + .setTriggerConfig( + Trigger.CONDITION, + autoApproveType_DISABLED, + maxAllowedAutoApprove, + ) + + //register with auto approve OFF + const abiEncodedBytes = registrar.interface.encodeFunctionData( + 'register', + [ + upkeepName, + emptyBytes, + mock.address, + performGas, + await admin.getAddress(), + 0, + emptyBytes, + trigger, + offchainConfig, + amount, + await requestSender.getAddress(), + ], + ) + const tx = await linkToken + .connect(requestSender) + .transferAndCall(registrar.address, amount, abiEncodedBytes) + const receipt = await tx.wait() + + //get upkeep count after attempting registration + const afterCount = (await registry.getState()).state.numUpkeeps + //confirm that a new upkeep has NOT been registered and upkeep count is still the same + assert.deepEqual(beforeCount, afterCount) + + //confirm that only RegistrationRequested event is emitted and RegistrationApproved event is not + await expect(tx).to.emit(registrar, 'RegistrationRequested') + await expect(tx).not.to.emit(registrar, 'RegistrationApproved') + + const hash = receipt.logs[2].topics[1] + const pendingRequest = await registrar.getPendingRequest(hash) + assert.equal(await admin.getAddress(), pendingRequest[0]) + assert.ok(amount.eq(pendingRequest[1])) + }) + + it('Auto Approve ON - Throttle max approvals - does not register an upkeep on KeeperRegistry beyond the max limit, emits only RegistrationRequested event after limit is hit', async () => { + assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 0) + + //set auto approve on, with max 1 allowed + await registrar + .connect(registrarOwner) + .setTriggerConfig(Trigger.CONDITION, autoApproveType_ENABLED_ALL, 1) + + //set auto approve on, with max 1 allowed + await registrar + .connect(registrarOwner) + .setTriggerConfig(Trigger.LOG, autoApproveType_ENABLED_ALL, 1) + + // register within threshold, new upkeep should be registered + let abiEncodedBytes = registrar.interface.encodeFunctionData('register', [ + upkeepName, + emptyBytes, + mock.address, + performGas, + await admin.getAddress(), + 0, + emptyBytes, + trigger, + offchainConfig, + amount, + await requestSender.getAddress(), + ]) + await linkToken + .connect(requestSender) + .transferAndCall(registrar.address, amount, abiEncodedBytes) + assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 1) // 0 -> 1 + + // try registering another one, new upkeep should not be registered + abiEncodedBytes = registrar.interface.encodeFunctionData('register', [ + upkeepName, + emptyBytes, + mock.address, + performGas.toNumber() + 1, // make unique hash + await admin.getAddress(), + 0, + emptyBytes, + trigger, + offchainConfig, + amount, + await requestSender.getAddress(), + ]) + await linkToken + .connect(requestSender) + .transferAndCall(registrar.address, amount, abiEncodedBytes) + assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 1) // Still 1 + + // register a second type of upkeep, different limit + abiEncodedBytes = registrar.interface.encodeFunctionData('register', [ + upkeepName, + emptyBytes, + mock.address, + performGas, + await admin.getAddress(), + Trigger.LOG, + emptyBytes, + trigger, + offchainConfig, + amount, + await requestSender.getAddress(), + ]) + await linkToken + .connect(requestSender) + .transferAndCall(registrar.address, amount, abiEncodedBytes) + assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 2) // 1 -> 2 + + // Now set new max limit to 2. One more upkeep should get auto approved + await registrar + .connect(registrarOwner) + .setTriggerConfig(Trigger.CONDITION, autoApproveType_ENABLED_ALL, 2) + + abiEncodedBytes = registrar.interface.encodeFunctionData('register', [ + upkeepName, + emptyBytes, + mock.address, + performGas.toNumber() + 2, // make unique hash + await admin.getAddress(), + 0, + emptyBytes, + trigger, + offchainConfig, + amount, + await requestSender.getAddress(), + ]) + await linkToken + .connect(requestSender) + .transferAndCall(registrar.address, amount, abiEncodedBytes) + assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 3) // 2 -> 3 + + // One more upkeep should not get registered + abiEncodedBytes = registrar.interface.encodeFunctionData('register', [ + upkeepName, + emptyBytes, + mock.address, + performGas.toNumber() + 3, // make unique hash + await admin.getAddress(), + 0, + emptyBytes, + trigger, + offchainConfig, + amount, + await requestSender.getAddress(), + ]) + await linkToken + .connect(requestSender) + .transferAndCall(registrar.address, amount, abiEncodedBytes) + assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 3) // Still 3 + }) + + it('Auto Approve Sender Allowlist - sender in allowlist - registers an upkeep on KeeperRegistry instantly and emits both RegistrationRequested and RegistrationApproved events', async () => { + const senderAddress = await requestSender.getAddress() + + //set auto approve to ENABLED_SENDER_ALLOWLIST type with high threshold limits + await registrar + .connect(registrarOwner) + .setTriggerConfig( + Trigger.CONDITION, + autoApproveType_ENABLED_SENDER_ALLOWLIST, + maxAllowedAutoApprove, + ) + + // Add sender to allowlist + await registrar + .connect(registrarOwner) + .setAutoApproveAllowedSender(senderAddress, true) + + //register with auto approve ON + const abiEncodedBytes = registrar.interface.encodeFunctionData( + 'register', + [ + upkeepName, + emptyBytes, + mock.address, + performGas, + await admin.getAddress(), + 0, + emptyBytes, + trigger, + offchainConfig, + amount, + await requestSender.getAddress(), + ], + ) + const tx = await linkToken + .connect(requestSender) + .transferAndCall(registrar.address, amount, abiEncodedBytes) + + const [id] = await registry.getActiveUpkeepIDs(0, 1) + + //confirm if a new upkeep has been registered and the details are the same as the one just registered + const newupkeep = await registry.getUpkeep(id) + assert.equal(newupkeep.target, mock.address) + assert.equal(newupkeep.admin, await admin.getAddress()) + assert.equal(newupkeep.checkData, emptyBytes) + assert.equal(newupkeep.balance.toString(), amount.toString()) + assert.equal(newupkeep.performGas, performGas.toNumber()) + + await expect(tx).to.emit(registrar, 'RegistrationRequested') + await expect(tx).to.emit(registrar, 'RegistrationApproved') + }) + + it('Auto Approve Sender Allowlist - sender NOT in allowlist - does not registers an upkeep on KeeperRegistry, emits only RegistrationRequested event', async () => { + const beforeCount = (await registry.getState()).state.numUpkeeps + const senderAddress = await requestSender.getAddress() + + //set auto approve to ENABLED_SENDER_ALLOWLIST type with high threshold limits + await registrar + .connect(registrarOwner) + .setTriggerConfig( + Trigger.CONDITION, + autoApproveType_ENABLED_SENDER_ALLOWLIST, + maxAllowedAutoApprove, + ) + + // Explicitly remove sender from allowlist + await registrar + .connect(registrarOwner) + .setAutoApproveAllowedSender(senderAddress, false) + + //register. auto approve shouldn't happen + const abiEncodedBytes = registrar.interface.encodeFunctionData( + 'register', + [ + upkeepName, + emptyBytes, + mock.address, + performGas, + await admin.getAddress(), + 0, + emptyBytes, + trigger, + offchainConfig, + amount, + await requestSender.getAddress(), + ], + ) + const tx = await linkToken + .connect(requestSender) + .transferAndCall(registrar.address, amount, abiEncodedBytes) + const receipt = await tx.wait() + + //get upkeep count after attempting registration + const afterCount = (await registry.getState()).state.numUpkeeps + //confirm that a new upkeep has NOT been registered and upkeep count is still the same + assert.deepEqual(beforeCount, afterCount) + + //confirm that only RegistrationRequested event is emitted and RegistrationApproved event is not + await expect(tx).to.emit(registrar, 'RegistrationRequested') + await expect(tx).not.to.emit(registrar, 'RegistrationApproved') + + const hash = receipt.logs[2].topics[1] + const pendingRequest = await registrar.getPendingRequest(hash) + assert.equal(await admin.getAddress(), pendingRequest[0]) + assert.ok(amount.eq(pendingRequest[1])) + }) + }) + + describe('#registerUpkeep', () => { + it('reverts with empty message if amount sent is not available in LINK allowance', async () => { + await evmRevert( + registrar.connect(someAddress).registerUpkeep({ + name: upkeepName, + upkeepContract: mock.address, + gasLimit: performGas, + adminAddress: await admin.getAddress(), + triggerType: 0, + checkData: emptyBytes, + triggerConfig: trigger, + offchainConfig: emptyBytes, + amount, + encryptedEmail: emptyBytes, + }), + '', + ) + }) + + it('reverts if the amount passed in data is less than configured minimum', async () => { + await registrar + .connect(registrarOwner) + .setTriggerConfig( + Trigger.CONDITION, + autoApproveType_ENABLED_ALL, + maxAllowedAutoApprove, + ) + + // amt is one order of magnitude less than minUpkeepSpend + const amt = BigNumber.from('100000000000000000') + + await evmRevert( + registrar.connect(someAddress).registerUpkeep({ + name: upkeepName, + upkeepContract: mock.address, + gasLimit: performGas, + adminAddress: await admin.getAddress(), + triggerType: 0, + checkData: emptyBytes, + triggerConfig: trigger, + offchainConfig: emptyBytes, + amount: amt, + encryptedEmail: emptyBytes, + }), + 'InsufficientPayment()', + ) + }) + + it('Auto Approve ON - registers an upkeep on KeeperRegistry instantly and emits both RegistrationRequested and RegistrationApproved events', async () => { + //set auto approve ON with high threshold limits + await registrar + .connect(registrarOwner) + .setTriggerConfig( + Trigger.CONDITION, + autoApproveType_ENABLED_ALL, + maxAllowedAutoApprove, + ) + + await linkToken.connect(requestSender).approve(registrar.address, amount) + + const tx = await registrar.connect(requestSender).registerUpkeep({ + name: upkeepName, + upkeepContract: mock.address, + gasLimit: performGas, + adminAddress: await admin.getAddress(), + triggerType: 0, + checkData: emptyBytes, + triggerConfig: trigger, + offchainConfig, + amount, + encryptedEmail: emptyBytes, + }) + assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 1) // 0 -> 1 + + //confirm if a new upkeep has been registered and the details are the same as the one just registered + const [id] = await registry.getActiveUpkeepIDs(0, 1) + const newupkeep = await registry.getUpkeep(id) + assert.equal(newupkeep.target, mock.address) + assert.equal(newupkeep.admin, await admin.getAddress()) + assert.equal(newupkeep.checkData, emptyBytes) + assert.equal(newupkeep.balance.toString(), amount.toString()) + assert.equal(newupkeep.performGas, performGas.toNumber()) + assert.equal(newupkeep.offchainConfig, offchainConfig) + + await expect(tx).to.emit(registrar, 'RegistrationRequested') + await expect(tx).to.emit(registrar, 'RegistrationApproved') + }) + }) + + describe('#setAutoApproveAllowedSender', () => { + it('reverts if not called by the owner', async () => { + const tx = registrar + .connect(stranger) + .setAutoApproveAllowedSender(await admin.getAddress(), false) + await evmRevert(tx, 'Only callable by owner') + }) + + it('sets the allowed status correctly and emits log', async () => { + const senderAddress = await stranger.getAddress() + let tx = await registrar + .connect(registrarOwner) + .setAutoApproveAllowedSender(senderAddress, true) + await expect(tx) + .to.emit(registrar, 'AutoApproveAllowedSenderSet') + .withArgs(senderAddress, true) + + let senderAllowedStatus = await registrar + .connect(owner) + .getAutoApproveAllowedSender(senderAddress) + assert.isTrue(senderAllowedStatus) + + tx = await registrar + .connect(registrarOwner) + .setAutoApproveAllowedSender(senderAddress, false) + await expect(tx) + .to.emit(registrar, 'AutoApproveAllowedSenderSet') + .withArgs(senderAddress, false) + + senderAllowedStatus = await registrar + .connect(owner) + .getAutoApproveAllowedSender(senderAddress) + assert.isFalse(senderAllowedStatus) + }) + }) + + describe('#setTriggerConfig', () => { + it('reverts if not called by the owner', async () => { + const tx = registrar + .connect(stranger) + .setTriggerConfig(Trigger.LOG, autoApproveType_ENABLED_ALL, 100) + await evmRevert(tx, 'Only callable by owner') + }) + + it('changes the config', async () => { + const tx = await registrar + .connect(registrarOwner) + .setTriggerConfig(Trigger.LOG, autoApproveType_ENABLED_ALL, 100) + await registrar.getTriggerRegistrationDetails(Trigger.LOG) + await expect(tx) + .to.emit(registrar, 'TriggerConfigSet') + .withArgs(Trigger.LOG, autoApproveType_ENABLED_ALL, 100) + }) + }) + + describe('#approve', () => { + let hash: string + + beforeEach(async () => { + await registrar + .connect(registrarOwner) + .setTriggerConfig( + Trigger.CONDITION, + autoApproveType_DISABLED, + maxAllowedAutoApprove, + ) + + //register with auto approve OFF + const abiEncodedBytes = registrar.interface.encodeFunctionData( + 'register', + [ + upkeepName, + emptyBytes, + mock.address, + performGas, + await admin.getAddress(), + 0, + emptyBytes, + trigger, + offchainConfig, + amount, + await requestSender.getAddress(), + ], + ) + + const tx = await linkToken + .connect(requestSender) + .transferAndCall(registrar.address, amount, abiEncodedBytes) + const receipt = await tx.wait() + hash = receipt.logs[2].topics[1] + }) + + it('reverts if not called by the owner', async () => { + const tx = registrar + .connect(stranger) + .approve( + upkeepName, + mock.address, + performGas, + await admin.getAddress(), + 0, + emptyBytes, + trigger, + emptyBytes, + hash, + ) + await evmRevert(tx, 'Only callable by owner') + }) + + it('reverts if the hash does not exist', async () => { + const tx = registrar + .connect(registrarOwner) + .approve( + upkeepName, + mock.address, + performGas, + await admin.getAddress(), + 0, + emptyBytes, + trigger, + emptyBytes, + '0x000000000000000000000000322813fd9a801c5507c9de605d63cea4f2ce6c44', + ) + await evmRevert(tx, errorMsgs.requestNotFound) + }) + + it('reverts if any member of the payload changes', async () => { + let tx = registrar + .connect(registrarOwner) + .approve( + upkeepName, + ethers.Wallet.createRandom().address, + performGas, + await admin.getAddress(), + 0, + emptyBytes, + trigger, + emptyBytes, + hash, + ) + await evmRevert(tx, errorMsgs.hashPayload) + tx = registrar + .connect(registrarOwner) + .approve( + upkeepName, + mock.address, + 10000, + await admin.getAddress(), + 0, + emptyBytes, + trigger, + emptyBytes, + hash, + ) + await evmRevert(tx, errorMsgs.hashPayload) + tx = registrar + .connect(registrarOwner) + .approve( + upkeepName, + mock.address, + performGas, + ethers.Wallet.createRandom().address, + 0, + emptyBytes, + trigger, + emptyBytes, + hash, + ) + await evmRevert(tx, errorMsgs.hashPayload) + tx = registrar + .connect(registrarOwner) + .approve( + upkeepName, + mock.address, + performGas, + await admin.getAddress(), + 0, + '0x1234', + trigger, + emptyBytes, + hash, + ) + await evmRevert(tx, errorMsgs.hashPayload) + }) + + it('approves an existing registration request', async () => { + const tx = await registrar + .connect(registrarOwner) + .approve( + upkeepName, + mock.address, + performGas, + await admin.getAddress(), + 0, + emptyBytes, + trigger, + offchainConfig, + hash, + ) + await expect(tx).to.emit(registrar, 'RegistrationApproved') + }) + + it('deletes the request afterwards / reverts if the request DNE', async () => { + await registrar + .connect(registrarOwner) + .approve( + upkeepName, + mock.address, + performGas, + await admin.getAddress(), + 0, + emptyBytes, + trigger, + offchainConfig, + hash, + ) + const tx = registrar + .connect(registrarOwner) + .approve( + upkeepName, + mock.address, + performGas, + await admin.getAddress(), + 0, + emptyBytes, + trigger, + offchainConfig, + hash, + ) + await evmRevert(tx, errorMsgs.requestNotFound) + }) + }) + + describe('#cancel', () => { + let hash: string + + beforeEach(async () => { + await registrar + .connect(registrarOwner) + .setTriggerConfig( + Trigger.CONDITION, + autoApproveType_DISABLED, + maxAllowedAutoApprove, + ) + + //register with auto approve OFF + const abiEncodedBytes = registrar.interface.encodeFunctionData( + 'register', + [ + upkeepName, + emptyBytes, + mock.address, + performGas, + await admin.getAddress(), + 0, + emptyBytes, + trigger, + offchainConfig, + amount, + await requestSender.getAddress(), + ], + ) + const tx = await linkToken + .connect(requestSender) + .transferAndCall(registrar.address, amount, abiEncodedBytes) + const receipt = await tx.wait() + hash = receipt.logs[2].topics[1] + // submit duplicate request (increase balance) + await linkToken + .connect(requestSender) + .transferAndCall(registrar.address, amount, abiEncodedBytes) + }) + + it('reverts if not called by the admin / owner', async () => { + const tx = registrar.connect(stranger).cancel(hash) + await evmRevert(tx, errorMsgs.onlyAdmin) + }) + + it('reverts if the hash does not exist', async () => { + const tx = registrar + .connect(registrarOwner) + .cancel( + '0x000000000000000000000000322813fd9a801c5507c9de605d63cea4f2ce6c44', + ) + await evmRevert(tx, errorMsgs.requestNotFound) + }) + + it('refunds the total request balance to the admin address if owner cancels', async () => { + const before = await linkToken.balanceOf(await admin.getAddress()) + const tx = await registrar.connect(registrarOwner).cancel(hash) + const after = await linkToken.balanceOf(await admin.getAddress()) + assert.isTrue(after.sub(before).eq(amount.mul(BigNumber.from(2)))) + await expect(tx).to.emit(registrar, 'RegistrationRejected') + }) + + it('refunds the total request balance to the admin address if admin cancels', async () => { + const before = await linkToken.balanceOf(await admin.getAddress()) + const tx = await registrar.connect(admin).cancel(hash) + const after = await linkToken.balanceOf(await admin.getAddress()) + assert.isTrue(after.sub(before).eq(amount.mul(BigNumber.from(2)))) + await expect(tx).to.emit(registrar, 'RegistrationRejected') + }) + + it('deletes the request hash', async () => { + await registrar.connect(registrarOwner).cancel(hash) + let tx = registrar.connect(registrarOwner).cancel(hash) + await evmRevert(tx, errorMsgs.requestNotFound) + tx = registrar + .connect(registrarOwner) + .approve( + upkeepName, + mock.address, + performGas, + await admin.getAddress(), + 0, + emptyBytes, + trigger, + emptyBytes, + hash, + ) + await evmRevert(tx, errorMsgs.requestNotFound) + }) + }) +}) diff --git a/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts b/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts index 365e61ed3e2..4b6ef59cb5c 100644 --- a/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts +++ b/contracts/test/v0.8/automation/AutomationRegistry2_2.test.ts @@ -2000,7 +2000,8 @@ describe('AutomationRegistry2_2', () => { }, ) - describe('Gas benchmarking conditional upkeeps [ @skip-coverage ]', function () { + // skipping it for now as it is passing in local but failing in CI + describe.skip('Gas benchmarking conditional upkeeps [ @skip-coverage ]', function () { const fs = [1, 10] fs.forEach(function (newF) { it( @@ -5217,6 +5218,7 @@ describe('AutomationRegistry2_2', () => { }) describe('when called by the owner when the admin has just canceled', () => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars let oldExpiration: BigNumber beforeEach(async () => { diff --git a/contracts/test/v0.8/automation/AutomationRegistry2_3.test.ts b/contracts/test/v0.8/automation/AutomationRegistry2_3.test.ts new file mode 100644 index 00000000000..a293a5f2544 --- /dev/null +++ b/contracts/test/v0.8/automation/AutomationRegistry2_3.test.ts @@ -0,0 +1,5884 @@ +import { ethers } from 'hardhat' +import { loadFixture } from '@nomicfoundation/hardhat-network-helpers' +import { assert, expect } from 'chai' +import { + BigNumber, + BigNumberish, + BytesLike, + Contract, + ContractFactory, + ContractReceipt, + ContractTransaction, + Signer, + Wallet, +} from 'ethers' +import { evmRevert } from '../../test-helpers/matchers' +import { getUsers, Personas } from '../../test-helpers/setup' +import { randomAddress, toWei } from '../../test-helpers/helpers' +import { StreamsLookupUpkeep__factory as StreamsLookupUpkeepFactory } from '../../../typechain/factories/StreamsLookupUpkeep__factory' +import { MockV3Aggregator__factory as MockV3AggregatorFactory } from '../../../typechain/factories/MockV3Aggregator__factory' +import { UpkeepMock__factory as UpkeepMockFactory } from '../../../typechain/factories/UpkeepMock__factory' +import { UpkeepAutoFunder__factory as UpkeepAutoFunderFactory } from '../../../typechain/factories/UpkeepAutoFunder__factory' +import { MockArbGasInfo__factory as MockArbGasInfoFactory } from '../../../typechain/factories/MockArbGasInfo__factory' +import { MockOVMGasPriceOracle__factory as MockOVMGasPriceOracleFactory } from '../../../typechain/factories/MockOVMGasPriceOracle__factory' +import { ChainModuleBase__factory as ChainModuleBaseFactory } from '../../../typechain/factories/ChainModuleBase__factory' +import { ArbitrumModule__factory as ArbitrumModuleFactory } from '../../../typechain/factories/ArbitrumModule__factory' +import { OptimismModule__factory as OptimismModuleFactory } from '../../../typechain/factories/OptimismModule__factory' +import { ILogAutomation__factory as ILogAutomationactory } from '../../../typechain/factories/ILogAutomation__factory' +import { IAutomationForwarder__factory as IAutomationForwarderFactory } from '../../../typechain/factories/IAutomationForwarder__factory' +import { MockArbSys__factory as MockArbSysFactory } from '../../../typechain/factories/MockArbSys__factory' +import { AutomationUtils2_3 as AutomationUtils } from '../../../typechain/AutomationUtils2_3' +import { MockArbGasInfo } from '../../../typechain/MockArbGasInfo' +import { MockOVMGasPriceOracle } from '../../../typechain/MockOVMGasPriceOracle' +import { StreamsLookupUpkeep } from '../../../typechain/StreamsLookupUpkeep' +import { MockV3Aggregator } from '../../../typechain/MockV3Aggregator' +import { UpkeepMock } from '../../../typechain/UpkeepMock' +import { ChainModuleBase } from '../../../typechain/ChainModuleBase' +import { ArbitrumModule } from '../../../typechain/ArbitrumModule' +import { OptimismModule } from '../../../typechain/OptimismModule' +import { UpkeepTranscoder } from '../../../typechain/UpkeepTranscoder' +import { IChainModule, UpkeepAutoFunder } from '../../../typechain' +import { + CancelledUpkeepReportEvent, + IAutomationRegistryMaster as IAutomationRegistry, + ReorgedUpkeepReportEvent, + StaleUpkeepReportEvent, + UpkeepPerformedEvent, +} from '../../../typechain/IAutomationRegistryMaster' +import { + deployMockContract, + MockContract, +} from '@ethereum-waffle/mock-contract' +import { deployRegistry23 } from './helpers' + +const describeMaybe = process.env.SKIP_SLOW ? describe.skip : describe +const itMaybe = process.env.SKIP_SLOW ? it.skip : it + +// copied from AutomationRegistryInterface2_3.sol +enum UpkeepFailureReason { + NONE, + UPKEEP_CANCELLED, + UPKEEP_PAUSED, + TARGET_CHECK_REVERTED, + UPKEEP_NOT_NEEDED, + PERFORM_DATA_EXCEEDS_LIMIT, + INSUFFICIENT_BALANCE, + CHECK_CALLBACK_REVERTED, + REVERT_DATA_EXCEEDS_LIMIT, + REGISTRY_PAUSED, +} + +// copied from AutomationRegistryBase2_3.sol +enum Trigger { + CONDITION, + LOG, +} + +// un-exported types that must be extracted from the utils contract +type Report = Parameters[0] +type OnChainConfig = Parameters[0] +type LogTrigger = Parameters[0] +type ConditionalTrigger = Parameters[0] +type Log = Parameters[0] + +// ----------------------------------------------------------------------------------------------- + +// These values should match the constants declared in registry +let registryConditionalOverhead: BigNumber +let registryLogOverhead: BigNumber +let registryPerSignerGasOverhead: BigNumber +let registryPerPerformByteGasOverhead: BigNumber +let registryTransmitCalldataFixedBytesOverhead: BigNumber +let registryTransmitCalldataPerSignerBytesOverhead: BigNumber +let cancellationDelay: number + +// This is the margin for gas that we test for. Gas charged should always be greater +// than total gas used in tx but should not increase beyond this margin +const gasCalculationMargin = BigNumber.from(5000) +// This is the margin for gas overhead estimation in checkUpkeep. The estimated gas +// overhead should be larger than actual gas overhead but should not increase beyond this margin +const gasEstimationMargin = BigNumber.from(5000) + +const linkEth = BigNumber.from(5000000000000000) // 1 Link = 0.005 Eth +const gasWei = BigNumber.from(1000000000) // 1 gwei +// ----------------------------------------------------------------------------------------------- +// test-wide configs for upkeeps +const linkDivisibility = BigNumber.from('1000000000000000000') +const performGas = BigNumber.from('1000000') +const paymentPremiumBase = BigNumber.from('1000000000') +const paymentPremiumPPB = BigNumber.from('250000000') +const flatFeeMicroLink = BigNumber.from(0) + +const randomBytes = '0x1234abcd' +const emptyBytes = '0x' +const emptyBytes32 = + '0x0000000000000000000000000000000000000000000000000000000000000000' + +const transmitGasOverhead = 1_000_000 +const checkGasOverhead = 500_000 + +const stalenessSeconds = BigNumber.from(43820) +const gasCeilingMultiplier = BigNumber.from(2) +const checkGasLimit = BigNumber.from(10000000) +const fallbackGasPrice = gasWei.mul(BigNumber.from('2')) +const fallbackLinkPrice = linkEth.div(BigNumber.from('2')) +const maxCheckDataSize = BigNumber.from(1000) +const maxPerformDataSize = BigNumber.from(1000) +const maxRevertDataSize = BigNumber.from(1000) +const maxPerformGas = BigNumber.from(5000000) +const minUpkeepSpend = BigNumber.from(0) +const f = 1 +const offchainVersion = 1 +const offchainBytes = '0x' +const zeroAddress = ethers.constants.AddressZero +const epochAndRound5_1 = + '0x0000000000000000000000000000000000000000000000000000000000000501' + +let logTriggerConfig: string + +// ----------------------------------------------------------------------------------------------- + +// Smart contract factories +let linkTokenFactory: ContractFactory +let mockArbGasInfoFactory: MockArbGasInfoFactory +let mockOVMGasPriceOracleFactory: MockOVMGasPriceOracleFactory +let mockV3AggregatorFactory: MockV3AggregatorFactory +let upkeepMockFactory: UpkeepMockFactory +let upkeepAutoFunderFactory: UpkeepAutoFunderFactory +let chainModuleBaseFactory: ChainModuleBaseFactory +let arbitrumModuleFactory: ArbitrumModuleFactory +let optimismModuleFactory: OptimismModuleFactory +let streamsLookupUpkeepFactory: StreamsLookupUpkeepFactory +let personas: Personas + +// contracts +let linkToken: Contract +let linkEthFeed: MockV3Aggregator +let gasPriceFeed: MockV3Aggregator +let registry: IAutomationRegistry // default registry, used for most tests +let arbRegistry: IAutomationRegistry // arbitrum registry +let opRegistry: IAutomationRegistry // optimism registry +let mgRegistry: IAutomationRegistry // "migrate registry" used in migration tests +let blankRegistry: IAutomationRegistry // used to test initial configurations +let mockArbGasInfo: MockArbGasInfo +let mockOVMGasPriceOracle: MockOVMGasPriceOracle +let mock: UpkeepMock +let autoFunderUpkeep: UpkeepAutoFunder +let ltUpkeep: MockContract +let transcoder: UpkeepTranscoder +let chainModuleBase: ChainModuleBase +let arbitrumModule: ArbitrumModule +let optimismModule: OptimismModule +let streamsLookupUpkeep: StreamsLookupUpkeep +let automationUtils: AutomationUtils + +function now() { + return Math.floor(Date.now() / 1000) +} + +async function getUpkeepID(tx: ContractTransaction): Promise { + const receipt = await tx.wait() + for (const event of receipt.events || []) { + if ( + event.args && + event.eventSignature == 'UpkeepRegistered(uint256,uint32,address)' + ) { + return event.args[0] + } + } + throw new Error('could not find upkeep ID in tx event logs') +} + +const getTriggerType = (upkeepId: BigNumber): Trigger => { + const hexBytes = ethers.utils.defaultAbiCoder.encode(['uint256'], [upkeepId]) + const bytes = ethers.utils.arrayify(hexBytes) + for (let idx = 4; idx < 15; idx++) { + if (bytes[idx] != 0) { + return Trigger.CONDITION + } + } + return bytes[15] as Trigger +} + +const encodeConfig = (onchainConfig: OnChainConfig) => { + return ( + '0x' + + automationUtils.interface + .encodeFunctionData('_onChainConfig', [onchainConfig]) + .slice(10) + ) +} + +const encodeBlockTrigger = (conditionalTrigger: ConditionalTrigger) => { + return ( + '0x' + + automationUtils.interface + .encodeFunctionData('_conditionalTrigger', [conditionalTrigger]) + .slice(10) + ) +} + +const encodeLogTrigger = (logTrigger: LogTrigger) => { + return ( + '0x' + + automationUtils.interface + .encodeFunctionData('_logTrigger', [logTrigger]) + .slice(10) + ) +} + +const encodeLog = (log: Log) => { + return ( + '0x' + automationUtils.interface.encodeFunctionData('_log', [log]).slice(10) + ) +} + +const encodeReport = (report: Report) => { + return ( + '0x' + + automationUtils.interface.encodeFunctionData('_report', [report]).slice(10) + ) +} + +type UpkeepData = { + Id: BigNumberish + performGas: BigNumberish + performData: BytesLike + trigger: BytesLike +} + +const makeReport = (upkeeps: UpkeepData[]) => { + const upkeepIds = upkeeps.map((u) => u.Id) + const performGases = upkeeps.map((u) => u.performGas) + const triggers = upkeeps.map((u) => u.trigger) + const performDatas = upkeeps.map((u) => u.performData) + return encodeReport({ + fastGasWei: gasWei, + linkNative: linkEth, + upkeepIds, + gasLimits: performGases, + triggers, + performDatas, + }) +} + +const makeLatestBlockReport = async (upkeepsIDs: BigNumberish[]) => { + const latestBlock = await ethers.provider.getBlock('latest') + const upkeeps: UpkeepData[] = [] + for (let i = 0; i < upkeepsIDs.length; i++) { + upkeeps.push({ + Id: upkeepsIDs[i], + performGas, + trigger: encodeBlockTrigger({ + blockNum: latestBlock.number, + blockHash: latestBlock.hash, + }), + performData: '0x', + }) + } + return makeReport(upkeeps) +} + +const signReport = ( + reportContext: string[], + report: any, + signers: Wallet[], +) => { + const reportDigest = ethers.utils.keccak256(report) + const packedArgs = ethers.utils.solidityPack( + ['bytes32', 'bytes32[3]'], + [reportDigest, reportContext], + ) + const packedDigest = ethers.utils.keccak256(packedArgs) + + const signatures = [] + for (const signer of signers) { + signatures.push(signer._signingKey().signDigest(packedDigest)) + } + const vs = signatures.map((i) => '0' + (i.v - 27).toString(16)).join('') + return { + vs: '0x' + vs.padEnd(64, '0'), + rs: signatures.map((i) => i.r), + ss: signatures.map((i) => i.s), + } +} + +const parseUpkeepPerformedLogs = (receipt: ContractReceipt) => { + const parsedLogs = [] + for (const rawLog of receipt.logs) { + try { + const log = registry.interface.parseLog(rawLog) + if ( + log.name == + registry.interface.events[ + 'UpkeepPerformed(uint256,bool,uint96,uint256,uint256,bytes)' + ].name + ) { + parsedLogs.push(log as unknown as UpkeepPerformedEvent) + } + } catch { + continue + } + } + return parsedLogs +} + +const parseReorgedUpkeepReportLogs = (receipt: ContractReceipt) => { + const parsedLogs = [] + for (const rawLog of receipt.logs) { + try { + const log = registry.interface.parseLog(rawLog) + if ( + log.name == + registry.interface.events['ReorgedUpkeepReport(uint256,bytes)'].name + ) { + parsedLogs.push(log as unknown as ReorgedUpkeepReportEvent) + } + } catch { + continue + } + } + return parsedLogs +} + +const parseStaleUpkeepReportLogs = (receipt: ContractReceipt) => { + const parsedLogs = [] + for (const rawLog of receipt.logs) { + try { + const log = registry.interface.parseLog(rawLog) + if ( + log.name == + registry.interface.events['StaleUpkeepReport(uint256,bytes)'].name + ) { + parsedLogs.push(log as unknown as StaleUpkeepReportEvent) + } + } catch { + continue + } + } + return parsedLogs +} + +const parseCancelledUpkeepReportLogs = (receipt: ContractReceipt) => { + const parsedLogs = [] + for (const rawLog of receipt.logs) { + try { + const log = registry.interface.parseLog(rawLog) + if ( + log.name == + registry.interface.events['CancelledUpkeepReport(uint256,bytes)'].name + ) { + parsedLogs.push(log as unknown as CancelledUpkeepReportEvent) + } + } catch { + continue + } + } + return parsedLogs +} + +describe('AutomationRegistry2_3', () => { + let owner: Signer + let keeper1: Signer + let keeper2: Signer + let keeper3: Signer + let keeper4: Signer + let keeper5: Signer + let nonkeeper: Signer + let signer1: Wallet + let signer2: Wallet + let signer3: Wallet + let signer4: Wallet + let signer5: Wallet + let admin: Signer + let payee1: Signer + let payee2: Signer + let payee3: Signer + let payee4: Signer + let payee5: Signer + + let upkeepId: BigNumber // conditional upkeep + let afUpkeepId: BigNumber // auto funding upkeep + let logUpkeepId: BigNumber // log trigger upkeepID + let streamsLookupUpkeepId: BigNumber // streams lookup upkeep + const numUpkeeps = 4 // see above + let keeperAddresses: string[] + let payees: string[] + let signers: Wallet[] + let signerAddresses: string[] + let config: any + let arbConfig: any + let opConfig: any + let baseConfig: Parameters + let arbConfigParams: Parameters + let opConfigParams: Parameters + let upkeepManager: string + + before(async () => { + personas = (await getUsers()).personas + + const utilsFactory = await ethers.getContractFactory('AutomationUtils2_3') + automationUtils = await utilsFactory.deploy() + + linkTokenFactory = await ethers.getContractFactory( + 'src/v0.4/LinkToken.sol:LinkToken', + ) + // need full path because there are two contracts with name MockV3Aggregator + mockV3AggregatorFactory = (await ethers.getContractFactory( + 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', + )) as unknown as MockV3AggregatorFactory + mockArbGasInfoFactory = await ethers.getContractFactory('MockArbGasInfo') + mockOVMGasPriceOracleFactory = await ethers.getContractFactory( + 'MockOVMGasPriceOracle', + ) + upkeepMockFactory = await ethers.getContractFactory('UpkeepMock') + upkeepAutoFunderFactory = + await ethers.getContractFactory('UpkeepAutoFunder') + chainModuleBaseFactory = await ethers.getContractFactory('ChainModuleBase') + arbitrumModuleFactory = await ethers.getContractFactory('ArbitrumModule') + optimismModuleFactory = await ethers.getContractFactory('OptimismModule') + streamsLookupUpkeepFactory = await ethers.getContractFactory( + 'StreamsLookupUpkeep', + ) + + owner = personas.Default + keeper1 = personas.Carol + keeper2 = personas.Eddy + keeper3 = personas.Nancy + keeper4 = personas.Norbert + keeper5 = personas.Nick + nonkeeper = personas.Ned + admin = personas.Neil + payee1 = personas.Nelly + payee2 = personas.Norbert + payee3 = personas.Nick + payee4 = personas.Eddy + payee5 = personas.Carol + upkeepManager = await personas.Norbert.getAddress() + // signers + signer1 = new ethers.Wallet( + '0x7777777000000000000000000000000000000000000000000000000000000001', + ) + signer2 = new ethers.Wallet( + '0x7777777000000000000000000000000000000000000000000000000000000002', + ) + signer3 = new ethers.Wallet( + '0x7777777000000000000000000000000000000000000000000000000000000003', + ) + signer4 = new ethers.Wallet( + '0x7777777000000000000000000000000000000000000000000000000000000004', + ) + signer5 = new ethers.Wallet( + '0x7777777000000000000000000000000000000000000000000000000000000005', + ) + + keeperAddresses = [ + await keeper1.getAddress(), + await keeper2.getAddress(), + await keeper3.getAddress(), + await keeper4.getAddress(), + await keeper5.getAddress(), + ] + payees = [ + await payee1.getAddress(), + await payee2.getAddress(), + await payee3.getAddress(), + await payee4.getAddress(), + await payee5.getAddress(), + ] + signers = [signer1, signer2, signer3, signer4, signer5] + + // We append 26 random addresses to keepers, payees and signers to get a system of 31 oracles + // This allows f value of 1 - 10 + for (let i = 0; i < 26; i++) { + keeperAddresses.push(randomAddress()) + payees.push(randomAddress()) + signers.push(ethers.Wallet.createRandom()) + } + signerAddresses = [] + for (const signer of signers) { + signerAddresses.push(await signer.getAddress()) + } + + logTriggerConfig = + '0x' + + automationUtils.interface + .encodeFunctionData('_logTriggerConfig', [ + { + contractAddress: randomAddress(), + filterSelector: 0, + topic0: ethers.utils.randomBytes(32), + topic1: ethers.utils.randomBytes(32), + topic2: ethers.utils.randomBytes(32), + topic3: ethers.utils.randomBytes(32), + }, + ]) + .slice(10) + }) + + // This function is similar to registry's _calculatePaymentAmount + // It uses global fastGasWei, linkEth, and assumes isExecution = false (gasFee = fastGasWei*multiplier) + // rest of the parameters are the same + const linkForGas = ( + upkeepGasSpent: BigNumber, + gasOverhead: BigNumber, + gasMultiplier: BigNumber, + premiumPPB: BigNumber, + flatFee: BigNumber, + l1CostWei?: BigNumber, + ) => { + l1CostWei = l1CostWei === undefined ? BigNumber.from(0) : l1CostWei + + const gasSpent = gasOverhead.add(BigNumber.from(upkeepGasSpent)) + const base = gasWei + .mul(gasMultiplier) + .mul(gasSpent) + .mul(linkDivisibility) + .div(linkEth) + const l1Fee = l1CostWei.mul(linkDivisibility).div(linkEth) + const gasPayment = base.add(l1Fee) + + const premium = gasWei + .mul(gasMultiplier) + .mul(upkeepGasSpent) + .add(l1CostWei) + .mul(linkDivisibility) + .div(linkEth) + .mul(premiumPPB) + .div(paymentPremiumBase) + .add(BigNumber.from(flatFee).mul('1000000000000')) + + return { + total: gasPayment.add(premium), + gasPayment, + premium, + } + } + + const verifyMaxPayment = async ( + registry: IAutomationRegistry, + chainModule: IChainModule, + maxl1CostWeWithoutMultiplier?: BigNumber, + ) => { + type TestCase = { + name: string + multiplier: number + gas: number + premium: number + flatFee: number + } + + const tests: TestCase[] = [ + { + name: 'no fees', + multiplier: 1, + gas: 100000, + premium: 0, + flatFee: 0, + }, + { + name: 'basic fees', + multiplier: 1, + gas: 100000, + premium: 250000000, + flatFee: 1000000, + }, + { + name: 'max fees', + multiplier: 3, + gas: 10000000, + premium: 250000000, + flatFee: 1000000, + }, + ] + + const fPlusOne = BigNumber.from(f + 1) + const chainModuleOverheads = await chainModule.getGasOverhead() + const totalConditionalOverhead = registryConditionalOverhead + .add(registryPerSignerGasOverhead.mul(fPlusOne)) + .add( + registryPerPerformByteGasOverhead + .add(chainModuleOverheads.chainModulePerByteOverhead) + .mul( + maxPerformDataSize + .add(registryTransmitCalldataFixedBytesOverhead) + .add( + registryTransmitCalldataPerSignerBytesOverhead.mul(fPlusOne), + ), + ), + ) + .add(chainModuleOverheads.chainModuleFixedOverhead) + + const totalLogOverhead = registryLogOverhead + .add(registryPerSignerGasOverhead.mul(fPlusOne)) + .add( + registryPerPerformByteGasOverhead + .add(chainModuleOverheads.chainModulePerByteOverhead) + .mul( + maxPerformDataSize + .add(registryTransmitCalldataFixedBytesOverhead) + .add( + registryTransmitCalldataPerSignerBytesOverhead.mul(fPlusOne), + ), + ), + ) + .add(chainModuleOverheads.chainModuleFixedOverhead) + + for (const test of tests) { + await registry.connect(owner).setConfig( + signerAddresses, + keeperAddresses, + f, + encodeConfig({ + paymentPremiumPPB: test.premium, + flatFeeMicroLink: test.flatFee, + checkGasLimit, + stalenessSeconds, + gasCeilingMultiplier: test.multiplier, + minUpkeepSpend, + maxCheckDataSize, + maxPerformDataSize, + maxRevertDataSize, + maxPerformGas, + fallbackGasPrice, + fallbackLinkPrice, + transcoder: transcoder.address, + registrars: [], + upkeepPrivilegeManager: upkeepManager, + chainModule: chainModule.address, + reorgProtectionEnabled: true, + }), + offchainVersion, + offchainBytes, + ) + + const conditionalPrice = await registry.getMaxPaymentForGas( + Trigger.CONDITION, + test.gas, + ) + expect(conditionalPrice).to.equal( + linkForGas( + BigNumber.from(test.gas), + totalConditionalOverhead, + BigNumber.from(test.multiplier), + BigNumber.from(test.premium), + BigNumber.from(test.flatFee), + maxl1CostWeWithoutMultiplier?.mul(BigNumber.from(test.multiplier)), + ).total, + ) + + const logPrice = await registry.getMaxPaymentForGas(Trigger.LOG, test.gas) + expect(logPrice).to.equal( + linkForGas( + BigNumber.from(test.gas), + totalLogOverhead, + BigNumber.from(test.multiplier), + BigNumber.from(test.premium), + BigNumber.from(test.flatFee), + maxl1CostWeWithoutMultiplier?.mul(BigNumber.from(test.multiplier)), + ).total, + ) + } + } + + const verifyConsistentAccounting = async ( + maxAllowedSpareChange: BigNumber, + ) => { + const expectedLinkBalance = (await registry.getState()).state + .expectedLinkBalance + const linkTokenBalance = await linkToken.balanceOf(registry.address) + const upkeepIdBalance = (await registry.getUpkeep(upkeepId)).balance + let totalKeeperBalance = BigNumber.from(0) + for (let i = 0; i < keeperAddresses.length; i++) { + totalKeeperBalance = totalKeeperBalance.add( + (await registry.getTransmitterInfo(keeperAddresses[i])).balance, + ) + } + const ownerBalance = (await registry.getState()).state.ownerLinkBalance + assert.isTrue(expectedLinkBalance.eq(linkTokenBalance)) + assert.isTrue( + upkeepIdBalance + .add(totalKeeperBalance) + .add(ownerBalance) + .lte(expectedLinkBalance), + ) + assert.isTrue( + expectedLinkBalance + .sub(upkeepIdBalance) + .sub(totalKeeperBalance) + .sub(ownerBalance) + .lte(maxAllowedSpareChange), + ) + } + + interface GetTransmitTXOptions { + numSigners?: number + startingSignerIndex?: number + gasLimit?: BigNumberish + gasPrice?: BigNumberish + performGas?: BigNumberish + performDatas?: string[] + checkBlockNum?: number + checkBlockHash?: string + logBlockHash?: BytesLike + txHash?: BytesLike + logIndex?: number + timestamp?: number + } + + const getTransmitTx = async ( + registry: IAutomationRegistry, + transmitter: Signer, + upkeepIds: BigNumber[], + overrides: GetTransmitTXOptions = {}, + ) => { + const latestBlock = await ethers.provider.getBlock('latest') + const configDigest = (await registry.getState()).state.latestConfigDigest + const config = { + numSigners: f + 1, + startingSignerIndex: 0, + performDatas: undefined, + performGas, + checkBlockNum: latestBlock.number, + checkBlockHash: latestBlock.hash, + logIndex: 0, + txHash: undefined, // assigned uniquely below + logBlockHash: undefined, // assigned uniquely below + timestamp: now(), + gasLimit: undefined, + gasPrice: undefined, + } + Object.assign(config, overrides) + const upkeeps: UpkeepData[] = [] + for (let i = 0; i < upkeepIds.length; i++) { + let trigger: string + switch (getTriggerType(upkeepIds[i])) { + case Trigger.CONDITION: + trigger = encodeBlockTrigger({ + blockNum: config.checkBlockNum, + blockHash: config.checkBlockHash, + }) + break + case Trigger.LOG: + trigger = encodeLogTrigger({ + logBlockHash: config.logBlockHash || ethers.utils.randomBytes(32), + txHash: config.txHash || ethers.utils.randomBytes(32), + logIndex: config.logIndex, + blockNum: config.checkBlockNum, + blockHash: config.checkBlockHash, + }) + break + } + upkeeps.push({ + Id: upkeepIds[i], + performGas: config.performGas, + trigger, + performData: config.performDatas ? config.performDatas[i] : '0x', + }) + } + + const report = makeReport(upkeeps) + const reportContext = [configDigest, epochAndRound5_1, emptyBytes32] + const sigs = signReport( + reportContext, + report, + signers.slice( + config.startingSignerIndex, + config.startingSignerIndex + config.numSigners, + ), + ) + + type txOverride = { + gasLimit?: BigNumberish | Promise + gasPrice?: BigNumberish | Promise + } + const txOverrides: txOverride = {} + if (config.gasLimit) { + txOverrides.gasLimit = config.gasLimit + } + if (config.gasPrice) { + txOverrides.gasPrice = config.gasPrice + } + + return registry + .connect(transmitter) + .transmit( + [configDigest, epochAndRound5_1, emptyBytes32], + report, + sigs.rs, + sigs.ss, + sigs.vs, + txOverrides, + ) + } + + const getTransmitTxWithReport = async ( + registry: IAutomationRegistry, + transmitter: Signer, + report: BytesLike, + ) => { + const configDigest = (await registry.getState()).state.latestConfigDigest + const reportContext = [configDigest, epochAndRound5_1, emptyBytes32] + const sigs = signReport(reportContext, report, signers.slice(0, f + 1)) + + return registry + .connect(transmitter) + .transmit( + [configDigest, epochAndRound5_1, emptyBytes32], + report, + sigs.rs, + sigs.ss, + sigs.vs, + ) + } + + const setup = async () => { + linkToken = await linkTokenFactory.connect(owner).deploy() + gasPriceFeed = await mockV3AggregatorFactory + .connect(owner) + .deploy(0, gasWei) + linkEthFeed = await mockV3AggregatorFactory + .connect(owner) + .deploy(9, linkEth) + const upkeepTranscoderFactory = await ethers.getContractFactory( + 'UpkeepTranscoder4_0', + ) + transcoder = await upkeepTranscoderFactory.connect(owner).deploy() + mockArbGasInfo = await mockArbGasInfoFactory.connect(owner).deploy() + mockOVMGasPriceOracle = await mockOVMGasPriceOracleFactory + .connect(owner) + .deploy() + chainModuleBase = await chainModuleBaseFactory.connect(owner).deploy() + arbitrumModule = await arbitrumModuleFactory.connect(owner).deploy() + optimismModule = await optimismModuleFactory.connect(owner).deploy() + streamsLookupUpkeep = await streamsLookupUpkeepFactory + .connect(owner) + .deploy( + BigNumber.from('10000'), + BigNumber.from('100'), + false /* useArbBlock */, + true /* staging */, + false /* verify mercury response */, + ) + + const arbOracleCode = await ethers.provider.send('eth_getCode', [ + mockArbGasInfo.address, + ]) + await ethers.provider.send('hardhat_setCode', [ + '0x000000000000000000000000000000000000006C', + arbOracleCode, + ]) + + const optOracleCode = await ethers.provider.send('eth_getCode', [ + mockOVMGasPriceOracle.address, + ]) + await ethers.provider.send('hardhat_setCode', [ + '0x420000000000000000000000000000000000000F', + optOracleCode, + ]) + + const mockArbSys = await new MockArbSysFactory(owner).deploy() + const arbSysCode = await ethers.provider.send('eth_getCode', [ + mockArbSys.address, + ]) + await ethers.provider.send('hardhat_setCode', [ + '0x0000000000000000000000000000000000000064', + arbSysCode, + ]) + + config = { + paymentPremiumPPB, + flatFeeMicroLink, + checkGasLimit, + stalenessSeconds, + gasCeilingMultiplier, + minUpkeepSpend, + maxCheckDataSize, + maxPerformDataSize, + maxRevertDataSize, + maxPerformGas, + fallbackGasPrice, + fallbackLinkPrice, + transcoder: transcoder.address, + registrars: [], + upkeepPrivilegeManager: upkeepManager, + chainModule: chainModuleBase.address, + reorgProtectionEnabled: true, + } + + arbConfig = { ...config } + arbConfig.chainModule = arbitrumModule.address + opConfig = { ...config } + opConfig.chainModule = optimismModule.address + + baseConfig = [ + signerAddresses, + keeperAddresses, + f, + encodeConfig(config), + offchainVersion, + offchainBytes, + ] + arbConfigParams = [ + signerAddresses, + keeperAddresses, + f, + encodeConfig(arbConfig), + offchainVersion, + offchainBytes, + ] + opConfigParams = [ + signerAddresses, + keeperAddresses, + f, + encodeConfig(opConfig), + offchainVersion, + offchainBytes, + ] + + registry = await deployRegistry23( + owner, + linkToken.address, + linkEthFeed.address, + gasPriceFeed.address, + zeroAddress, + ) + + arbRegistry = await deployRegistry23( + owner, + linkToken.address, + linkEthFeed.address, + gasPriceFeed.address, + zeroAddress, + ) + + opRegistry = await deployRegistry23( + owner, + linkToken.address, + linkEthFeed.address, + gasPriceFeed.address, + zeroAddress, + ) + + mgRegistry = await deployRegistry23( + owner, + linkToken.address, + linkEthFeed.address, + gasPriceFeed.address, + zeroAddress, + ) + + blankRegistry = await deployRegistry23( + owner, + linkToken.address, + linkEthFeed.address, + gasPriceFeed.address, + zeroAddress, + ) + + registryConditionalOverhead = await registry.getConditionalGasOverhead() + registryLogOverhead = await registry.getLogGasOverhead() + registryPerSignerGasOverhead = await registry.getPerSignerGasOverhead() + registryPerPerformByteGasOverhead = + await registry.getPerPerformByteGasOverhead() + registryTransmitCalldataFixedBytesOverhead = + await registry.getTransmitCalldataFixedBytesOverhead() + registryTransmitCalldataPerSignerBytesOverhead = + await registry.getTransmitCalldataPerSignerBytesOverhead() + cancellationDelay = (await registry.getCancellationDelay()).toNumber() + + await registry.connect(owner).setConfig(...baseConfig) + await mgRegistry.connect(owner).setConfig(...baseConfig) + await arbRegistry.connect(owner).setConfig(...arbConfigParams) + await opRegistry.connect(owner).setConfig(...opConfigParams) + for (const reg of [registry, arbRegistry, opRegistry, mgRegistry]) { + await reg.connect(owner).setPayees(payees) + await linkToken.connect(admin).approve(reg.address, toWei('1000')) + await linkToken.connect(owner).approve(reg.address, toWei('1000')) + } + + mock = await upkeepMockFactory.deploy() + await linkToken + .connect(owner) + .transfer(await admin.getAddress(), toWei('1000')) + let tx = await registry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,bytes,bytes)' + ](mock.address, performGas, await admin.getAddress(), randomBytes, '0x') + upkeepId = await getUpkeepID(tx) + + autoFunderUpkeep = await upkeepAutoFunderFactory + .connect(owner) + .deploy(linkToken.address, registry.address) + tx = await registry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,bytes,bytes)' + ](autoFunderUpkeep.address, performGas, autoFunderUpkeep.address, randomBytes, '0x') + afUpkeepId = await getUpkeepID(tx) + + ltUpkeep = await deployMockContract(owner, ILogAutomationactory.abi) + tx = await registry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,uint8,bytes,bytes,bytes)' + ](ltUpkeep.address, performGas, await admin.getAddress(), Trigger.LOG, '0x', logTriggerConfig, emptyBytes) + logUpkeepId = await getUpkeepID(tx) + + await autoFunderUpkeep.setUpkeepId(afUpkeepId) + // Give enough funds for upkeep as well as to the upkeep contract + await linkToken + .connect(owner) + .transfer(autoFunderUpkeep.address, toWei('1000')) + + tx = await registry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,bytes,bytes)' + ](streamsLookupUpkeep.address, performGas, await admin.getAddress(), randomBytes, '0x') + streamsLookupUpkeepId = await getUpkeepID(tx) + } + + const getMultipleUpkeepsDeployedAndFunded = async ( + numPassingConditionalUpkeeps: number, + numPassingLogUpkeeps: number, + numFailingUpkeeps: number, + ) => { + const passingConditionalUpkeepIds = [] + const passingLogUpkeepIds = [] + const failingUpkeepIds = [] + for (let i = 0; i < numPassingConditionalUpkeeps; i++) { + const mock = await upkeepMockFactory.deploy() + await mock.setCanPerform(true) + await mock.setPerformGasToBurn(BigNumber.from('0')) + const tx = await registry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,bytes,bytes)' + ](mock.address, performGas, await admin.getAddress(), randomBytes, '0x') + const condUpkeepId = await getUpkeepID(tx) + passingConditionalUpkeepIds.push(condUpkeepId) + + // Add funds to passing upkeeps + await registry.connect(admin).addFunds(condUpkeepId, toWei('100')) + } + for (let i = 0; i < numPassingLogUpkeeps; i++) { + const mock = await upkeepMockFactory.deploy() + await mock.setCanPerform(true) + await mock.setPerformGasToBurn(BigNumber.from('0')) + const tx = await registry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,uint8,bytes,bytes,bytes)' + ](mock.address, performGas, await admin.getAddress(), Trigger.LOG, '0x', logTriggerConfig, emptyBytes) + const logUpkeepId = await getUpkeepID(tx) + passingLogUpkeepIds.push(logUpkeepId) + + // Add funds to passing upkeeps + await registry.connect(admin).addFunds(logUpkeepId, toWei('100')) + } + for (let i = 0; i < numFailingUpkeeps; i++) { + const mock = await upkeepMockFactory.deploy() + await mock.setCanPerform(true) + await mock.setPerformGasToBurn(BigNumber.from('0')) + const tx = await registry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,bytes,bytes)' + ](mock.address, performGas, await admin.getAddress(), randomBytes, '0x') + const failingUpkeepId = await getUpkeepID(tx) + failingUpkeepIds.push(failingUpkeepId) + } + return { + passingConditionalUpkeepIds, + passingLogUpkeepIds, + failingUpkeepIds, + } + } + + beforeEach(async () => { + await loadFixture(setup) + }) + + describe('#transmit', () => { + const fArray = [1, 5, 10] + + it('reverts when registry is paused', async () => { + await registry.connect(owner).pause() + await evmRevert( + getTransmitTx(registry, keeper1, [upkeepId]), + 'RegistryPaused()', + ) + }) + + it('reverts when called by non active transmitter', async () => { + await evmRevert( + getTransmitTx(registry, payee1, [upkeepId]), + 'OnlyActiveTransmitters()', + ) + }) + + it('reverts when report data lengths mismatches', async () => { + const upkeepIds = [] + const gasLimits: BigNumber[] = [] + const triggers: string[] = [] + const performDatas = [] + + upkeepIds.push(upkeepId) + gasLimits.push(performGas) + triggers.push('0x') + performDatas.push('0x') + // Push an extra perform data + performDatas.push('0x') + + const report = encodeReport({ + fastGasWei: 0, + linkNative: 0, + upkeepIds, + gasLimits, + triggers, + performDatas, + }) + + await evmRevert( + getTransmitTxWithReport(registry, keeper1, report), + 'InvalidReport()', + ) + }) + + it('returns early when invalid upkeepIds are included in report', async () => { + const tx = await getTransmitTx(registry, keeper1, [ + upkeepId.add(BigNumber.from('1')), + ]) + + const receipt = await tx.wait() + const cancelledUpkeepReportLogs = parseCancelledUpkeepReportLogs(receipt) + // exactly 1 CancelledUpkeepReport log should be emitted + assert.equal(cancelledUpkeepReportLogs.length, 1) + }) + + it('performs even when the upkeep has insufficient funds and the upkeep pays out all the remaining balance', async () => { + // add very little fund to this upkeep + await registry.connect(admin).addFunds(upkeepId, BigNumber.from(10)) + const tx = await getTransmitTx(registry, keeper1, [upkeepId]) + const receipt = await tx.wait() + // the upkeep is underfunded in transmit but still performed + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + assert.equal(upkeepPerformedLogs.length, 1) + const balance = (await registry.getUpkeep(upkeepId)).balance + assert.equal(balance.toNumber(), 0) + }) + + context('When the upkeep is funded', async () => { + beforeEach(async () => { + // Fund the upkeep + await Promise.all([ + registry.connect(admin).addFunds(upkeepId, toWei('100')), + registry.connect(admin).addFunds(logUpkeepId, toWei('100')), + ]) + }) + + it('handles duplicate upkeepIDs', async () => { + const tests: [string, BigNumber, number, number][] = [ + // [name, upkeep, num stale, num performed] + ['conditional', upkeepId, 1, 1], // checkBlocks must be sequential + ['log-trigger', logUpkeepId, 0, 2], // logs are deduped based on the "trigger ID" + ] + for (const [type, id, nStale, nPerformed] of tests) { + const tx = await getTransmitTx(registry, keeper1, [id, id]) + const receipt = await tx.wait() + const staleUpkeepReport = parseStaleUpkeepReportLogs(receipt) + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + assert.equal( + staleUpkeepReport.length, + nStale, + `wrong log count for ${type} upkeep`, + ) + assert.equal( + upkeepPerformedLogs.length, + nPerformed, + `wrong log count for ${type} upkeep`, + ) + } + }) + + it('handles duplicate log triggers', async () => { + const logBlockHash = ethers.utils.randomBytes(32) + const txHash = ethers.utils.randomBytes(32) + const logIndex = 0 + const expectedDedupKey = ethers.utils.solidityKeccak256( + ['uint256', 'bytes32', 'bytes32', 'uint32'], + [logUpkeepId, logBlockHash, txHash, logIndex], + ) + assert.isFalse(await registry.hasDedupKey(expectedDedupKey)) + const tx = await getTransmitTx( + registry, + keeper1, + [logUpkeepId, logUpkeepId], + { logBlockHash, txHash, logIndex }, // will result in the same dedup key + ) + const receipt = await tx.wait() + const staleUpkeepReport = parseStaleUpkeepReportLogs(receipt) + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + assert.equal(staleUpkeepReport.length, 1) + assert.equal(upkeepPerformedLogs.length, 1) + assert.isTrue(await registry.hasDedupKey(expectedDedupKey)) + await expect(tx) + .to.emit(registry, 'DedupKeyAdded') + .withArgs(expectedDedupKey) + }) + + it('returns early when check block number is less than last perform (block)', async () => { + // First perform an upkeep to put last perform block number on upkeep state + const tx = await getTransmitTx(registry, keeper1, [upkeepId]) + await tx.wait() + const lastPerformed = (await registry.getUpkeep(upkeepId)) + .lastPerformedBlockNumber + const lastPerformBlock = await ethers.provider.getBlock(lastPerformed) + assert.equal(lastPerformed.toString(), tx.blockNumber?.toString()) + // Try to transmit a report which has checkBlockNumber = lastPerformed-1, should result in stale report + const transmitTx = await getTransmitTx(registry, keeper1, [upkeepId], { + checkBlockNum: lastPerformBlock.number - 1, + checkBlockHash: lastPerformBlock.parentHash, + }) + const receipt = await transmitTx.wait() + const staleUpkeepReportLogs = parseStaleUpkeepReportLogs(receipt) + // exactly 1 StaleUpkeepReportLogs log should be emitted + assert.equal(staleUpkeepReportLogs.length, 1) + }) + + it('handles case when check block hash does not match', async () => { + const tests: [string, BigNumber][] = [ + ['conditional', upkeepId], + ['log-trigger', logUpkeepId], + ] + for (const [type, id] of tests) { + const latestBlock = await ethers.provider.getBlock('latest') + // Try to transmit a report which has incorrect checkBlockHash + const tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: latestBlock.number - 1, + checkBlockHash: latestBlock.hash, // should be latestBlock.parentHash + }) + + const receipt = await tx.wait() + const reorgedUpkeepReportLogs = parseReorgedUpkeepReportLogs(receipt) + // exactly 1 ReorgedUpkeepReportLogs log should be emitted + assert.equal( + reorgedUpkeepReportLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + } + }) + + it('handles case when check block number is older than 256 blocks', async () => { + for (let i = 0; i < 256; i++) { + await ethers.provider.send('evm_mine', []) + } + const tests: [string, BigNumber][] = [ + ['conditional', upkeepId], + ['log-trigger', logUpkeepId], + ] + for (const [type, id] of tests) { + const latestBlock = await ethers.provider.getBlock('latest') + const old = await ethers.provider.getBlock(latestBlock.number - 256) + // Try to transmit a report which has incorrect checkBlockHash + const tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: old.number, + checkBlockHash: old.hash, + }) + + const receipt = await tx.wait() + const reorgedUpkeepReportLogs = parseReorgedUpkeepReportLogs(receipt) + // exactly 1 ReorgedUpkeepReportLogs log should be emitted + assert.equal( + reorgedUpkeepReportLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + } + }) + + it('allows bypassing reorg protection with empty blockhash', async () => { + const tests: [string, BigNumber][] = [ + ['conditional', upkeepId], + ['log-trigger', logUpkeepId], + ] + for (const [type, id] of tests) { + const latestBlock = await ethers.provider.getBlock('latest') + const tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: latestBlock.number, + checkBlockHash: emptyBytes32, + }) + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + assert.equal( + upkeepPerformedLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + } + }) + + it('allows bypassing reorg protection with reorgProtectionEnabled false config', async () => { + const tests: [string, BigNumber][] = [ + ['conditional', upkeepId], + ['log-trigger', logUpkeepId], + ] + let newConfig = config + newConfig.reorgProtectionEnabled = false + await registry // used to test initial configurations + .connect(owner) + .setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + newConfig, + offchainVersion, + offchainBytes, + ) + + for (const [type, id] of tests) { + const latestBlock = await ethers.provider.getBlock('latest') + // Try to transmit a report which has incorrect checkBlockHash + const tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: latestBlock.number - 1, + checkBlockHash: latestBlock.hash, // should be latestBlock.parentHash + }) + + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + assert.equal( + upkeepPerformedLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + } + }) + + it('allows very old trigger block numbers when bypassing reorg protection with reorgProtectionEnabled config', async () => { + let newConfig = config + newConfig.reorgProtectionEnabled = false + await registry // used to test initial configurations + .connect(owner) + .setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + newConfig, + offchainVersion, + offchainBytes, + ) + for (let i = 0; i < 256; i++) { + await ethers.provider.send('evm_mine', []) + } + const tests: [string, BigNumber][] = [ + ['conditional', upkeepId], + ['log-trigger', logUpkeepId], + ] + for (const [type, id] of tests) { + const latestBlock = await ethers.provider.getBlock('latest') + const old = await ethers.provider.getBlock(latestBlock.number - 256) + // Try to transmit a report which has incorrect checkBlockHash + const tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: old.number, + checkBlockHash: old.hash, + }) + + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + assert.equal( + upkeepPerformedLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + } + }) + + it('allows very old trigger block numbers when bypassing reorg protection with empty blockhash', async () => { + // mine enough blocks so that blockhash(1) is unavailable + for (let i = 0; i <= 256; i++) { + await ethers.provider.send('evm_mine', []) + } + const tests: [string, BigNumber][] = [ + ['conditional', upkeepId], + ['log-trigger', logUpkeepId], + ] + for (const [type, id] of tests) { + const tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: 1, + checkBlockHash: emptyBytes32, + }) + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + assert.equal( + upkeepPerformedLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + } + }) + + it('returns early when future block number is provided as trigger, irrespective of blockhash being present', async () => { + const tests: [string, BigNumber][] = [ + ['conditional', upkeepId], + ['log-trigger', logUpkeepId], + ] + for (const [type, id] of tests) { + const latestBlock = await ethers.provider.getBlock('latest') + + // Should fail when blockhash is empty + let tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: latestBlock.number + 100, + checkBlockHash: emptyBytes32, + }) + let receipt = await tx.wait() + let reorgedUpkeepReportLogs = parseReorgedUpkeepReportLogs(receipt) + // exactly 1 ReorgedUpkeepReportLogs log should be emitted + assert.equal( + reorgedUpkeepReportLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + + // Should also fail when blockhash is not empty + tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: latestBlock.number + 100, + checkBlockHash: latestBlock.hash, + }) + receipt = await tx.wait() + reorgedUpkeepReportLogs = parseReorgedUpkeepReportLogs(receipt) + // exactly 1 ReorgedUpkeepReportLogs log should be emitted + assert.equal( + reorgedUpkeepReportLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + } + }) + + it('returns early when future block number is provided as trigger, irrespective of reorgProtectionEnabled config', async () => { + let newConfig = config + newConfig.reorgProtectionEnabled = false + await registry // used to test initial configurations + .connect(owner) + .setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + newConfig, + offchainVersion, + offchainBytes, + ) + const tests: [string, BigNumber][] = [ + ['conditional', upkeepId], + ['log-trigger', logUpkeepId], + ] + for (const [type, id] of tests) { + const latestBlock = await ethers.provider.getBlock('latest') + + // Should fail when blockhash is empty + let tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: latestBlock.number + 100, + checkBlockHash: emptyBytes32, + }) + let receipt = await tx.wait() + let reorgedUpkeepReportLogs = parseReorgedUpkeepReportLogs(receipt) + // exactly 1 ReorgedUpkeepReportLogs log should be emitted + assert.equal( + reorgedUpkeepReportLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + + // Should also fail when blockhash is not empty + tx = await getTransmitTx(registry, keeper1, [id], { + checkBlockNum: latestBlock.number + 100, + checkBlockHash: latestBlock.hash, + }) + receipt = await tx.wait() + reorgedUpkeepReportLogs = parseReorgedUpkeepReportLogs(receipt) + // exactly 1 ReorgedUpkeepReportLogs log should be emitted + assert.equal( + reorgedUpkeepReportLogs.length, + 1, + `wrong log count for ${type} upkeep`, + ) + } + }) + + it('returns early when upkeep is cancelled and cancellation delay has gone', async () => { + const latestBlockReport = await makeLatestBlockReport([upkeepId]) + await registry.connect(admin).cancelUpkeep(upkeepId) + + for (let i = 0; i < cancellationDelay; i++) { + await ethers.provider.send('evm_mine', []) + } + + const tx = await getTransmitTxWithReport( + registry, + keeper1, + latestBlockReport, + ) + + const receipt = await tx.wait() + const cancelledUpkeepReportLogs = + parseCancelledUpkeepReportLogs(receipt) + // exactly 1 CancelledUpkeepReport log should be emitted + assert.equal(cancelledUpkeepReportLogs.length, 1) + }) + + it('does not revert if the target cannot execute', async () => { + await mock.setCanPerform(false) + const tx = await getTransmitTx(registry, keeper1, [upkeepId]) + + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + // exactly 1 Upkeep Performed should be emitted + assert.equal(upkeepPerformedLogs.length, 1) + const upkeepPerformedLog = upkeepPerformedLogs[0] + + const success = upkeepPerformedLog.args.success + assert.equal(success, false) + }) + + it('does not revert if the target runs out of gas', async () => { + await mock.setCanPerform(false) + + const tx = await getTransmitTx(registry, keeper1, [upkeepId], { + performGas: 10, // too little gas + }) + + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + // exactly 1 Upkeep Performed should be emitted + assert.equal(upkeepPerformedLogs.length, 1) + const upkeepPerformedLog = upkeepPerformedLogs[0] + + const success = upkeepPerformedLog.args.success + assert.equal(success, false) + }) + + it('reverts if not enough gas supplied', async () => { + await evmRevert( + getTransmitTx(registry, keeper1, [upkeepId], { + gasLimit: performGas, + }), + ) + }) + + it('executes the data passed to the registry', async () => { + await mock.setCanPerform(true) + + const tx = await getTransmitTx(registry, keeper1, [upkeepId], { + performDatas: [randomBytes], + }) + const receipt = await tx.wait() + + const upkeepPerformedWithABI = [ + 'event UpkeepPerformedWith(bytes upkeepData)', + ] + const iface = new ethers.utils.Interface(upkeepPerformedWithABI) + const parsedLogs = [] + for (let i = 0; i < receipt.logs.length; i++) { + const log = receipt.logs[i] + try { + parsedLogs.push(iface.parseLog(log)) + } catch (e) { + // ignore log + } + } + assert.equal(parsedLogs.length, 1) + assert.equal(parsedLogs[0].args.upkeepData, randomBytes) + }) + + it('uses actual execution price for payment and premium calculation', async () => { + // Actual multiplier is 2, but we set gasPrice to be 1x gasWei + const gasPrice = gasWei.mul(BigNumber.from('1')) + await mock.setCanPerform(true) + const registryPremiumBefore = (await registry.getState()).state + .totalPremium + const tx = await getTransmitTx(registry, keeper1, [upkeepId], { + gasPrice, + }) + const receipt = await tx.wait() + const registryPremiumAfter = (await registry.getState()).state + .totalPremium + const premium = registryPremiumAfter.sub(registryPremiumBefore) + + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + // exactly 1 Upkeep Performed should be emitted + assert.equal(upkeepPerformedLogs.length, 1) + const upkeepPerformedLog = upkeepPerformedLogs[0] + + const gasUsed = upkeepPerformedLog.args.gasUsed + const gasOverhead = upkeepPerformedLog.args.gasOverhead + const totalPayment = upkeepPerformedLog.args.totalPayment + + assert.equal( + linkForGas( + gasUsed, + gasOverhead, + BigNumber.from('1'), // Not the config multiplier, but the actual gas used + paymentPremiumPPB, + flatFeeMicroLink, + ).total.toString(), + totalPayment.toString(), + ) + + assert.equal( + linkForGas( + gasUsed, + gasOverhead, + BigNumber.from('1'), // Not the config multiplier, but the actual gas used + paymentPremiumPPB, + flatFeeMicroLink, + ).premium.toString(), + premium.toString(), + ) + }) + + it('only pays at a rate up to the gas ceiling [ @skip-coverage ]', async () => { + // Actual multiplier is 2, but we set gasPrice to be 10x + const gasPrice = gasWei.mul(BigNumber.from('10')) + await mock.setCanPerform(true) + + const tx = await getTransmitTx(registry, keeper1, [upkeepId], { + gasPrice, + }) + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + // exactly 1 Upkeep Performed should be emitted + assert.equal(upkeepPerformedLogs.length, 1) + const upkeepPerformedLog = upkeepPerformedLogs[0] + + const gasUsed = upkeepPerformedLog.args.gasUsed + const gasOverhead = upkeepPerformedLog.args.gasOverhead + const totalPayment = upkeepPerformedLog.args.totalPayment + + assert.equal( + linkForGas( + gasUsed, + gasOverhead, + gasCeilingMultiplier, // Should be same with exisitng multiplier + paymentPremiumPPB, + flatFeeMicroLink, + ).total.toString(), + totalPayment.toString(), + ) + }) + + it('correctly accounts for l payment', async () => { + await mock.setCanPerform(true) + // Same as MockArbGasInfo.sol + const l1CostWeiArb = BigNumber.from(1000000) + + let tx = await arbRegistry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,bytes,bytes)' + ](mock.address, performGas, await admin.getAddress(), randomBytes, '0x') + const testUpkeepId = await getUpkeepID(tx) + await arbRegistry.connect(owner).addFunds(testUpkeepId, toWei('100')) + + // Do the thing + tx = await getTransmitTx( + arbRegistry, + keeper1, + [testUpkeepId], + + { gasPrice: gasWei.mul('5') }, // High gas price so that it gets capped + ) + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + // exactly 1 Upkeep Performed should be emitted + assert.equal(upkeepPerformedLogs.length, 1) + const upkeepPerformedLog = upkeepPerformedLogs[0] + + const gasUsed = upkeepPerformedLog.args.gasUsed + const gasOverhead = upkeepPerformedLog.args.gasOverhead + const totalPayment = upkeepPerformedLog.args.totalPayment + + assert.equal( + linkForGas( + gasUsed, + gasOverhead, + gasCeilingMultiplier, + paymentPremiumPPB, + flatFeeMicroLink, + l1CostWeiArb, + ).total.toString(), + totalPayment.toString(), + ) + }) + + itMaybe('can self fund', async () => { + const maxPayment = await registry.getMaxPaymentForGas( + Trigger.CONDITION, + performGas, + ) + + // First set auto funding amount to 0 and verify that balance is deducted upon performUpkeep + let initialBalance = toWei('100') + await registry.connect(owner).addFunds(afUpkeepId, initialBalance) + await autoFunderUpkeep.setAutoFundLink(0) + await autoFunderUpkeep.setIsEligible(true) + await getTransmitTx(registry, keeper1, [afUpkeepId]) + + let postUpkeepBalance = (await registry.getUpkeep(afUpkeepId)).balance + assert.isTrue(postUpkeepBalance.lt(initialBalance)) // Balance should be deducted + assert.isTrue(postUpkeepBalance.gte(initialBalance.sub(maxPayment))) // Balance should not be deducted more than maxPayment + + // Now set auto funding amount to 100 wei and verify that the balance increases + initialBalance = postUpkeepBalance + const autoTopupAmount = toWei('100') + await autoFunderUpkeep.setAutoFundLink(autoTopupAmount) + await autoFunderUpkeep.setIsEligible(true) + await getTransmitTx(registry, keeper1, [afUpkeepId]) + + postUpkeepBalance = (await registry.getUpkeep(afUpkeepId)).balance + // Balance should increase by autoTopupAmount and decrease by max maxPayment + assert.isTrue( + postUpkeepBalance.gte( + initialBalance.add(autoTopupAmount).sub(maxPayment), + ), + ) + }) + + it('can self cancel', async () => { + await registry.connect(owner).addFunds(afUpkeepId, toWei('100')) + + await autoFunderUpkeep.setIsEligible(true) + await autoFunderUpkeep.setShouldCancel(true) + + let registration = await registry.getUpkeep(afUpkeepId) + const oldExpiration = registration.maxValidBlocknumber + + // Do the thing + await getTransmitTx(registry, keeper1, [afUpkeepId]) + + // Verify upkeep gets cancelled + registration = await registry.getUpkeep(afUpkeepId) + const newExpiration = registration.maxValidBlocknumber + assert.isTrue(newExpiration.lt(oldExpiration)) + }) + + it('reverts when configDigest mismatches', async () => { + const report = await makeLatestBlockReport([upkeepId]) + const reportContext = [emptyBytes32, epochAndRound5_1, emptyBytes32] // wrong config digest + const sigs = signReport(reportContext, report, signers.slice(0, f + 1)) + await evmRevert( + registry + .connect(keeper1) + .transmit( + [reportContext[0], reportContext[1], reportContext[2]], + report, + sigs.rs, + sigs.ss, + sigs.vs, + ), + 'ConfigDigestMismatch()', + ) + }) + + it('reverts with incorrect number of signatures', async () => { + const configDigest = (await registry.getState()).state + .latestConfigDigest + const report = await makeLatestBlockReport([upkeepId]) + const reportContext = [configDigest, epochAndRound5_1, emptyBytes32] // wrong config digest + const sigs = signReport(reportContext, report, signers.slice(0, f + 2)) + await evmRevert( + registry + .connect(keeper1) + .transmit( + [reportContext[0], reportContext[1], reportContext[2]], + report, + sigs.rs, + sigs.ss, + sigs.vs, + ), + 'IncorrectNumberOfSignatures()', + ) + }) + + it('reverts with invalid signature for inactive signers', async () => { + const configDigest = (await registry.getState()).state + .latestConfigDigest + const report = await makeLatestBlockReport([upkeepId]) + const reportContext = [configDigest, epochAndRound5_1, emptyBytes32] // wrong config digest + const sigs = signReport(reportContext, report, [ + new ethers.Wallet(ethers.Wallet.createRandom()), + new ethers.Wallet(ethers.Wallet.createRandom()), + ]) + await evmRevert( + registry + .connect(keeper1) + .transmit( + [reportContext[0], reportContext[1], reportContext[2]], + report, + sigs.rs, + sigs.ss, + sigs.vs, + ), + 'OnlyActiveSigners()', + ) + }) + + it('reverts with invalid signature for duplicated signers', async () => { + const configDigest = (await registry.getState()).state + .latestConfigDigest + const report = await makeLatestBlockReport([upkeepId]) + const reportContext = [configDigest, epochAndRound5_1, emptyBytes32] // wrong config digest + const sigs = signReport(reportContext, report, [signer1, signer1]) + await evmRevert( + registry + .connect(keeper1) + .transmit( + [reportContext[0], reportContext[1], reportContext[2]], + report, + sigs.rs, + sigs.ss, + sigs.vs, + ), + 'DuplicateSigners()', + ) + }) + + itMaybe( + 'has a large enough gas overhead to cover upkeep that use all its gas [ @skip-coverage ]', + async () => { + await registry.connect(owner).setConfigTypeSafe( + signerAddresses, + keeperAddresses, + 10, // maximise f to maximise overhead + config, + offchainVersion, + offchainBytes, + ) + const tx = await registry + .connect(owner) + ['registerUpkeep(address,uint32,address,bytes,bytes)']( + mock.address, + maxPerformGas, // max allowed gas + await admin.getAddress(), + randomBytes, + '0x', + ) + const testUpkeepId = await getUpkeepID(tx) + await registry.connect(admin).addFunds(testUpkeepId, toWei('100')) + + let performData = '0x' + for (let i = 0; i < maxPerformDataSize.toNumber(); i++) { + performData += '11' + } // max allowed performData + + await mock.setCanPerform(true) + await mock.setPerformGasToBurn(maxPerformGas) + + await getTransmitTx(registry, keeper1, [testUpkeepId], { + gasLimit: maxPerformGas.add(transmitGasOverhead), + numSigners: 11, + performDatas: [performData], + }) // Should not revert + }, + ) + + itMaybe( + 'performs upkeep, deducts payment, updates lastPerformed and emits events', + async () => { + await mock.setCanPerform(true) + + for (const i in fArray) { + const newF = fArray[i] + await registry + .connect(owner) + .setConfigTypeSafe( + signerAddresses, + keeperAddresses, + newF, + config, + offchainVersion, + offchainBytes, + ) + const checkBlock = await ethers.provider.getBlock('latest') + + const keeperBefore = await registry.getTransmitterInfo( + await keeper1.getAddress(), + ) + const registrationBefore = await registry.getUpkeep(upkeepId) + const registryPremiumBefore = (await registry.getState()).state + .totalPremium + const keeperLinkBefore = await linkToken.balanceOf( + await keeper1.getAddress(), + ) + const registryLinkBefore = await linkToken.balanceOf( + registry.address, + ) + + // Do the thing + const tx = await getTransmitTx(registry, keeper1, [upkeepId], { + checkBlockNum: checkBlock.number, + checkBlockHash: checkBlock.hash, + numSigners: newF + 1, + }) + + const receipt = await tx.wait() + + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + // exactly 1 Upkeep Performed should be emitted + assert.equal(upkeepPerformedLogs.length, 1) + const upkeepPerformedLog = upkeepPerformedLogs[0] + + const id = upkeepPerformedLog.args.id + const success = upkeepPerformedLog.args.success + const trigger = upkeepPerformedLog.args.trigger + const gasUsed = upkeepPerformedLog.args.gasUsed + const gasOverhead = upkeepPerformedLog.args.gasOverhead + const totalPayment = upkeepPerformedLog.args.totalPayment + assert.equal(id.toString(), upkeepId.toString()) + assert.equal(success, true) + assert.equal( + trigger, + encodeBlockTrigger({ + blockNum: checkBlock.number, + blockHash: checkBlock.hash, + }), + ) + assert.isTrue(gasUsed.gt(BigNumber.from('0'))) + assert.isTrue(gasOverhead.gt(BigNumber.from('0'))) + assert.isTrue(totalPayment.gt(BigNumber.from('0'))) + + const keeperAfter = await registry.getTransmitterInfo( + await keeper1.getAddress(), + ) + const registrationAfter = await registry.getUpkeep(upkeepId) + const keeperLinkAfter = await linkToken.balanceOf( + await keeper1.getAddress(), + ) + const registryLinkAfter = await linkToken.balanceOf( + registry.address, + ) + const registryPremiumAfter = (await registry.getState()).state + .totalPremium + const premium = registryPremiumAfter.sub(registryPremiumBefore) + // Keeper payment is gasPayment + premium / num keepers + const keeperPayment = totalPayment + .sub(premium) + .add(premium.div(BigNumber.from(keeperAddresses.length))) + + assert.equal( + keeperAfter.balance.sub(keeperPayment).toString(), + keeperBefore.balance.toString(), + ) + assert.equal( + registrationBefore.balance.sub(totalPayment).toString(), + registrationAfter.balance.toString(), + ) + assert.isTrue(keeperLinkAfter.eq(keeperLinkBefore)) + assert.isTrue(registryLinkBefore.eq(registryLinkAfter)) + + // Amount spent should be updated correctly + assert.equal( + registrationAfter.amountSpent.sub(totalPayment).toString(), + registrationBefore.amountSpent.toString(), + ) + assert.isTrue( + registrationAfter.amountSpent + .sub(registrationBefore.amountSpent) + .eq(registrationBefore.balance.sub(registrationAfter.balance)), + ) + // Last perform block number should be updated + assert.equal( + registrationAfter.lastPerformedBlockNumber.toString(), + tx.blockNumber?.toString(), + ) + + // Latest epoch should be 5 + assert.equal((await registry.getState()).state.latestEpoch, 5) + } + }, + ) + + // skipping it for now as it is passing in local but failing in CI + describe.skip('Gas benchmarking conditional upkeeps [ @skip-coverage ]', function () { + const fs = [1, 10] + fs.forEach(function (newF) { + it( + 'When f=' + + newF + + ' calculates gas overhead appropriately within a margin for different scenarios', + async () => { + // Perform the upkeep once to remove non-zero storage slots and have predictable gas measurement + let tx = await getTransmitTx(registry, keeper1, [upkeepId]) + await tx.wait() + + // Different test scenarios + let longBytes = '0x' + for (let i = 0; i < maxPerformDataSize.toNumber(); i++) { + longBytes += '11' + } + const upkeepSuccessArray = [true, false] + const performGasArray = [5000, performGas] + const performDataArray = ['0x', longBytes] + const chainModuleOverheads = + await chainModuleBase.getGasOverhead() + + for (const i in upkeepSuccessArray) { + for (const j in performGasArray) { + for (const k in performDataArray) { + const upkeepSuccess = upkeepSuccessArray[i] + const performGas = performGasArray[j] + const performData = performDataArray[k] + + await mock.setCanPerform(upkeepSuccess) + await mock.setPerformGasToBurn(performGas) + await registry + .connect(owner) + .setConfigTypeSafe( + signerAddresses, + keeperAddresses, + newF, + config, + offchainVersion, + offchainBytes, + ) + tx = await getTransmitTx(registry, keeper1, [upkeepId], { + numSigners: newF + 1, + performDatas: [performData], + }) + const receipt = await tx.wait() + const upkeepPerformedLogs = + parseUpkeepPerformedLogs(receipt) + // exactly 1 Upkeep Performed should be emitted + assert.equal(upkeepPerformedLogs.length, 1) + const upkeepPerformedLog = upkeepPerformedLogs[0] + + const upkeepGasUsed = upkeepPerformedLog.args.gasUsed + const chargedGasOverhead = + upkeepPerformedLog.args.gasOverhead + const actualGasOverhead = receipt.gasUsed.sub(upkeepGasUsed) + const estimatedGasOverhead = registryConditionalOverhead + .add( + registryPerSignerGasOverhead.mul( + BigNumber.from(newF + 1), + ), + ) + .add( + registryPerPerformByteGasOverhead + .add(chainModuleOverheads.chainModulePerByteOverhead) + .mul( + BigNumber.from(performData.length / 2 - 1) + .add(registryTransmitCalldataFixedBytesOverhead) + .add( + registryTransmitCalldataPerSignerBytesOverhead.mul( + BigNumber.from(newF + 1), + ), + ), + ), + ) + .add(chainModuleOverheads.chainModuleFixedOverhead) + + assert.isTrue(upkeepGasUsed.gt(BigNumber.from('0'))) + assert.isTrue(chargedGasOverhead.gt(BigNumber.from('0'))) + assert.isTrue(actualGasOverhead.gt(BigNumber.from('0'))) + + console.log( + 'Gas Benchmarking conditional upkeeps:', + 'upkeepSuccess=', + upkeepSuccess, + 'performGas=', + performGas.toString(), + 'performData length=', + performData.length / 2 - 1, + 'sig verification ( f =', + newF, + '): estimated overhead: ', + estimatedGasOverhead.toString(), + ' charged overhead: ', + chargedGasOverhead.toString(), + ' actual overhead: ', + actualGasOverhead.toString(), + ' calculation margin over gasUsed: ', + chargedGasOverhead.sub(actualGasOverhead).toString(), + ' estimation margin over gasUsed: ', + estimatedGasOverhead.sub(actualGasOverhead).toString(), + ) + + // The actual gas overhead should be less than charged gas overhead, but not by a lot + // The charged gas overhead is controlled by ACCOUNTING_FIXED_GAS_OVERHEAD and + // ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD, and their correct values should be set to + // satisfy constraints in multiple places + assert.isTrue( + chargedGasOverhead.gt(actualGasOverhead), + 'Gas overhead calculated is too low, increase account gas variables (ACCOUNTING_FIXED_GAS_OVERHEAD/ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD) by at least ' + + actualGasOverhead.sub(chargedGasOverhead).toString(), + ) + assert.isTrue( + chargedGasOverhead + .sub(actualGasOverhead) + .lt(gasCalculationMargin), + 'Gas overhead calculated is too high, decrease account gas variables (ACCOUNTING_FIXED_GAS_OVERHEAD/ACCOUNTING_PER_SIGNER_GAS_OVERHEAD) by at least ' + + chargedGasOverhead + .sub(actualGasOverhead) + .sub(gasCalculationMargin) + .toString(), + ) + + // The estimated overhead during checkUpkeep should be close to the actual overhead in transaction + // It should be greater than the actual overhead but not by a lot + // The estimated overhead is controlled by variables + // REGISTRY_CONDITIONAL_OVERHEAD, REGISTRY_LOG_OVERHEAD, REGISTRY_PER_SIGNER_GAS_OVERHEAD + // REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD + assert.isTrue( + estimatedGasOverhead.gt(actualGasOverhead), + 'Gas overhead estimated in check upkeep is too low, increase estimation gas variables (REGISTRY_CONDITIONAL_OVERHEAD/REGISTRY_LOG_OVERHEAD/REGISTRY_PER_SIGNER_GAS_OVERHEAD/REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD) by at least ' + + estimatedGasOverhead.sub(chargedGasOverhead).toString(), + ) + assert.isTrue( + estimatedGasOverhead + .sub(actualGasOverhead) + .lt(gasEstimationMargin), + 'Gas overhead estimated is too high, decrease estimation gas variables (REGISTRY_CONDITIONAL_OVERHEAD/REGISTRY_LOG_OVERHEAD/REGISTRY_PER_SIGNER_GAS_OVERHEAD/REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD) by at least ' + + estimatedGasOverhead + .sub(actualGasOverhead) + .sub(gasEstimationMargin) + .toString(), + ) + } + } + } + }, + ) + }) + }) + + describe('Gas benchmarking log upkeeps [ @skip-coverage ]', function () { + const fs = [1, 10] + fs.forEach(function (newF) { + it( + 'When f=' + + newF + + ' calculates gas overhead appropriately within a margin', + async () => { + // Perform the upkeep once to remove non-zero storage slots and have predictable gas measurement + let tx = await getTransmitTx(registry, keeper1, [logUpkeepId]) + await tx.wait() + const performData = '0x' + await mock.setCanPerform(true) + await mock.setPerformGasToBurn(performGas) + await registry.setConfigTypeSafe( + signerAddresses, + keeperAddresses, + newF, + config, + offchainVersion, + offchainBytes, + ) + tx = await getTransmitTx(registry, keeper1, [logUpkeepId], { + numSigners: newF + 1, + performDatas: [performData], + }) + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + // exactly 1 Upkeep Performed should be emitted + assert.equal(upkeepPerformedLogs.length, 1) + const upkeepPerformedLog = upkeepPerformedLogs[0] + const chainModuleOverheads = + await chainModuleBase.getGasOverhead() + + const upkeepGasUsed = upkeepPerformedLog.args.gasUsed + const chargedGasOverhead = upkeepPerformedLog.args.gasOverhead + const actualGasOverhead = receipt.gasUsed.sub(upkeepGasUsed) + const estimatedGasOverhead = registryLogOverhead + .add(registryPerSignerGasOverhead.mul(BigNumber.from(newF + 1))) + .add( + registryPerPerformByteGasOverhead + .add(chainModuleOverheads.chainModulePerByteOverhead) + .mul( + BigNumber.from(performData.length / 2 - 1) + .add(registryTransmitCalldataFixedBytesOverhead) + .add( + registryTransmitCalldataPerSignerBytesOverhead.mul( + BigNumber.from(newF + 1), + ), + ), + ), + ) + .add(chainModuleOverheads.chainModuleFixedOverhead) + + assert.isTrue(upkeepGasUsed.gt(BigNumber.from('0'))) + assert.isTrue(chargedGasOverhead.gt(BigNumber.from('0'))) + assert.isTrue(actualGasOverhead.gt(BigNumber.from('0'))) + + console.log( + 'Gas Benchmarking log upkeeps:', + 'upkeepSuccess=', + true, + 'performGas=', + performGas.toString(), + 'performData length=', + performData.length / 2 - 1, + 'sig verification ( f =', + newF, + '): estimated overhead: ', + estimatedGasOverhead.toString(), + ' charged overhead: ', + chargedGasOverhead.toString(), + ' actual overhead: ', + actualGasOverhead.toString(), + ' calculation margin over gasUsed: ', + chargedGasOverhead.sub(actualGasOverhead).toString(), + ' estimation margin over gasUsed: ', + estimatedGasOverhead.sub(actualGasOverhead).toString(), + ) + + assert.isTrue( + chargedGasOverhead.gt(actualGasOverhead), + 'Gas overhead calculated is too low, increase account gas variables (ACCOUNTING_FIXED_GAS_OVERHEAD/ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD) by at least ' + + actualGasOverhead.sub(chargedGasOverhead).toString(), + ) + assert.isTrue( + chargedGasOverhead + .sub(actualGasOverhead) + .lt(gasCalculationMargin), + 'Gas overhead calculated is too high, decrease account gas variables (ACCOUNTING_FIXED_GAS_OVERHEAD/ACCOUNTING_PER_SIGNER_GAS_OVERHEAD) by at least ' + + chargedGasOverhead + .sub(actualGasOverhead) + .sub(gasCalculationMargin) + .toString(), + ) + + assert.isTrue( + estimatedGasOverhead.gt(actualGasOverhead), + 'Gas overhead estimated in check upkeep is too low, increase estimation gas variables (REGISTRY_CONDITIONAL_OVERHEAD/REGISTRY_LOG_OVERHEAD/REGISTRY_PER_SIGNER_GAS_OVERHEAD/REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD) by at least ' + + estimatedGasOverhead.sub(chargedGasOverhead).toString(), + ) + assert.isTrue( + estimatedGasOverhead + .sub(actualGasOverhead) + .lt(gasEstimationMargin), + 'Gas overhead estimated is too high, decrease estimation gas variables (REGISTRY_CONDITIONAL_OVERHEAD/REGISTRY_LOG_OVERHEAD/REGISTRY_PER_SIGNER_GAS_OVERHEAD/REGISTRY_PER_PERFORM_BYTE_GAS_OVERHEAD) by at least ' + + estimatedGasOverhead + .sub(actualGasOverhead) + .sub(gasEstimationMargin) + .toString(), + ) + }, + ) + }) + }) + }) + }) + + describe('#transmit with upkeep batches [ @skip-coverage ]', function () { + const numPassingConditionalUpkeepsArray = [0, 1, 5] + const numPassingLogUpkeepsArray = [0, 1, 5] + const numFailingUpkeepsArray = [0, 3] + + for (let idx = 0; idx < numPassingConditionalUpkeepsArray.length; idx++) { + for (let jdx = 0; jdx < numPassingLogUpkeepsArray.length; jdx++) { + for (let kdx = 0; kdx < numFailingUpkeepsArray.length; kdx++) { + const numPassingConditionalUpkeeps = + numPassingConditionalUpkeepsArray[idx] + const numPassingLogUpkeeps = numPassingLogUpkeepsArray[jdx] + const numFailingUpkeeps = numFailingUpkeepsArray[kdx] + if (numPassingConditionalUpkeeps == 0 && numPassingLogUpkeeps == 0) { + continue + } + it( + '[Conditional:' + + numPassingConditionalUpkeeps + + ',Log:' + + numPassingLogUpkeeps + + ',Failures:' + + numFailingUpkeeps + + '] performs successful upkeeps and does not charge failing upkeeps', + async () => { + const allUpkeeps = await getMultipleUpkeepsDeployedAndFunded( + numPassingConditionalUpkeeps, + numPassingLogUpkeeps, + numFailingUpkeeps, + ) + const passingConditionalUpkeepIds = + allUpkeeps.passingConditionalUpkeepIds + const passingLogUpkeepIds = allUpkeeps.passingLogUpkeepIds + const failingUpkeepIds = allUpkeeps.failingUpkeepIds + + const keeperBefore = await registry.getTransmitterInfo( + await keeper1.getAddress(), + ) + const keeperLinkBefore = await linkToken.balanceOf( + await keeper1.getAddress(), + ) + const registryLinkBefore = await linkToken.balanceOf( + registry.address, + ) + const registryPremiumBefore = (await registry.getState()).state + .totalPremium + const registrationConditionalPassingBefore = await Promise.all( + passingConditionalUpkeepIds.map(async (id) => { + const reg = await registry.getUpkeep(BigNumber.from(id)) + assert.equal(reg.lastPerformedBlockNumber.toString(), '0') + return reg + }), + ) + const registrationLogPassingBefore = await Promise.all( + passingLogUpkeepIds.map(async (id) => { + const reg = await registry.getUpkeep(BigNumber.from(id)) + assert.equal(reg.lastPerformedBlockNumber.toString(), '0') + return reg + }), + ) + const registrationFailingBefore = await Promise.all( + failingUpkeepIds.map(async (id) => { + const reg = await registry.getUpkeep(BigNumber.from(id)) + assert.equal(reg.lastPerformedBlockNumber.toString(), '0') + return reg + }), + ) + + // cancel upkeeps so they will fail in the transmit process + // must call the cancel upkeep as the owner to avoid the CANCELLATION_DELAY + for (let ldx = 0; ldx < failingUpkeepIds.length; ldx++) { + await registry + .connect(owner) + .cancelUpkeep(failingUpkeepIds[ldx]) + } + + const tx = await getTransmitTx( + registry, + keeper1, + passingConditionalUpkeepIds.concat( + passingLogUpkeepIds.concat(failingUpkeepIds), + ), + ) + + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + // exactly numPassingUpkeeps Upkeep Performed should be emitted + assert.equal( + upkeepPerformedLogs.length, + numPassingConditionalUpkeeps + numPassingLogUpkeeps, + ) + const cancelledUpkeepReportLogs = + parseCancelledUpkeepReportLogs(receipt) + // exactly numFailingUpkeeps Upkeep Performed should be emitted + assert.equal(cancelledUpkeepReportLogs.length, numFailingUpkeeps) + + const keeperAfter = await registry.getTransmitterInfo( + await keeper1.getAddress(), + ) + const keeperLinkAfter = await linkToken.balanceOf( + await keeper1.getAddress(), + ) + const registryLinkAfter = await linkToken.balanceOf( + registry.address, + ) + const registrationConditionalPassingAfter = await Promise.all( + passingConditionalUpkeepIds.map(async (id) => { + return await registry.getUpkeep(BigNumber.from(id)) + }), + ) + const registrationLogPassingAfter = await Promise.all( + passingLogUpkeepIds.map(async (id) => { + return await registry.getUpkeep(BigNumber.from(id)) + }), + ) + const registrationFailingAfter = await Promise.all( + failingUpkeepIds.map(async (id) => { + return await registry.getUpkeep(BigNumber.from(id)) + }), + ) + const registryPremiumAfter = (await registry.getState()).state + .totalPremium + const premium = registryPremiumAfter.sub(registryPremiumBefore) + + let netPayment = BigNumber.from('0') + for (let i = 0; i < numPassingConditionalUpkeeps; i++) { + const id = upkeepPerformedLogs[i].args.id + const gasUsed = upkeepPerformedLogs[i].args.gasUsed + const gasOverhead = upkeepPerformedLogs[i].args.gasOverhead + const totalPayment = upkeepPerformedLogs[i].args.totalPayment + + expect(id).to.equal(passingConditionalUpkeepIds[i]) + assert.isTrue(gasUsed.gt(BigNumber.from('0'))) + assert.isTrue(gasOverhead.gt(BigNumber.from('0'))) + assert.isTrue(totalPayment.gt(BigNumber.from('0'))) + + // Balance should be deducted + assert.equal( + registrationConditionalPassingBefore[i].balance + .sub(totalPayment) + .toString(), + registrationConditionalPassingAfter[i].balance.toString(), + ) + + // Amount spent should be updated correctly + assert.equal( + registrationConditionalPassingAfter[i].amountSpent + .sub(totalPayment) + .toString(), + registrationConditionalPassingBefore[ + i + ].amountSpent.toString(), + ) + + // Last perform block number should be updated + assert.equal( + registrationConditionalPassingAfter[ + i + ].lastPerformedBlockNumber.toString(), + tx.blockNumber?.toString(), + ) + + netPayment = netPayment.add(totalPayment) + } + + for (let i = 0; i < numPassingLogUpkeeps; i++) { + const id = + upkeepPerformedLogs[numPassingConditionalUpkeeps + i].args.id + const gasUsed = + upkeepPerformedLogs[numPassingConditionalUpkeeps + i].args + .gasUsed + const gasOverhead = + upkeepPerformedLogs[numPassingConditionalUpkeeps + i].args + .gasOverhead + const totalPayment = + upkeepPerformedLogs[numPassingConditionalUpkeeps + i].args + .totalPayment + + expect(id).to.equal(passingLogUpkeepIds[i]) + assert.isTrue(gasUsed.gt(BigNumber.from('0'))) + assert.isTrue(gasOverhead.gt(BigNumber.from('0'))) + assert.isTrue(totalPayment.gt(BigNumber.from('0'))) + + // Balance should be deducted + assert.equal( + registrationLogPassingBefore[i].balance + .sub(totalPayment) + .toString(), + registrationLogPassingAfter[i].balance.toString(), + ) + + // Amount spent should be updated correctly + assert.equal( + registrationLogPassingAfter[i].amountSpent + .sub(totalPayment) + .toString(), + registrationLogPassingBefore[i].amountSpent.toString(), + ) + + // Last perform block number should not be updated for log triggers + assert.equal( + registrationLogPassingAfter[ + i + ].lastPerformedBlockNumber.toString(), + '0', + ) + + netPayment = netPayment.add(totalPayment) + } + + for (let i = 0; i < numFailingUpkeeps; i++) { + // CancelledUpkeep log should be emitted + const id = cancelledUpkeepReportLogs[i].args.id + expect(id).to.equal(failingUpkeepIds[i]) + + // Balance and amount spent should be same + assert.equal( + registrationFailingBefore[i].balance.toString(), + registrationFailingAfter[i].balance.toString(), + ) + assert.equal( + registrationFailingBefore[i].amountSpent.toString(), + registrationFailingAfter[i].amountSpent.toString(), + ) + + // Last perform block number should not be updated + assert.equal( + registrationFailingAfter[ + i + ].lastPerformedBlockNumber.toString(), + '0', + ) + } + + // Keeper payment is gasPayment + premium / num keepers + const keeperPayment = netPayment + .sub(premium) + .add(premium.div(BigNumber.from(keeperAddresses.length))) + + // Keeper should be paid net payment for all passed upkeeps + assert.equal( + keeperAfter.balance.sub(keeperPayment).toString(), + keeperBefore.balance.toString(), + ) + + assert.isTrue(keeperLinkAfter.eq(keeperLinkBefore)) + assert.isTrue(registryLinkBefore.eq(registryLinkAfter)) + }, + ) + + it( + '[Conditional:' + + numPassingConditionalUpkeeps + + ',Log' + + numPassingLogUpkeeps + + ',Failures:' + + numFailingUpkeeps + + '] splits gas overhead appropriately among performed upkeeps [ @skip-coverage ]', + async () => { + const allUpkeeps = await getMultipleUpkeepsDeployedAndFunded( + numPassingConditionalUpkeeps, + numPassingLogUpkeeps, + numFailingUpkeeps, + ) + const passingConditionalUpkeepIds = + allUpkeeps.passingConditionalUpkeepIds + const passingLogUpkeepIds = allUpkeeps.passingLogUpkeepIds + const failingUpkeepIds = allUpkeeps.failingUpkeepIds + + // Perform the upkeeps once to remove non-zero storage slots and have predictable gas measurement + let tx = await getTransmitTx( + registry, + keeper1, + passingConditionalUpkeepIds.concat( + passingLogUpkeepIds.concat(failingUpkeepIds), + ), + ) + + await tx.wait() + + // cancel upkeeps so they will fail in the transmit process + // must call the cancel upkeep as the owner to avoid the CANCELLATION_DELAY + for (let ldx = 0; ldx < failingUpkeepIds.length; ldx++) { + await registry + .connect(owner) + .cancelUpkeep(failingUpkeepIds[ldx]) + } + + // Do the actual thing + + tx = await getTransmitTx( + registry, + keeper1, + passingConditionalUpkeepIds.concat( + passingLogUpkeepIds.concat(failingUpkeepIds), + ), + ) + + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + // exactly numPassingUpkeeps Upkeep Performed should be emitted + assert.equal( + upkeepPerformedLogs.length, + numPassingConditionalUpkeeps + numPassingLogUpkeeps, + ) + + let netGasUsedPlusChargedOverhead = BigNumber.from('0') + for (let i = 0; i < numPassingConditionalUpkeeps; i++) { + const gasUsed = upkeepPerformedLogs[i].args.gasUsed + const chargedGasOverhead = + upkeepPerformedLogs[i].args.gasOverhead + + assert.isTrue(gasUsed.gt(BigNumber.from('0'))) + assert.isTrue(chargedGasOverhead.gt(BigNumber.from('0'))) + + // Overhead should be same for every upkeep + assert.isTrue( + chargedGasOverhead.eq( + upkeepPerformedLogs[0].args.gasOverhead, + ), + ) + netGasUsedPlusChargedOverhead = netGasUsedPlusChargedOverhead + .add(gasUsed) + .add(chargedGasOverhead) + } + + for (let i = 0; i < numPassingLogUpkeeps; i++) { + const gasUsed = + upkeepPerformedLogs[numPassingConditionalUpkeeps + i].args + .gasUsed + const chargedGasOverhead = + upkeepPerformedLogs[numPassingConditionalUpkeeps + i].args + .gasOverhead + + assert.isTrue(gasUsed.gt(BigNumber.from('0'))) + assert.isTrue(chargedGasOverhead.gt(BigNumber.from('0'))) + + // Overhead should be same for every upkeep + assert.isTrue( + chargedGasOverhead.eq( + upkeepPerformedLogs[numPassingConditionalUpkeeps].args + .gasOverhead, + ), + ) + netGasUsedPlusChargedOverhead = netGasUsedPlusChargedOverhead + .add(gasUsed) + .add(chargedGasOverhead) + } + + console.log( + 'Gas Benchmarking - batching (passedConditionalUpkeeps: ', + numPassingConditionalUpkeeps, + 'passedLogUpkeeps:', + numPassingLogUpkeeps, + 'failedUpkeeps:', + numFailingUpkeeps, + '): ', + numPassingConditionalUpkeeps > 0 + ? 'charged conditional overhead' + : '', + numPassingConditionalUpkeeps > 0 + ? upkeepPerformedLogs[0].args.gasOverhead.toString() + : '', + numPassingLogUpkeeps > 0 ? 'charged log overhead' : '', + numPassingLogUpkeeps > 0 + ? upkeepPerformedLogs[ + numPassingConditionalUpkeeps + ].args.gasOverhead.toString() + : '', + ' margin over gasUsed', + netGasUsedPlusChargedOverhead.sub(receipt.gasUsed).toString(), + ) + + // The total gas charged should be greater than tx gas + assert.isTrue( + netGasUsedPlusChargedOverhead.gt(receipt.gasUsed), + 'Charged gas overhead is too low for batch upkeeps, increase ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD', + ) + }, + ) + } + } + } + + it('has enough perform gas overhead for large batches [ @skip-coverage ]', async () => { + const numUpkeeps = 20 + const upkeepIds: BigNumber[] = [] + let totalPerformGas = BigNumber.from('0') + for (let i = 0; i < numUpkeeps; i++) { + const mock = await upkeepMockFactory.deploy() + const tx = await registry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,bytes,bytes)' + ](mock.address, performGas, await admin.getAddress(), randomBytes, '0x') + const testUpkeepId = await getUpkeepID(tx) + upkeepIds.push(testUpkeepId) + + // Add funds to passing upkeeps + await registry.connect(owner).addFunds(testUpkeepId, toWei('10')) + + await mock.setCanPerform(true) + await mock.setPerformGasToBurn(performGas) + + totalPerformGas = totalPerformGas.add(performGas) + } + + // Should revert with no overhead added + await evmRevert( + getTransmitTx(registry, keeper1, upkeepIds, { + gasLimit: totalPerformGas, + }), + ) + // Should not revert with overhead added + await getTransmitTx(registry, keeper1, upkeepIds, { + gasLimit: totalPerformGas.add(transmitGasOverhead), + }) + }) + + it('splits l2 payment among performed upkeeps according to perform data weight', async () => { + const numUpkeeps = 7 + const upkeepIds: BigNumber[] = [] + const performDataSizes = [0, 10, 1000, 50, 33, 69, 420] + const performDatas: string[] = [] + const upkeepCalldataWeights: BigNumber[] = [] + let totalCalldataWeight = BigNumber.from('0') + // Same as MockArbGasInfo.sol + const l1CostWeiArb = BigNumber.from(1000000) + + for (let i = 0; i < numUpkeeps; i++) { + const mock = await upkeepMockFactory.deploy() + const tx = await arbRegistry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,bytes,bytes)' + ](mock.address, performGas, await admin.getAddress(), randomBytes, '0x') + const testUpkeepId = await getUpkeepID(tx) + upkeepIds.push(testUpkeepId) + + // Add funds to passing upkeeps + await arbRegistry.connect(owner).addFunds(testUpkeepId, toWei('100')) + + // Generate performData + let pd = '0x' + for (let j = 0; j < performDataSizes[i]; j++) { + pd += '11' + } + performDatas.push(pd) + const w = BigNumber.from(performDataSizes[i]) + .add(registryTransmitCalldataFixedBytesOverhead) + .add( + registryTransmitCalldataPerSignerBytesOverhead.mul( + BigNumber.from(f + 1), + ), + ) + upkeepCalldataWeights.push(w) + totalCalldataWeight = totalCalldataWeight.add(w) + } + + // Do the thing + const tx = await getTransmitTx(arbRegistry, keeper1, upkeepIds, { + gasPrice: gasWei.mul('5'), // High gas price so that it gets capped + performDatas, + }) + + const receipt = await tx.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + // exactly numPassingUpkeeps Upkeep Performed should be emitted + assert.equal(upkeepPerformedLogs.length, numUpkeeps) + + for (let i = 0; i < numUpkeeps; i++) { + const upkeepPerformedLog = upkeepPerformedLogs[i] + + const gasUsed = upkeepPerformedLog.args.gasUsed + const gasOverhead = upkeepPerformedLog.args.gasOverhead + const totalPayment = upkeepPerformedLog.args.totalPayment + + assert.equal( + linkForGas( + gasUsed, + gasOverhead, + gasCeilingMultiplier, + paymentPremiumPPB, + flatFeeMicroLink, + l1CostWeiArb.mul(upkeepCalldataWeights[i]).div(totalCalldataWeight), + ).total.toString(), + totalPayment.toString(), + ) + } + }) + }) + + describe('#recoverFunds', () => { + const sent = toWei('7') + + beforeEach(async () => { + await linkToken.connect(admin).approve(registry.address, toWei('100')) + await linkToken + .connect(owner) + .transfer(await keeper1.getAddress(), toWei('1000')) + + // add funds to upkeep 1 and perform and withdraw some payment + const tx = await registry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,bytes,bytes)' + ](mock.address, performGas, await admin.getAddress(), emptyBytes, emptyBytes) + + const id1 = await getUpkeepID(tx) + await registry.connect(admin).addFunds(id1, toWei('5')) + + await getTransmitTx(registry, keeper1, [id1]) + await getTransmitTx(registry, keeper2, [id1]) + await getTransmitTx(registry, keeper3, [id1]) + + await registry + .connect(payee1) + .withdrawPayment( + await keeper1.getAddress(), + await nonkeeper.getAddress(), + ) + + // transfer funds directly to the registry + await linkToken.connect(keeper1).transfer(registry.address, sent) + + // add funds to upkeep 2 and perform and withdraw some payment + const tx2 = await registry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,bytes,bytes)' + ](mock.address, performGas, await admin.getAddress(), emptyBytes, emptyBytes) + const id2 = await getUpkeepID(tx2) + await registry.connect(admin).addFunds(id2, toWei('5')) + + await getTransmitTx(registry, keeper1, [id2]) + await getTransmitTx(registry, keeper2, [id2]) + await getTransmitTx(registry, keeper3, [id2]) + + await registry + .connect(payee2) + .withdrawPayment( + await keeper2.getAddress(), + await nonkeeper.getAddress(), + ) + + // transfer funds using onTokenTransfer + const data = ethers.utils.defaultAbiCoder.encode(['uint256'], [id2]) + await linkToken + .connect(owner) + .transferAndCall(registry.address, toWei('1'), data) + + // withdraw some funds + await registry.connect(owner).cancelUpkeep(id1) + await registry + .connect(admin) + .withdrawFunds(id1, await nonkeeper.getAddress()) + }) + + it('reverts if not called by owner', async () => { + await evmRevert( + registry.connect(keeper1).recoverFunds(), + 'Only callable by owner', + ) + }) + + it('allows any funds that have been accidentally transfered to be moved', async () => { + const balanceBefore = await linkToken.balanceOf(registry.address) + const ownerBefore = await linkToken.balanceOf(await owner.getAddress()) + + await registry.connect(owner).recoverFunds() + + const balanceAfter = await linkToken.balanceOf(registry.address) + const ownerAfter = await linkToken.balanceOf(await owner.getAddress()) + + assert.isTrue(balanceBefore.eq(balanceAfter.add(sent))) + assert.isTrue(ownerAfter.eq(ownerBefore.add(sent))) + }) + }) + + describe('#getMinBalanceForUpkeep / #checkUpkeep / #transmit', () => { + it('calculates the minimum balance appropriately', async () => { + await mock.setCanCheck(true) + + const oneWei = BigNumber.from(1) + const minBalance = await registry.getMinBalanceForUpkeep(upkeepId) + const tooLow = minBalance.sub(oneWei) + + await registry.connect(admin).addFunds(upkeepId, tooLow) + let checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + + assert.equal(checkUpkeepResult.upkeepNeeded, false) + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.INSUFFICIENT_BALANCE, + ) + + await registry.connect(admin).addFunds(upkeepId, oneWei) + checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + assert.equal(checkUpkeepResult.upkeepNeeded, true) + }) + + it('uses maxPerformData size in checkUpkeep but actual performDataSize in transmit', async () => { + const tx = await registry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,bytes,bytes)' + ](mock.address, performGas, await admin.getAddress(), randomBytes, '0x') + const upkeepID = await getUpkeepID(tx) + await mock.setCanCheck(true) + await mock.setCanPerform(true) + + // upkeep is underfunded by 1 wei + const minBalance1 = (await registry.getMinBalanceForUpkeep(upkeepID)).sub( + 1, + ) + await registry.connect(owner).addFunds(upkeepID, minBalance1) + + // upkeep check should return false, 2 should return true + let checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepID) + assert.equal(checkUpkeepResult.upkeepNeeded, false) + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.INSUFFICIENT_BALANCE, + ) + + // however upkeep should perform and pay all the remaining balance + let maxPerformData = '0x' + for (let i = 0; i < maxPerformDataSize.toNumber(); i++) { + maxPerformData += '11' + } + + const tx2 = await getTransmitTx(registry, keeper1, [upkeepID], { + gasPrice: gasWei.mul(gasCeilingMultiplier), + performDatas: [maxPerformData], + }) + + const receipt = await tx2.wait() + const upkeepPerformedLogs = parseUpkeepPerformedLogs(receipt) + assert.equal(upkeepPerformedLogs.length, 1) + }) + }) + + describe('#withdrawFunds', () => { + let upkeepId2: BigNumber + + beforeEach(async () => { + const tx = await registry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,bytes,bytes)' + ](mock.address, performGas, await admin.getAddress(), randomBytes, '0x') + upkeepId2 = await getUpkeepID(tx) + + await registry.connect(admin).addFunds(upkeepId, toWei('100')) + await registry.connect(admin).addFunds(upkeepId2, toWei('100')) + + // Do a perform so that upkeep is charged some amount + await getTransmitTx(registry, keeper1, [upkeepId]) + await getTransmitTx(registry, keeper1, [upkeepId2]) + }) + + it('reverts if called on a non existing ID', async () => { + await evmRevert( + registry + .connect(admin) + .withdrawFunds(upkeepId.add(1), await payee1.getAddress()), + 'OnlyCallableByAdmin()', + ) + }) + + it('reverts if called by anyone but the admin', async () => { + await evmRevert( + registry + .connect(owner) + .withdrawFunds(upkeepId, await payee1.getAddress()), + 'OnlyCallableByAdmin()', + ) + }) + + it('reverts if called on an uncanceled upkeep', async () => { + await evmRevert( + registry + .connect(admin) + .withdrawFunds(upkeepId, await payee1.getAddress()), + 'UpkeepNotCanceled()', + ) + }) + + it('reverts if called with the 0 address', async () => { + await evmRevert( + registry.connect(admin).withdrawFunds(upkeepId, zeroAddress), + 'InvalidRecipient()', + ) + }) + + describe('after the registration is paused, then cancelled', () => { + it('allows the admin to withdraw', async () => { + const balance = await registry.getBalance(upkeepId) + const payee = await payee1.getAddress() + await registry.connect(admin).pauseUpkeep(upkeepId) + await registry.connect(owner).cancelUpkeep(upkeepId) + await expect(() => + registry.connect(admin).withdrawFunds(upkeepId, payee), + ).to.changeTokenBalance(linkToken, payee1, balance) + }) + }) + + describe('after the registration is cancelled', () => { + beforeEach(async () => { + await registry.connect(owner).cancelUpkeep(upkeepId) + await registry.connect(owner).cancelUpkeep(upkeepId2) + }) + + it('can be called successively on two upkeeps', async () => { + await registry + .connect(admin) + .withdrawFunds(upkeepId, await payee1.getAddress()) + await registry + .connect(admin) + .withdrawFunds(upkeepId2, await payee1.getAddress()) + }) + + it('moves the funds out and updates the balance and emits an event', async () => { + const payee1Before = await linkToken.balanceOf( + await payee1.getAddress(), + ) + const registryBefore = await linkToken.balanceOf(registry.address) + + let registration = await registry.getUpkeep(upkeepId) + const previousBalance = registration.balance + + const tx = await registry + .connect(admin) + .withdrawFunds(upkeepId, await payee1.getAddress()) + await expect(tx) + .to.emit(registry, 'FundsWithdrawn') + .withArgs(upkeepId, previousBalance, await payee1.getAddress()) + + const payee1After = await linkToken.balanceOf(await payee1.getAddress()) + const registryAfter = await linkToken.balanceOf(registry.address) + + assert.isTrue(payee1Before.add(previousBalance).eq(payee1After)) + assert.isTrue(registryBefore.sub(previousBalance).eq(registryAfter)) + + registration = await registry.getUpkeep(upkeepId) + assert.equal(registration.balance.toNumber(), 0) + }) + }) + }) + + describe('#simulatePerformUpkeep', () => { + it('reverts if called by non zero address', async () => { + await evmRevert( + registry + .connect(await owner.getAddress()) + .callStatic.simulatePerformUpkeep(upkeepId, '0x'), + 'OnlySimulatedBackend()', + ) + }) + + it('reverts when registry is paused', async () => { + await registry.connect(owner).pause() + await evmRevert( + registry + .connect(zeroAddress) + .callStatic.simulatePerformUpkeep(upkeepId, '0x'), + 'RegistryPaused()', + ) + }) + + it('returns false and gasUsed when perform fails', async () => { + await mock.setCanPerform(false) + + const simulatePerformResult = await registry + .connect(zeroAddress) + .callStatic.simulatePerformUpkeep(upkeepId, '0x') + + assert.equal(simulatePerformResult.success, false) + assert.isTrue(simulatePerformResult.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + }) + + it('returns true, gasUsed, and performGas when perform succeeds', async () => { + await mock.setCanPerform(true) + + const simulatePerformResult = await registry + .connect(zeroAddress) + .callStatic.simulatePerformUpkeep(upkeepId, '0x') + + assert.equal(simulatePerformResult.success, true) + assert.isTrue(simulatePerformResult.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + }) + + it('returns correct amount of gasUsed when perform succeeds', async () => { + await mock.setCanPerform(true) + await mock.setPerformGasToBurn(performGas) + + const simulatePerformResult = await registry + .connect(zeroAddress) + .callStatic.simulatePerformUpkeep(upkeepId, '0x') + + assert.equal(simulatePerformResult.success, true) + // Full execute gas should be used, with some performGasBuffer(1000) + assert.isTrue( + simulatePerformResult.gasUsed.gt( + performGas.sub(BigNumber.from('1000')), + ), + ) + }) + }) + + describe('#checkUpkeep', () => { + it('reverts if called by non zero address', async () => { + await evmRevert( + registry + .connect(await owner.getAddress()) + .callStatic['checkUpkeep(uint256)'](upkeepId), + 'OnlySimulatedBackend()', + ) + }) + + it('returns false and error code if the upkeep is cancelled by admin', async () => { + await registry.connect(admin).cancelUpkeep(upkeepId) + + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + + assert.equal(checkUpkeepResult.upkeepNeeded, false) + assert.equal(checkUpkeepResult.performData, '0x') + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.UPKEEP_CANCELLED, + ) + expect(checkUpkeepResult.gasUsed).to.equal(0) + expect(checkUpkeepResult.gasLimit).to.equal(performGas) + }) + + it('returns false and error code if the upkeep is cancelled by owner', async () => { + await registry.connect(owner).cancelUpkeep(upkeepId) + + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + + assert.equal(checkUpkeepResult.upkeepNeeded, false) + assert.equal(checkUpkeepResult.performData, '0x') + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.UPKEEP_CANCELLED, + ) + expect(checkUpkeepResult.gasUsed).to.equal(0) + expect(checkUpkeepResult.gasLimit).to.equal(performGas) + }) + + it('returns false and error code if the registry is paused', async () => { + await registry.connect(owner).pause() + + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + + assert.equal(checkUpkeepResult.upkeepNeeded, false) + assert.equal(checkUpkeepResult.performData, '0x') + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.REGISTRY_PAUSED, + ) + expect(checkUpkeepResult.gasUsed).to.equal(0) + expect(checkUpkeepResult.gasLimit).to.equal(performGas) + }) + + it('returns false and error code if the upkeep is paused', async () => { + await registry.connect(admin).pauseUpkeep(upkeepId) + + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + + assert.equal(checkUpkeepResult.upkeepNeeded, false) + assert.equal(checkUpkeepResult.performData, '0x') + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.UPKEEP_PAUSED, + ) + expect(checkUpkeepResult.gasUsed).to.equal(0) + expect(checkUpkeepResult.gasLimit).to.equal(performGas) + }) + + it('returns false and error code if user is out of funds', async () => { + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + + assert.equal(checkUpkeepResult.upkeepNeeded, false) + assert.equal(checkUpkeepResult.performData, '0x') + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.INSUFFICIENT_BALANCE, + ) + expect(checkUpkeepResult.gasUsed).to.equal(0) + expect(checkUpkeepResult.gasLimit).to.equal(performGas) + }) + + context('when the registration is funded', () => { + beforeEach(async () => { + await linkToken.connect(admin).approve(registry.address, toWei('200')) + await registry.connect(admin).addFunds(upkeepId, toWei('100')) + await registry.connect(admin).addFunds(logUpkeepId, toWei('100')) + }) + + it('returns false, error code, and revert data if the target check reverts', async () => { + await mock.setShouldRevertCheck(true) + await mock.setCheckRevertReason( + 'custom revert error, clever way to insert offchain data', + ) + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + assert.equal(checkUpkeepResult.upkeepNeeded, false) + + const revertReasonBytes = `0x${checkUpkeepResult.performData.slice(10)}` // remove sighash + assert.equal( + ethers.utils.defaultAbiCoder.decode(['string'], revertReasonBytes)[0], + 'custom revert error, clever way to insert offchain data', + ) + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.TARGET_CHECK_REVERTED, + ) + assert.isTrue(checkUpkeepResult.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + expect(checkUpkeepResult.gasLimit).to.equal(performGas) + // Feed data should be returned here + assert.isTrue(checkUpkeepResult.fastGasWei.gt(BigNumber.from('0'))) + assert.isTrue(checkUpkeepResult.linkNative.gt(BigNumber.from('0'))) + }) + + it('returns false, error code, and no revert data if the target check revert data exceeds maxRevertDataSize', async () => { + await mock.setShouldRevertCheck(true) + let longRevertReason = '' + for (let i = 0; i <= maxRevertDataSize.toNumber(); i++) { + longRevertReason += 'x' + } + await mock.setCheckRevertReason(longRevertReason) + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + assert.equal(checkUpkeepResult.upkeepNeeded, false) + + assert.equal(checkUpkeepResult.performData, '0x') + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.REVERT_DATA_EXCEEDS_LIMIT, + ) + assert.isTrue(checkUpkeepResult.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + expect(checkUpkeepResult.gasLimit).to.equal(performGas) + }) + + it('returns false and error code if the upkeep is not needed', async () => { + await mock.setCanCheck(false) + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + + assert.equal(checkUpkeepResult.upkeepNeeded, false) + assert.equal(checkUpkeepResult.performData, '0x') + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.UPKEEP_NOT_NEEDED, + ) + assert.isTrue(checkUpkeepResult.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + expect(checkUpkeepResult.gasLimit).to.equal(performGas) + }) + + it('returns false and error code if the performData exceeds limit', async () => { + let longBytes = '0x' + for (let i = 0; i < 5000; i++) { + longBytes += '1' + } + await mock.setCanCheck(true) + await mock.setPerformData(longBytes) + + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId) + + assert.equal(checkUpkeepResult.upkeepNeeded, false) + assert.equal(checkUpkeepResult.performData, '0x') + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.PERFORM_DATA_EXCEEDS_LIMIT, + ) + assert.isTrue(checkUpkeepResult.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + expect(checkUpkeepResult.gasLimit).to.equal(performGas) + }) + + it('returns true with gas used if the target can execute', async () => { + await mock.setCanCheck(true) + await mock.setPerformData(randomBytes) + + const latestBlock = await ethers.provider.getBlock('latest') + + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId, { + blockTag: latestBlock.number, + }) + + assert.equal(checkUpkeepResult.upkeepNeeded, true) + assert.equal(checkUpkeepResult.performData, randomBytes) + assert.equal( + checkUpkeepResult.upkeepFailureReason, + UpkeepFailureReason.NONE, + ) + assert.isTrue(checkUpkeepResult.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + expect(checkUpkeepResult.gasLimit).to.equal(performGas) + assert.isTrue(checkUpkeepResult.fastGasWei.eq(gasWei)) + assert.isTrue(checkUpkeepResult.linkNative.eq(linkEth)) + }) + + it('calls checkLog for log-trigger upkeeps', async () => { + const log: Log = { + index: 0, + timestamp: 0, + txHash: ethers.utils.randomBytes(32), + blockNumber: 100, + blockHash: ethers.utils.randomBytes(32), + source: randomAddress(), + topics: [ethers.utils.randomBytes(32), ethers.utils.randomBytes(32)], + data: ethers.utils.randomBytes(1000), + } + + await ltUpkeep.mock.checkLog.withArgs(log, '0x').returns(true, '0x1234') + + const checkData = encodeLog(log) + + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256,bytes)'](logUpkeepId, checkData) + + expect(checkUpkeepResult.upkeepNeeded).to.be.true + expect(checkUpkeepResult.performData).to.equal('0x1234') + }) + + itMaybe( + 'has a large enough gas overhead to cover upkeeps that use all their gas [ @skip-coverage ]', + async () => { + await mock.setCanCheck(true) + await mock.setCheckGasToBurn(checkGasLimit) + const gas = checkGasLimit.add(checkGasOverhead) + const checkUpkeepResult = await registry + .connect(zeroAddress) + .callStatic['checkUpkeep(uint256)'](upkeepId, { + gasLimit: gas, + }) + + assert.equal(checkUpkeepResult.upkeepNeeded, true) + }, + ) + }) + }) + + describe('#addFunds', () => { + const amount = toWei('1') + + it('reverts if the registration does not exist', async () => { + await evmRevert( + registry.connect(keeper1).addFunds(upkeepId.add(1), amount), + 'UpkeepCancelled()', + ) + }) + + it('adds to the balance of the registration', async () => { + await registry.connect(admin).addFunds(upkeepId, amount) + const registration = await registry.getUpkeep(upkeepId) + assert.isTrue(amount.eq(registration.balance)) + }) + + it('lets anyone add funds to an upkeep not just admin', async () => { + await linkToken.connect(owner).transfer(await payee1.getAddress(), amount) + await linkToken.connect(payee1).approve(registry.address, amount) + + await registry.connect(payee1).addFunds(upkeepId, amount) + const registration = await registry.getUpkeep(upkeepId) + assert.isTrue(amount.eq(registration.balance)) + }) + + it('emits a log', async () => { + const tx = await registry.connect(admin).addFunds(upkeepId, amount) + await expect(tx) + .to.emit(registry, 'FundsAdded') + .withArgs(upkeepId, await admin.getAddress(), amount) + }) + + it('reverts if the upkeep is canceled', async () => { + await registry.connect(admin).cancelUpkeep(upkeepId) + await evmRevert( + registry.connect(keeper1).addFunds(upkeepId, amount), + 'UpkeepCancelled()', + ) + }) + }) + + describe('#getActiveUpkeepIDs', () => { + it('reverts if startIndex is out of bounds ', async () => { + await evmRevert( + registry.getActiveUpkeepIDs(numUpkeeps, 0), + 'IndexOutOfRange()', + ) + await evmRevert( + registry.getActiveUpkeepIDs(numUpkeeps + 1, 0), + 'IndexOutOfRange()', + ) + }) + + it('returns upkeep IDs bounded by maxCount', async () => { + let upkeepIds = await registry.getActiveUpkeepIDs(0, 1) + assert(upkeepIds.length == 1) + assert(upkeepIds[0].eq(upkeepId)) + upkeepIds = await registry.getActiveUpkeepIDs(1, 3) + assert(upkeepIds.length == 3) + expect(upkeepIds).to.deep.equal([ + afUpkeepId, + logUpkeepId, + streamsLookupUpkeepId, + ]) + }) + + it('returns as many ids as possible if maxCount > num available', async () => { + const upkeepIds = await registry.getActiveUpkeepIDs(1, numUpkeeps + 100) + assert(upkeepIds.length == numUpkeeps - 1) + }) + + it('returns all upkeep IDs if maxCount is 0', async () => { + let upkeepIds = await registry.getActiveUpkeepIDs(0, 0) + assert(upkeepIds.length == numUpkeeps) + upkeepIds = await registry.getActiveUpkeepIDs(2, 0) + assert(upkeepIds.length == numUpkeeps - 2) + }) + }) + + describe('#getMaxPaymentForGas', () => { + let maxl1CostWeiArbWithoutMultiplier: BigNumber + let maxl1CostWeiOptWithoutMultiplier: BigNumber + + beforeEach(async () => { + const arbL1PriceinWei = BigNumber.from(1000) // Same as MockArbGasInfo.sol + maxl1CostWeiArbWithoutMultiplier = arbL1PriceinWei.mul( + maxPerformDataSize + .add(registryTransmitCalldataFixedBytesOverhead) + .add( + registryTransmitCalldataPerSignerBytesOverhead.mul( + BigNumber.from(f + 1), + ), + ), + ) + maxl1CostWeiOptWithoutMultiplier = BigNumber.from(2000000) // Same as MockOVMGasPriceOracle.sol + }) + + itMaybe('calculates the max fee appropriately', async () => { + await verifyMaxPayment(registry, chainModuleBase) + }) + + itMaybe('calculates the max fee appropriately for Arbitrum', async () => { + await verifyMaxPayment( + arbRegistry, + arbitrumModule, + maxl1CostWeiArbWithoutMultiplier, + ) + }) + + itMaybe('calculates the max fee appropriately for Optimism', async () => { + await verifyMaxPayment( + opRegistry, + optimismModule, + maxl1CostWeiOptWithoutMultiplier, + ) + }) + + it('uses the fallback gas price if the feed has issues', async () => { + const chainModuleOverheads = await chainModuleBase.getGasOverhead() + const expectedFallbackMaxPayment = linkForGas( + performGas, + registryConditionalOverhead + .add(registryPerSignerGasOverhead.mul(f + 1)) + .add( + maxPerformDataSize + .add(registryTransmitCalldataFixedBytesOverhead) + .add( + registryTransmitCalldataPerSignerBytesOverhead.mul( + BigNumber.from(f + 1), + ), + ) + .mul( + registryPerPerformByteGasOverhead.add( + chainModuleOverheads.chainModulePerByteOverhead, + ), + ), + ) + .add(chainModuleOverheads.chainModuleFixedOverhead), + gasCeilingMultiplier.mul('2'), // fallbackGasPrice is 2x gas price + paymentPremiumPPB, + flatFeeMicroLink, + ).total + + // Stale feed + let roundId = 99 + const answer = 100 + let updatedAt = 946684800 // New Years 2000 🥳 + let startedAt = 946684799 + await gasPriceFeed + .connect(owner) + .updateRoundData(roundId, answer, updatedAt, startedAt) + + assert.equal( + expectedFallbackMaxPayment.toString(), + ( + await registry.getMaxPaymentForGas(Trigger.CONDITION, performGas) + ).toString(), + ) + + // Negative feed price + roundId = 100 + updatedAt = now() + startedAt = 946684799 + await gasPriceFeed + .connect(owner) + .updateRoundData(roundId, -100, updatedAt, startedAt) + + assert.equal( + expectedFallbackMaxPayment.toString(), + ( + await registry.getMaxPaymentForGas(Trigger.CONDITION, performGas) + ).toString(), + ) + + // Zero feed price + roundId = 101 + updatedAt = now() + startedAt = 946684799 + await gasPriceFeed + .connect(owner) + .updateRoundData(roundId, 0, updatedAt, startedAt) + + assert.equal( + expectedFallbackMaxPayment.toString(), + ( + await registry.getMaxPaymentForGas(Trigger.CONDITION, performGas) + ).toString(), + ) + }) + + it('uses the fallback link price if the feed has issues', async () => { + const chainModuleOverheads = await chainModuleBase.getGasOverhead() + const expectedFallbackMaxPayment = linkForGas( + performGas, + registryConditionalOverhead + .add(registryPerSignerGasOverhead.mul(f + 1)) + .add( + maxPerformDataSize + .add(registryTransmitCalldataFixedBytesOverhead) + .add( + registryTransmitCalldataPerSignerBytesOverhead.mul( + BigNumber.from(f + 1), + ), + ) + .mul( + registryPerPerformByteGasOverhead.add( + chainModuleOverheads.chainModulePerByteOverhead, + ), + ), + ) + .add(chainModuleOverheads.chainModuleFixedOverhead), + gasCeilingMultiplier.mul('2'), // fallbackLinkPrice is 1/2 link price, so multiply by 2 + paymentPremiumPPB, + flatFeeMicroLink, + ).total + + // Stale feed + let roundId = 99 + const answer = 100 + let updatedAt = 946684800 // New Years 2000 🥳 + let startedAt = 946684799 + await linkEthFeed + .connect(owner) + .updateRoundData(roundId, answer, updatedAt, startedAt) + + assert.equal( + expectedFallbackMaxPayment.toString(), + ( + await registry.getMaxPaymentForGas(Trigger.CONDITION, performGas) + ).toString(), + ) + + // Negative feed price + roundId = 100 + updatedAt = now() + startedAt = 946684799 + await linkEthFeed + .connect(owner) + .updateRoundData(roundId, -100, updatedAt, startedAt) + + assert.equal( + expectedFallbackMaxPayment.toString(), + ( + await registry.getMaxPaymentForGas(Trigger.CONDITION, performGas) + ).toString(), + ) + + // Zero feed price + roundId = 101 + updatedAt = now() + startedAt = 946684799 + await linkEthFeed + .connect(owner) + .updateRoundData(roundId, 0, updatedAt, startedAt) + + assert.equal( + expectedFallbackMaxPayment.toString(), + ( + await registry.getMaxPaymentForGas(Trigger.CONDITION, performGas) + ).toString(), + ) + }) + }) + + describe('#typeAndVersion', () => { + it('uses the correct type and version', async () => { + const typeAndVersion = await registry.typeAndVersion() + assert.equal(typeAndVersion, 'AutomationRegistry 2.3.0') + }) + }) + + describe('#onTokenTransfer', () => { + const amount = toWei('1') + + it('reverts if not called by the LINK token', async () => { + const data = ethers.utils.defaultAbiCoder.encode(['uint256'], [upkeepId]) + + await evmRevert( + registry + .connect(keeper1) + .onTokenTransfer(await keeper1.getAddress(), amount, data), + 'OnlyCallableByLINKToken()', + ) + }) + + it('reverts if not called with more or less than 32 bytes', async () => { + const longData = ethers.utils.defaultAbiCoder.encode( + ['uint256', 'uint256'], + ['33', '34'], + ) + const shortData = '0x12345678' + + await evmRevert( + linkToken + .connect(owner) + .transferAndCall(registry.address, amount, longData), + ) + await evmRevert( + linkToken + .connect(owner) + .transferAndCall(registry.address, amount, shortData), + ) + }) + + it('reverts if the upkeep is canceled', async () => { + await registry.connect(admin).cancelUpkeep(upkeepId) + await evmRevert( + registry.connect(keeper1).addFunds(upkeepId, amount), + 'UpkeepCancelled()', + ) + }) + + it('updates the funds of the job id passed', async () => { + const data = ethers.utils.defaultAbiCoder.encode(['uint256'], [upkeepId]) + + const before = (await registry.getUpkeep(upkeepId)).balance + await linkToken + .connect(owner) + .transferAndCall(registry.address, amount, data) + const after = (await registry.getUpkeep(upkeepId)).balance + + assert.isTrue(before.add(amount).eq(after)) + }) + }) + + describeMaybe('#setConfig - onchain', async () => { + const payment = BigNumber.from(1) + const flatFee = BigNumber.from(2) + const maxGas = BigNumber.from(6) + const staleness = BigNumber.from(4) + const ceiling = BigNumber.from(5) + const newMinUpkeepSpend = BigNumber.from(9) + const newMaxCheckDataSize = BigNumber.from(10000) + const newMaxPerformDataSize = BigNumber.from(10000) + const newMaxRevertDataSize = BigNumber.from(10000) + const newMaxPerformGas = BigNumber.from(10000000) + const fbGasEth = BigNumber.from(7) + const fbLinkEth = BigNumber.from(8) + const newTranscoder = randomAddress() + const newRegistrars = [randomAddress(), randomAddress()] + const upkeepManager = randomAddress() + + const newConfig: OnChainConfig = { + paymentPremiumPPB: payment, + flatFeeMicroLink: flatFee, + checkGasLimit: maxGas, + stalenessSeconds: staleness, + gasCeilingMultiplier: ceiling, + minUpkeepSpend: newMinUpkeepSpend, + maxCheckDataSize: newMaxCheckDataSize, + maxPerformDataSize: newMaxPerformDataSize, + maxRevertDataSize: newMaxRevertDataSize, + maxPerformGas: newMaxPerformGas, + fallbackGasPrice: fbGasEth, + fallbackLinkPrice: fbLinkEth, + transcoder: newTranscoder, + registrars: newRegistrars, + upkeepPrivilegeManager: upkeepManager, + chainModule: chainModuleBase.address, + reorgProtectionEnabled: true, + } + + it('reverts when called by anyone but the proposed owner', async () => { + await evmRevert( + registry + .connect(payee1) + .setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + newConfig, + offchainVersion, + offchainBytes, + ), + 'Only callable by owner', + ) + }) + + it('reverts if signers or transmitters are the zero address', async () => { + await evmRevert( + registry + .connect(owner) + .setConfigTypeSafe( + [randomAddress(), randomAddress(), randomAddress(), zeroAddress], + [ + randomAddress(), + randomAddress(), + randomAddress(), + randomAddress(), + ], + f, + newConfig, + offchainVersion, + offchainBytes, + ), + 'InvalidSigner()', + ) + + await evmRevert( + registry + .connect(owner) + .setConfigTypeSafe( + [ + randomAddress(), + randomAddress(), + randomAddress(), + randomAddress(), + ], + [randomAddress(), randomAddress(), randomAddress(), zeroAddress], + f, + newConfig, + offchainVersion, + offchainBytes, + ), + 'InvalidTransmitter()', + ) + }) + + it('updates the onchainConfig and configDigest', async () => { + const old = await registry.getState() + const oldConfig = old.config + const oldState = old.state + assert.isTrue(paymentPremiumPPB.eq(oldConfig.paymentPremiumPPB)) + assert.isTrue(flatFeeMicroLink.eq(oldConfig.flatFeeMicroLink)) + assert.isTrue(stalenessSeconds.eq(oldConfig.stalenessSeconds)) + assert.isTrue(gasCeilingMultiplier.eq(oldConfig.gasCeilingMultiplier)) + + await registry + .connect(owner) + .setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + newConfig, + offchainVersion, + offchainBytes, + ) + + const updated = await registry.getState() + const updatedConfig = updated.config + const updatedState = updated.state + assert.equal(updatedConfig.paymentPremiumPPB, payment.toNumber()) + assert.equal(updatedConfig.flatFeeMicroLink, flatFee.toNumber()) + assert.equal(updatedConfig.stalenessSeconds, staleness.toNumber()) + assert.equal(updatedConfig.gasCeilingMultiplier, ceiling.toNumber()) + assert.equal( + updatedConfig.minUpkeepSpend.toString(), + newMinUpkeepSpend.toString(), + ) + assert.equal( + updatedConfig.maxCheckDataSize, + newMaxCheckDataSize.toNumber(), + ) + assert.equal( + updatedConfig.maxPerformDataSize, + newMaxPerformDataSize.toNumber(), + ) + assert.equal( + updatedConfig.maxRevertDataSize, + newMaxRevertDataSize.toNumber(), + ) + assert.equal(updatedConfig.maxPerformGas, newMaxPerformGas.toNumber()) + assert.equal(updatedConfig.checkGasLimit, maxGas.toNumber()) + assert.equal( + updatedConfig.fallbackGasPrice.toNumber(), + fbGasEth.toNumber(), + ) + assert.equal( + updatedConfig.fallbackLinkPrice.toNumber(), + fbLinkEth.toNumber(), + ) + assert.equal(updatedState.latestEpoch, 0) + + assert(oldState.configCount + 1 == updatedState.configCount) + assert( + oldState.latestConfigBlockNumber != + updatedState.latestConfigBlockNumber, + ) + assert(oldState.latestConfigDigest != updatedState.latestConfigDigest) + + assert.equal(updatedConfig.transcoder, newTranscoder) + assert.deepEqual(updatedConfig.registrars, newRegistrars) + assert.equal(updatedConfig.upkeepPrivilegeManager, upkeepManager) + }) + + it('maintains paused state when config is changed', async () => { + await registry.pause() + const old = await registry.getState() + assert.isTrue(old.state.paused) + + await registry + .connect(owner) + .setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + newConfig, + offchainVersion, + offchainBytes, + ) + + const updated = await registry.getState() + assert.isTrue(updated.state.paused) + }) + + it('emits an event', async () => { + const tx = await registry + .connect(owner) + .setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + newConfig, + offchainVersion, + offchainBytes, + ) + await expect(tx).to.emit(registry, 'ConfigSet') + }) + }) + + describe('#setConfig - offchain', () => { + let newKeepers: string[] + + beforeEach(async () => { + newKeepers = [ + await personas.Eddy.getAddress(), + await personas.Nick.getAddress(), + await personas.Neil.getAddress(), + await personas.Carol.getAddress(), + ] + }) + + it('reverts when called by anyone but the owner', async () => { + await evmRevert( + registry + .connect(payee1) + .setConfigTypeSafe( + newKeepers, + newKeepers, + f, + config, + offchainVersion, + offchainBytes, + ), + 'Only callable by owner', + ) + }) + + it('reverts if too many keeperAddresses set', async () => { + for (let i = 0; i < 40; i++) { + newKeepers.push(randomAddress()) + } + await evmRevert( + registry + .connect(owner) + .setConfigTypeSafe( + newKeepers, + newKeepers, + f, + config, + offchainVersion, + offchainBytes, + ), + 'TooManyOracles()', + ) + }) + + it('reverts if f=0', async () => { + await evmRevert( + registry + .connect(owner) + .setConfigTypeSafe( + newKeepers, + newKeepers, + 0, + config, + offchainVersion, + offchainBytes, + ), + 'IncorrectNumberOfFaultyOracles()', + ) + }) + + it('reverts if signers != transmitters length', async () => { + const signers = [randomAddress()] + await evmRevert( + registry + .connect(owner) + .setConfigTypeSafe( + signers, + newKeepers, + f, + config, + offchainVersion, + offchainBytes, + ), + 'IncorrectNumberOfSigners()', + ) + }) + + it('reverts if signers <= 3f', async () => { + newKeepers.pop() + await evmRevert( + registry + .connect(owner) + .setConfigTypeSafe( + newKeepers, + newKeepers, + f, + config, + offchainVersion, + offchainBytes, + ), + 'IncorrectNumberOfSigners()', + ) + }) + + it('reverts on repeated signers', async () => { + const newSigners = [ + await personas.Eddy.getAddress(), + await personas.Eddy.getAddress(), + await personas.Eddy.getAddress(), + await personas.Eddy.getAddress(), + ] + await evmRevert( + registry + .connect(owner) + .setConfigTypeSafe( + newSigners, + newKeepers, + f, + config, + offchainVersion, + offchainBytes, + ), + 'RepeatedSigner()', + ) + }) + + it('reverts on repeated transmitters', async () => { + const newTransmitters = [ + await personas.Eddy.getAddress(), + await personas.Eddy.getAddress(), + await personas.Eddy.getAddress(), + await personas.Eddy.getAddress(), + ] + await evmRevert( + registry + .connect(owner) + .setConfigTypeSafe( + newKeepers, + newTransmitters, + f, + config, + offchainVersion, + offchainBytes, + ), + 'RepeatedTransmitter()', + ) + }) + + itMaybe('stores new config and emits event', async () => { + // Perform an upkeep so that totalPremium is updated + await registry.connect(admin).addFunds(upkeepId, toWei('100')) + let tx = await getTransmitTx(registry, keeper1, [upkeepId]) + await tx.wait() + + const newOffChainVersion = BigNumber.from('2') + const newOffChainConfig = '0x1122' + + const old = await registry.getState() + const oldState = old.state + assert(oldState.totalPremium.gt(BigNumber.from('0'))) + + const newSigners = newKeepers + tx = await registry + .connect(owner) + .setConfigTypeSafe( + newSigners, + newKeepers, + f, + config, + newOffChainVersion, + newOffChainConfig, + ) + + const updated = await registry.getState() + const updatedState = updated.state + assert(oldState.totalPremium.eq(updatedState.totalPremium)) + + // Old signer addresses which are not in new signers should be non active + for (let i = 0; i < signerAddresses.length; i++) { + const signer = signerAddresses[i] + if (!newSigners.includes(signer)) { + assert(!(await registry.getSignerInfo(signer)).active) + assert((await registry.getSignerInfo(signer)).index == 0) + } + } + // New signer addresses should be active + for (let i = 0; i < newSigners.length; i++) { + const signer = newSigners[i] + assert((await registry.getSignerInfo(signer)).active) + assert((await registry.getSignerInfo(signer)).index == i) + } + // Old transmitter addresses which are not in new transmitter should be non active, update lastCollected but retain other info + for (let i = 0; i < keeperAddresses.length; i++) { + const transmitter = keeperAddresses[i] + if (!newKeepers.includes(transmitter)) { + assert(!(await registry.getTransmitterInfo(transmitter)).active) + assert((await registry.getTransmitterInfo(transmitter)).index == i) + assert( + (await registry.getTransmitterInfo(transmitter)).lastCollected.eq( + oldState.totalPremium.sub( + oldState.totalPremium.mod(keeperAddresses.length), + ), + ), + ) + } + } + // New transmitter addresses should be active + for (let i = 0; i < newKeepers.length; i++) { + const transmitter = newKeepers[i] + assert((await registry.getTransmitterInfo(transmitter)).active) + assert((await registry.getTransmitterInfo(transmitter)).index == i) + assert( + (await registry.getTransmitterInfo(transmitter)).lastCollected.eq( + oldState.totalPremium, + ), + ) + } + + // config digest should be updated + assert(oldState.configCount + 1 == updatedState.configCount) + assert( + oldState.latestConfigBlockNumber != + updatedState.latestConfigBlockNumber, + ) + assert(oldState.latestConfigDigest != updatedState.latestConfigDigest) + + //New config should be updated + assert.deepEqual(updated.signers, newKeepers) + assert.deepEqual(updated.transmitters, newKeepers) + + // Event should have been emitted + await expect(tx).to.emit(registry, 'ConfigSet') + }) + }) + + describe('#setPeerRegistryMigrationPermission() / #getPeerRegistryMigrationPermission()', () => { + const peer = randomAddress() + it('allows the owner to set the peer registries', async () => { + let permission = await registry.getPeerRegistryMigrationPermission(peer) + expect(permission).to.equal(0) + await registry.setPeerRegistryMigrationPermission(peer, 1) + permission = await registry.getPeerRegistryMigrationPermission(peer) + expect(permission).to.equal(1) + await registry.setPeerRegistryMigrationPermission(peer, 2) + permission = await registry.getPeerRegistryMigrationPermission(peer) + expect(permission).to.equal(2) + await registry.setPeerRegistryMigrationPermission(peer, 0) + permission = await registry.getPeerRegistryMigrationPermission(peer) + expect(permission).to.equal(0) + }) + it('reverts if passed an unsupported permission', async () => { + await expect( + registry.connect(admin).setPeerRegistryMigrationPermission(peer, 10), + ).to.be.reverted + }) + it('reverts if not called by the owner', async () => { + await expect( + registry.connect(admin).setPeerRegistryMigrationPermission(peer, 1), + ).to.be.revertedWith('Only callable by owner') + }) + }) + + describe('#registerUpkeep', () => { + it('reverts when registry is paused', async () => { + await registry.connect(owner).pause() + await evmRevert( + registry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,bytes,bytes)' + ](mock.address, performGas, await admin.getAddress(), emptyBytes, '0x'), + 'RegistryPaused()', + ) + }) + + it('reverts if the target is not a contract', async () => { + await evmRevert( + registry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,bytes,bytes)' + ](zeroAddress, performGas, await admin.getAddress(), emptyBytes, '0x'), + 'NotAContract()', + ) + }) + + it('reverts if called by a non-owner', async () => { + await evmRevert( + registry + .connect(keeper1) + [ + 'registerUpkeep(address,uint32,address,bytes,bytes)' + ](mock.address, performGas, await admin.getAddress(), emptyBytes, '0x'), + 'OnlyCallableByOwnerOrRegistrar()', + ) + }) + + it('reverts if execute gas is too low', async () => { + await evmRevert( + registry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,bytes,bytes)' + ](mock.address, 2299, await admin.getAddress(), emptyBytes, '0x'), + 'GasLimitOutsideRange()', + ) + }) + + it('reverts if execute gas is too high', async () => { + await evmRevert( + registry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,bytes,bytes)' + ](mock.address, 5000001, await admin.getAddress(), emptyBytes, '0x'), + 'GasLimitOutsideRange()', + ) + }) + + it('reverts if checkData is too long', async () => { + let longBytes = '0x' + for (let i = 0; i < 10000; i++) { + longBytes += '1' + } + await evmRevert( + registry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,bytes,bytes)' + ](mock.address, performGas, await admin.getAddress(), longBytes, '0x'), + 'CheckDataExceedsLimit()', + ) + }) + + it('creates a record of the registration', async () => { + const performGases = [100000, 500000] + const checkDatas = [emptyBytes, '0x12'] + + for (let jdx = 0; jdx < performGases.length; jdx++) { + const performGas = performGases[jdx] + for (let kdx = 0; kdx < checkDatas.length; kdx++) { + const checkData = checkDatas[kdx] + const tx = await registry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,bytes,bytes)' + ](mock.address, performGas, await admin.getAddress(), checkData, '0x') + + //confirm the upkeep details and verify emitted events + const testUpkeepId = await getUpkeepID(tx) + await expect(tx) + .to.emit(registry, 'UpkeepRegistered') + .withArgs(testUpkeepId, performGas, await admin.getAddress()) + + await expect(tx) + .to.emit(registry, 'UpkeepCheckDataSet') + .withArgs(testUpkeepId, checkData) + await expect(tx) + .to.emit(registry, 'UpkeepTriggerConfigSet') + .withArgs(testUpkeepId, '0x') + + const registration = await registry.getUpkeep(testUpkeepId) + + assert.equal(mock.address, registration.target) + assert.notEqual( + ethers.constants.AddressZero, + await registry.getForwarder(testUpkeepId), + ) + assert.equal( + performGas.toString(), + registration.performGas.toString(), + ) + assert.equal(await admin.getAddress(), registration.admin) + assert.equal(registration.balance.toNumber(), 0) + assert.equal(registration.amountSpent.toNumber(), 0) + assert.equal(registration.lastPerformedBlockNumber, 0) + assert.equal(checkData, registration.checkData) + assert.equal(registration.paused, false) + assert.equal(registration.offchainConfig, '0x') + assert(registration.maxValidBlocknumber.eq('0xffffffff')) + } + } + }) + }) + + describe('#pauseUpkeep', () => { + it('reverts if the registration does not exist', async () => { + await evmRevert( + registry.connect(keeper1).pauseUpkeep(upkeepId.add(1)), + 'OnlyCallableByAdmin()', + ) + }) + + it('reverts if the upkeep is already canceled', async () => { + await registry.connect(admin).cancelUpkeep(upkeepId) + + await evmRevert( + registry.connect(admin).pauseUpkeep(upkeepId), + 'UpkeepCancelled()', + ) + }) + + it('reverts if the upkeep is already paused', async () => { + await registry.connect(admin).pauseUpkeep(upkeepId) + + await evmRevert( + registry.connect(admin).pauseUpkeep(upkeepId), + 'OnlyUnpausedUpkeep()', + ) + }) + + it('reverts if the caller is not the upkeep admin', async () => { + await evmRevert( + registry.connect(keeper1).pauseUpkeep(upkeepId), + 'OnlyCallableByAdmin()', + ) + }) + + it('pauses the upkeep and emits an event', async () => { + const tx = await registry.connect(admin).pauseUpkeep(upkeepId) + await expect(tx).to.emit(registry, 'UpkeepPaused').withArgs(upkeepId) + + const registration = await registry.getUpkeep(upkeepId) + assert.equal(registration.paused, true) + }) + }) + + describe('#unpauseUpkeep', () => { + it('reverts if the registration does not exist', async () => { + await evmRevert( + registry.connect(keeper1).unpauseUpkeep(upkeepId.add(1)), + 'OnlyCallableByAdmin()', + ) + }) + + it('reverts if the upkeep is already canceled', async () => { + await registry.connect(owner).cancelUpkeep(upkeepId) + + await evmRevert( + registry.connect(admin).unpauseUpkeep(upkeepId), + 'UpkeepCancelled()', + ) + }) + + it('marks the contract as paused', async () => { + assert.isFalse((await registry.getState()).state.paused) + + await registry.connect(owner).pause() + + assert.isTrue((await registry.getState()).state.paused) + }) + + it('reverts if the upkeep is not paused', async () => { + await evmRevert( + registry.connect(admin).unpauseUpkeep(upkeepId), + 'OnlyPausedUpkeep()', + ) + }) + + it('reverts if the caller is not the upkeep admin', async () => { + await registry.connect(admin).pauseUpkeep(upkeepId) + + const registration = await registry.getUpkeep(upkeepId) + + assert.equal(registration.paused, true) + + await evmRevert( + registry.connect(keeper1).unpauseUpkeep(upkeepId), + 'OnlyCallableByAdmin()', + ) + }) + + it('unpauses the upkeep and emits an event', async () => { + const originalCount = (await registry.getActiveUpkeepIDs(0, 0)).length + + await registry.connect(admin).pauseUpkeep(upkeepId) + + const tx = await registry.connect(admin).unpauseUpkeep(upkeepId) + + await expect(tx).to.emit(registry, 'UpkeepUnpaused').withArgs(upkeepId) + + const registration = await registry.getUpkeep(upkeepId) + assert.equal(registration.paused, false) + + const upkeepIds = await registry.getActiveUpkeepIDs(0, 0) + assert.equal(upkeepIds.length, originalCount) + }) + }) + + describe('#setUpkeepCheckData', () => { + it('reverts if the registration does not exist', async () => { + await evmRevert( + registry + .connect(keeper1) + .setUpkeepCheckData(upkeepId.add(1), randomBytes), + 'OnlyCallableByAdmin()', + ) + }) + + it('reverts if the caller is not upkeep admin', async () => { + await evmRevert( + registry.connect(keeper1).setUpkeepCheckData(upkeepId, randomBytes), + 'OnlyCallableByAdmin()', + ) + }) + + it('reverts if the upkeep is cancelled', async () => { + await registry.connect(admin).cancelUpkeep(upkeepId) + + await evmRevert( + registry.connect(admin).setUpkeepCheckData(upkeepId, randomBytes), + 'UpkeepCancelled()', + ) + }) + + it('is allowed to update on paused upkeep', async () => { + await registry.connect(admin).pauseUpkeep(upkeepId) + await registry.connect(admin).setUpkeepCheckData(upkeepId, randomBytes) + + const registration = await registry.getUpkeep(upkeepId) + assert.equal(randomBytes, registration.checkData) + }) + + it('reverts if new data exceeds limit', async () => { + let longBytes = '0x' + for (let i = 0; i < 10000; i++) { + longBytes += '1' + } + + await evmRevert( + registry.connect(admin).setUpkeepCheckData(upkeepId, longBytes), + 'CheckDataExceedsLimit()', + ) + }) + + it('updates the upkeep check data and emits an event', async () => { + const tx = await registry + .connect(admin) + .setUpkeepCheckData(upkeepId, randomBytes) + await expect(tx) + .to.emit(registry, 'UpkeepCheckDataSet') + .withArgs(upkeepId, randomBytes) + + const registration = await registry.getUpkeep(upkeepId) + assert.equal(randomBytes, registration.checkData) + }) + }) + + describe('#setUpkeepGasLimit', () => { + const newGasLimit = BigNumber.from('300000') + + it('reverts if the registration does not exist', async () => { + await evmRevert( + registry.connect(admin).setUpkeepGasLimit(upkeepId.add(1), newGasLimit), + 'OnlyCallableByAdmin()', + ) + }) + + it('reverts if the upkeep is canceled', async () => { + await registry.connect(admin).cancelUpkeep(upkeepId) + await evmRevert( + registry.connect(admin).setUpkeepGasLimit(upkeepId, newGasLimit), + 'UpkeepCancelled()', + ) + }) + + it('reverts if called by anyone but the admin', async () => { + await evmRevert( + registry.connect(owner).setUpkeepGasLimit(upkeepId, newGasLimit), + 'OnlyCallableByAdmin()', + ) + }) + + it('reverts if new gas limit is out of bounds', async () => { + await evmRevert( + registry + .connect(admin) + .setUpkeepGasLimit(upkeepId, BigNumber.from('100')), + 'GasLimitOutsideRange()', + ) + await evmRevert( + registry + .connect(admin) + .setUpkeepGasLimit(upkeepId, BigNumber.from('6000000')), + 'GasLimitOutsideRange()', + ) + }) + + it('updates the gas limit successfully', async () => { + const initialGasLimit = (await registry.getUpkeep(upkeepId)).performGas + assert.equal(initialGasLimit, performGas.toNumber()) + await registry.connect(admin).setUpkeepGasLimit(upkeepId, newGasLimit) + const updatedGasLimit = (await registry.getUpkeep(upkeepId)).performGas + assert.equal(updatedGasLimit, newGasLimit.toNumber()) + }) + + it('emits a log', async () => { + const tx = await registry + .connect(admin) + .setUpkeepGasLimit(upkeepId, newGasLimit) + await expect(tx) + .to.emit(registry, 'UpkeepGasLimitSet') + .withArgs(upkeepId, newGasLimit) + }) + }) + + describe('#setUpkeepOffchainConfig', () => { + const newConfig = '0xc0ffeec0ffee' + + it('reverts if the registration does not exist', async () => { + await evmRevert( + registry + .connect(admin) + .setUpkeepOffchainConfig(upkeepId.add(1), newConfig), + 'OnlyCallableByAdmin()', + ) + }) + + it('reverts if the upkeep is canceled', async () => { + await registry.connect(admin).cancelUpkeep(upkeepId) + await evmRevert( + registry.connect(admin).setUpkeepOffchainConfig(upkeepId, newConfig), + 'UpkeepCancelled()', + ) + }) + + it('reverts if called by anyone but the admin', async () => { + await evmRevert( + registry.connect(owner).setUpkeepOffchainConfig(upkeepId, newConfig), + 'OnlyCallableByAdmin()', + ) + }) + + it('updates the config successfully', async () => { + const initialConfig = (await registry.getUpkeep(upkeepId)).offchainConfig + assert.equal(initialConfig, '0x') + await registry.connect(admin).setUpkeepOffchainConfig(upkeepId, newConfig) + const updatedConfig = (await registry.getUpkeep(upkeepId)).offchainConfig + assert.equal(newConfig, updatedConfig) + }) + + it('emits a log', async () => { + const tx = await registry + .connect(admin) + .setUpkeepOffchainConfig(upkeepId, newConfig) + await expect(tx) + .to.emit(registry, 'UpkeepOffchainConfigSet') + .withArgs(upkeepId, newConfig) + }) + }) + + describe('#setUpkeepTriggerConfig', () => { + const newConfig = '0xdeadbeef' + + it('reverts if the registration does not exist', async () => { + await evmRevert( + registry + .connect(admin) + .setUpkeepTriggerConfig(upkeepId.add(1), newConfig), + 'OnlyCallableByAdmin()', + ) + }) + + it('reverts if the upkeep is canceled', async () => { + await registry.connect(admin).cancelUpkeep(upkeepId) + await evmRevert( + registry.connect(admin).setUpkeepTriggerConfig(upkeepId, newConfig), + 'UpkeepCancelled()', + ) + }) + + it('reverts if called by anyone but the admin', async () => { + await evmRevert( + registry.connect(owner).setUpkeepTriggerConfig(upkeepId, newConfig), + 'OnlyCallableByAdmin()', + ) + }) + + it('emits a log', async () => { + const tx = await registry + .connect(admin) + .setUpkeepTriggerConfig(upkeepId, newConfig) + await expect(tx) + .to.emit(registry, 'UpkeepTriggerConfigSet') + .withArgs(upkeepId, newConfig) + }) + }) + + describe('#transferUpkeepAdmin', () => { + it('reverts when called by anyone but the current upkeep admin', async () => { + await evmRevert( + registry + .connect(payee1) + .transferUpkeepAdmin(upkeepId, await payee2.getAddress()), + 'OnlyCallableByAdmin()', + ) + }) + + it('reverts when transferring to self', async () => { + await evmRevert( + registry + .connect(admin) + .transferUpkeepAdmin(upkeepId, await admin.getAddress()), + 'ValueNotChanged()', + ) + }) + + it('reverts when the upkeep is cancelled', async () => { + await registry.connect(admin).cancelUpkeep(upkeepId) + + await evmRevert( + registry + .connect(admin) + .transferUpkeepAdmin(upkeepId, await keeper1.getAddress()), + 'UpkeepCancelled()', + ) + }) + + it('allows cancelling transfer by reverting to zero address', async () => { + await registry + .connect(admin) + .transferUpkeepAdmin(upkeepId, await payee1.getAddress()) + const tx = await registry + .connect(admin) + .transferUpkeepAdmin(upkeepId, ethers.constants.AddressZero) + + await expect(tx) + .to.emit(registry, 'UpkeepAdminTransferRequested') + .withArgs( + upkeepId, + await admin.getAddress(), + ethers.constants.AddressZero, + ) + }) + + it('does not change the upkeep admin', async () => { + await registry + .connect(admin) + .transferUpkeepAdmin(upkeepId, await payee1.getAddress()) + + const upkeep = await registry.getUpkeep(upkeepId) + assert.equal(await admin.getAddress(), upkeep.admin) + }) + + it('emits an event announcing the new upkeep admin', async () => { + const tx = await registry + .connect(admin) + .transferUpkeepAdmin(upkeepId, await payee1.getAddress()) + + await expect(tx) + .to.emit(registry, 'UpkeepAdminTransferRequested') + .withArgs(upkeepId, await admin.getAddress(), await payee1.getAddress()) + }) + + it('does not emit an event when called with the same proposed upkeep admin', async () => { + await registry + .connect(admin) + .transferUpkeepAdmin(upkeepId, await payee1.getAddress()) + + const tx = await registry + .connect(admin) + .transferUpkeepAdmin(upkeepId, await payee1.getAddress()) + const receipt = await tx.wait() + assert.equal(receipt.logs.length, 0) + }) + }) + + describe('#acceptUpkeepAdmin', () => { + beforeEach(async () => { + // Start admin transfer to payee1 + await registry + .connect(admin) + .transferUpkeepAdmin(upkeepId, await payee1.getAddress()) + }) + + it('reverts when not called by the proposed upkeep admin', async () => { + await evmRevert( + registry.connect(payee2).acceptUpkeepAdmin(upkeepId), + 'OnlyCallableByProposedAdmin()', + ) + }) + + it('reverts when the upkeep is cancelled', async () => { + await registry.connect(admin).cancelUpkeep(upkeepId) + + await evmRevert( + registry.connect(payee1).acceptUpkeepAdmin(upkeepId), + 'UpkeepCancelled()', + ) + }) + + it('does change the admin', async () => { + await registry.connect(payee1).acceptUpkeepAdmin(upkeepId) + + const upkeep = await registry.getUpkeep(upkeepId) + assert.equal(await payee1.getAddress(), upkeep.admin) + }) + + it('emits an event announcing the new upkeep admin', async () => { + const tx = await registry.connect(payee1).acceptUpkeepAdmin(upkeepId) + await expect(tx) + .to.emit(registry, 'UpkeepAdminTransferred') + .withArgs(upkeepId, await admin.getAddress(), await payee1.getAddress()) + }) + }) + + describe('#withdrawOwnerFunds', () => { + it('can only be called by owner', async () => { + await evmRevert( + registry.connect(keeper1).withdrawOwnerFunds(), + 'Only callable by owner', + ) + }) + + itMaybe('withdraws the collected fees to owner', async () => { + await registry.connect(admin).addFunds(upkeepId, toWei('100')) + // Very high min spend, whole balance as cancellation fees + const minUpkeepSpend = toWei('1000') + await registry.connect(owner).setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + { + paymentPremiumPPB, + flatFeeMicroLink, + checkGasLimit, + stalenessSeconds, + gasCeilingMultiplier, + minUpkeepSpend, + maxCheckDataSize, + maxPerformDataSize, + maxRevertDataSize, + maxPerformGas, + fallbackGasPrice, + fallbackLinkPrice, + transcoder: transcoder.address, + registrars: [], + upkeepPrivilegeManager: upkeepManager, + chainModule: chainModuleBase.address, + reorgProtectionEnabled: true, + }, + offchainVersion, + offchainBytes, + ) + const upkeepBalance = (await registry.getUpkeep(upkeepId)).balance + const ownerBefore = await linkToken.balanceOf(await owner.getAddress()) + + await registry.connect(owner).cancelUpkeep(upkeepId) + + // Transfered to owner balance on registry + let ownerRegistryBalance = (await registry.getState()).state + .ownerLinkBalance + assert.isTrue(ownerRegistryBalance.eq(upkeepBalance)) + + // Now withdraw + await registry.connect(owner).withdrawOwnerFunds() + + ownerRegistryBalance = (await registry.getState()).state.ownerLinkBalance + const ownerAfter = await linkToken.balanceOf(await owner.getAddress()) + + // Owner registry balance should be changed to 0 + assert.isTrue(ownerRegistryBalance.eq(BigNumber.from('0'))) + + // Owner should be credited with the balance + assert.isTrue(ownerBefore.add(upkeepBalance).eq(ownerAfter)) + }) + }) + + describe('#transferPayeeship', () => { + it('reverts when called by anyone but the current payee', async () => { + await evmRevert( + registry + .connect(payee2) + .transferPayeeship( + await keeper1.getAddress(), + await payee2.getAddress(), + ), + 'OnlyCallableByPayee()', + ) + }) + + it('reverts when transferring to self', async () => { + await evmRevert( + registry + .connect(payee1) + .transferPayeeship( + await keeper1.getAddress(), + await payee1.getAddress(), + ), + 'ValueNotChanged()', + ) + }) + + it('does not change the payee', async () => { + await registry + .connect(payee1) + .transferPayeeship( + await keeper1.getAddress(), + await payee2.getAddress(), + ) + + const info = await registry.getTransmitterInfo(await keeper1.getAddress()) + assert.equal(await payee1.getAddress(), info.payee) + }) + + it('emits an event announcing the new payee', async () => { + const tx = await registry + .connect(payee1) + .transferPayeeship( + await keeper1.getAddress(), + await payee2.getAddress(), + ) + await expect(tx) + .to.emit(registry, 'PayeeshipTransferRequested') + .withArgs( + await keeper1.getAddress(), + await payee1.getAddress(), + await payee2.getAddress(), + ) + }) + + it('does not emit an event when called with the same proposal', async () => { + await registry + .connect(payee1) + .transferPayeeship( + await keeper1.getAddress(), + await payee2.getAddress(), + ) + + const tx = await registry + .connect(payee1) + .transferPayeeship( + await keeper1.getAddress(), + await payee2.getAddress(), + ) + const receipt = await tx.wait() + assert.equal(receipt.logs.length, 0) + }) + }) + + describe('#acceptPayeeship', () => { + beforeEach(async () => { + await registry + .connect(payee1) + .transferPayeeship( + await keeper1.getAddress(), + await payee2.getAddress(), + ) + }) + + it('reverts when called by anyone but the proposed payee', async () => { + await evmRevert( + registry.connect(payee1).acceptPayeeship(await keeper1.getAddress()), + 'OnlyCallableByProposedPayee()', + ) + }) + + it('emits an event announcing the new payee', async () => { + const tx = await registry + .connect(payee2) + .acceptPayeeship(await keeper1.getAddress()) + await expect(tx) + .to.emit(registry, 'PayeeshipTransferred') + .withArgs( + await keeper1.getAddress(), + await payee1.getAddress(), + await payee2.getAddress(), + ) + }) + + it('does change the payee', async () => { + await registry.connect(payee2).acceptPayeeship(await keeper1.getAddress()) + + const info = await registry.getTransmitterInfo(await keeper1.getAddress()) + assert.equal(await payee2.getAddress(), info.payee) + }) + }) + + describe('#pause', () => { + it('reverts if called by a non-owner', async () => { + await evmRevert( + registry.connect(keeper1).pause(), + 'Only callable by owner', + ) + }) + + it('marks the contract as paused', async () => { + assert.isFalse((await registry.getState()).state.paused) + + await registry.connect(owner).pause() + + assert.isTrue((await registry.getState()).state.paused) + }) + + it('Does not allow transmits when paused', async () => { + await registry.connect(owner).pause() + + await evmRevert( + getTransmitTx(registry, keeper1, [upkeepId]), + 'RegistryPaused()', + ) + }) + + it('Does not allow creation of new upkeeps when paused', async () => { + await registry.connect(owner).pause() + + await evmRevert( + registry + .connect(owner) + [ + 'registerUpkeep(address,uint32,address,bytes,bytes)' + ](mock.address, performGas, await admin.getAddress(), emptyBytes, '0x'), + 'RegistryPaused()', + ) + }) + }) + + describe('#unpause', () => { + beforeEach(async () => { + await registry.connect(owner).pause() + }) + + it('reverts if called by a non-owner', async () => { + await evmRevert( + registry.connect(keeper1).unpause(), + 'Only callable by owner', + ) + }) + + it('marks the contract as not paused', async () => { + assert.isTrue((await registry.getState()).state.paused) + + await registry.connect(owner).unpause() + + assert.isFalse((await registry.getState()).state.paused) + }) + }) + + describe('#migrateUpkeeps() / #receiveUpkeeps()', async () => { + context('when permissions are set', () => { + beforeEach(async () => { + await linkToken.connect(owner).approve(registry.address, toWei('100')) + await registry.connect(owner).addFunds(upkeepId, toWei('100')) + await registry.setPeerRegistryMigrationPermission(mgRegistry.address, 1) + await mgRegistry.setPeerRegistryMigrationPermission(registry.address, 2) + }) + + it('migrates an upkeep', async () => { + const offchainBytes = '0x987654abcd' + await registry + .connect(admin) + .setUpkeepOffchainConfig(upkeepId, offchainBytes) + const reg1Upkeep = await registry.getUpkeep(upkeepId) + const forwarderAddress = await registry.getForwarder(upkeepId) + expect(reg1Upkeep.balance).to.equal(toWei('100')) + expect(reg1Upkeep.checkData).to.equal(randomBytes) + expect(forwarderAddress).to.not.equal(ethers.constants.AddressZero) + expect(reg1Upkeep.offchainConfig).to.equal(offchainBytes) + expect((await registry.getState()).state.numUpkeeps).to.equal( + numUpkeeps, + ) + const forwarder = IAutomationForwarderFactory.connect( + forwarderAddress, + owner, + ) + expect(await forwarder.getRegistry()).to.equal(registry.address) + // Set an upkeep admin transfer in progress too + await registry + .connect(admin) + .transferUpkeepAdmin(upkeepId, await payee1.getAddress()) + + // migrate + await registry + .connect(admin) + .migrateUpkeeps([upkeepId], mgRegistry.address) + expect((await registry.getState()).state.numUpkeeps).to.equal( + numUpkeeps - 1, + ) + expect((await mgRegistry.getState()).state.numUpkeeps).to.equal(1) + expect((await registry.getUpkeep(upkeepId)).balance).to.equal(0) + expect((await registry.getUpkeep(upkeepId)).checkData).to.equal('0x') + expect((await mgRegistry.getUpkeep(upkeepId)).balance).to.equal( + toWei('100'), + ) + expect( + (await mgRegistry.getState()).state.expectedLinkBalance, + ).to.equal(toWei('100')) + expect((await mgRegistry.getUpkeep(upkeepId)).checkData).to.equal( + randomBytes, + ) + expect((await mgRegistry.getUpkeep(upkeepId)).offchainConfig).to.equal( + offchainBytes, + ) + expect(await mgRegistry.getForwarder(upkeepId)).to.equal( + forwarderAddress, + ) + // test that registry is updated on forwarder + expect(await forwarder.getRegistry()).to.equal(mgRegistry.address) + // migration will delete the upkeep and nullify admin transfer + await expect( + registry.connect(payee1).acceptUpkeepAdmin(upkeepId), + ).to.be.revertedWith('UpkeepCancelled()') + await expect( + mgRegistry.connect(payee1).acceptUpkeepAdmin(upkeepId), + ).to.be.revertedWith('OnlyCallableByProposedAdmin()') + }) + + it('migrates a paused upkeep', async () => { + expect((await registry.getUpkeep(upkeepId)).balance).to.equal( + toWei('100'), + ) + expect((await registry.getUpkeep(upkeepId)).checkData).to.equal( + randomBytes, + ) + expect((await registry.getState()).state.numUpkeeps).to.equal( + numUpkeeps, + ) + await registry.connect(admin).pauseUpkeep(upkeepId) + // verify the upkeep is paused + expect((await registry.getUpkeep(upkeepId)).paused).to.equal(true) + // migrate + await registry + .connect(admin) + .migrateUpkeeps([upkeepId], mgRegistry.address) + expect((await registry.getState()).state.numUpkeeps).to.equal( + numUpkeeps - 1, + ) + expect((await mgRegistry.getState()).state.numUpkeeps).to.equal(1) + expect((await registry.getUpkeep(upkeepId)).balance).to.equal(0) + expect((await mgRegistry.getUpkeep(upkeepId)).balance).to.equal( + toWei('100'), + ) + expect((await registry.getUpkeep(upkeepId)).checkData).to.equal('0x') + expect((await mgRegistry.getUpkeep(upkeepId)).checkData).to.equal( + randomBytes, + ) + expect( + (await mgRegistry.getState()).state.expectedLinkBalance, + ).to.equal(toWei('100')) + // verify the upkeep is still paused after migration + expect((await mgRegistry.getUpkeep(upkeepId)).paused).to.equal(true) + }) + + it('emits an event on both contracts', async () => { + expect((await registry.getUpkeep(upkeepId)).balance).to.equal( + toWei('100'), + ) + expect((await registry.getUpkeep(upkeepId)).checkData).to.equal( + randomBytes, + ) + expect((await registry.getState()).state.numUpkeeps).to.equal( + numUpkeeps, + ) + const tx = registry + .connect(admin) + .migrateUpkeeps([upkeepId], mgRegistry.address) + await expect(tx) + .to.emit(registry, 'UpkeepMigrated') + .withArgs(upkeepId, toWei('100'), mgRegistry.address) + await expect(tx) + .to.emit(mgRegistry, 'UpkeepReceived') + .withArgs(upkeepId, toWei('100'), registry.address) + }) + + it('is only migratable by the admin', async () => { + await expect( + registry + .connect(owner) + .migrateUpkeeps([upkeepId], mgRegistry.address), + ).to.be.revertedWith('OnlyCallableByAdmin()') + await registry + .connect(admin) + .migrateUpkeeps([upkeepId], mgRegistry.address) + }) + }) + + context('when permissions are not set', () => { + it('reverts', async () => { + // no permissions + await registry.setPeerRegistryMigrationPermission(mgRegistry.address, 0) + await mgRegistry.setPeerRegistryMigrationPermission(registry.address, 0) + await expect(registry.migrateUpkeeps([upkeepId], mgRegistry.address)).to + .be.reverted + // only outgoing permissions + await registry.setPeerRegistryMigrationPermission(mgRegistry.address, 1) + await mgRegistry.setPeerRegistryMigrationPermission(registry.address, 0) + await expect(registry.migrateUpkeeps([upkeepId], mgRegistry.address)).to + .be.reverted + // only incoming permissions + await registry.setPeerRegistryMigrationPermission(mgRegistry.address, 0) + await mgRegistry.setPeerRegistryMigrationPermission(registry.address, 2) + await expect(registry.migrateUpkeeps([upkeepId], mgRegistry.address)).to + .be.reverted + // permissions opposite direction + await registry.setPeerRegistryMigrationPermission(mgRegistry.address, 2) + await mgRegistry.setPeerRegistryMigrationPermission(registry.address, 1) + await expect(registry.migrateUpkeeps([upkeepId], mgRegistry.address)).to + .be.reverted + }) + }) + }) + + describe('#setPayees', () => { + const IGNORE_ADDRESS = '0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF' + + it('reverts when not called by the owner', async () => { + await evmRevert( + registry.connect(keeper1).setPayees(payees), + 'Only callable by owner', + ) + }) + + it('reverts with different numbers of payees than transmitters', async () => { + await evmRevert( + registry.connect(owner).setPayees([...payees, randomAddress()]), + 'ParameterLengthError()', + ) + }) + + it('reverts if the payee is the zero address', async () => { + await blankRegistry.connect(owner).setConfig(...baseConfig) // used to test initial config + + await evmRevert( + blankRegistry // used to test initial config + .connect(owner) + .setPayees([ethers.constants.AddressZero, ...payees.slice(1)]), + 'InvalidPayee()', + ) + }) + + itMaybe( + 'sets the payees when exisitng payees are zero address', + async () => { + //Initial payees should be zero address + await blankRegistry.connect(owner).setConfig(...baseConfig) // used to test initial config + + for (let i = 0; i < keeperAddresses.length; i++) { + const payee = ( + await blankRegistry.getTransmitterInfo(keeperAddresses[i]) + ).payee // used to test initial config + assert.equal(payee, zeroAddress) + } + + await blankRegistry.connect(owner).setPayees(payees) // used to test initial config + + for (let i = 0; i < keeperAddresses.length; i++) { + const payee = ( + await blankRegistry.getTransmitterInfo(keeperAddresses[i]) + ).payee + assert.equal(payee, payees[i]) + } + }, + ) + + it('does not change the payee if IGNORE_ADDRESS is used as payee', async () => { + const signers = Array.from({ length: 5 }, randomAddress) + const keepers = Array.from({ length: 5 }, randomAddress) + const payees = Array.from({ length: 5 }, randomAddress) + const newTransmitter = randomAddress() + const newPayee = randomAddress() + const ignoreAddresses = new Array(payees.length).fill(IGNORE_ADDRESS) + const newPayees = [...ignoreAddresses, newPayee] + // arbitrum registry + // configure registry with 5 keepers // optimism registry + await blankRegistry // used to test initial configurations + .connect(owner) + .setConfigTypeSafe( + signers, + keepers, + f, + config, + offchainVersion, + offchainBytes, + ) + // arbitrum registry + // set initial payees // optimism registry + await blankRegistry.connect(owner).setPayees(payees) // used to test initial configurations + // arbitrum registry + // add another keeper // optimism registry + await blankRegistry // used to test initial configurations + .connect(owner) + .setConfigTypeSafe( + [...signers, randomAddress()], + [...keepers, newTransmitter], + f, + config, + offchainVersion, + offchainBytes, + ) + // arbitrum registry + // update payee list // optimism registry // arbitrum registry + await blankRegistry.connect(owner).setPayees(newPayees) // used to test initial configurations // optimism registry + const ignored = await blankRegistry.getTransmitterInfo(newTransmitter) // used to test initial configurations + assert.equal(newPayee, ignored.payee) + assert.equal(ignored.active, true) + }) + + it('reverts if payee is non zero and owner tries to change payee', async () => { + const newPayees = [randomAddress(), ...payees.slice(1)] + + await evmRevert( + registry.connect(owner).setPayees(newPayees), + 'InvalidPayee()', + ) + }) + + it('emits events for every payee added and removed', async () => { + const tx = await registry.connect(owner).setPayees(payees) + await expect(tx) + .to.emit(registry, 'PayeesUpdated') + .withArgs(keeperAddresses, payees) + }) + }) + + describe('#cancelUpkeep', () => { + it('reverts if the ID is not valid', async () => { + await evmRevert( + registry.connect(owner).cancelUpkeep(upkeepId.add(1)), + 'CannotCancel()', + ) + }) + + it('reverts if called by a non-owner/non-admin', async () => { + await evmRevert( + registry.connect(keeper1).cancelUpkeep(upkeepId), + 'OnlyCallableByOwnerOrAdmin()', + ) + }) + + describe('when called by the owner', async () => { + it('sets the registration to invalid immediately', async () => { + const tx = await registry.connect(owner).cancelUpkeep(upkeepId) + const receipt = await tx.wait() + const registration = await registry.getUpkeep(upkeepId) + assert.equal( + registration.maxValidBlocknumber.toNumber(), + receipt.blockNumber, + ) + }) + + it('emits an event', async () => { + const tx = await registry.connect(owner).cancelUpkeep(upkeepId) + const receipt = await tx.wait() + await expect(tx) + .to.emit(registry, 'UpkeepCanceled') + .withArgs(upkeepId, BigNumber.from(receipt.blockNumber)) + }) + + it('immediately prevents upkeep', async () => { + await registry.connect(owner).cancelUpkeep(upkeepId) + + const tx = await getTransmitTx(registry, keeper1, [upkeepId]) + const receipt = await tx.wait() + const cancelledUpkeepReportLogs = + parseCancelledUpkeepReportLogs(receipt) + // exactly 1 CancelledUpkeepReport log should be emitted + assert.equal(cancelledUpkeepReportLogs.length, 1) + }) + + it('does not revert if reverts if called multiple times', async () => { + await registry.connect(owner).cancelUpkeep(upkeepId) + await evmRevert( + registry.connect(owner).cancelUpkeep(upkeepId), + 'UpkeepCancelled()', + ) + }) + + describe('when called by the owner when the admin has just canceled', () => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + let oldExpiration: BigNumber + + beforeEach(async () => { + await registry.connect(admin).cancelUpkeep(upkeepId) + const registration = await registry.getUpkeep(upkeepId) + oldExpiration = registration.maxValidBlocknumber + }) + + it('reverts with proper error', async () => { + await evmRevert( + registry.connect(owner).cancelUpkeep(upkeepId), + 'UpkeepCancelled()', + ) + }) + }) + }) + + describe('when called by the admin', async () => { + it('reverts if called again by the admin', async () => { + await registry.connect(admin).cancelUpkeep(upkeepId) + + await evmRevert( + registry.connect(admin).cancelUpkeep(upkeepId), + 'UpkeepCancelled()', + ) + }) + + it('reverts if called by the owner after the timeout', async () => { + await registry.connect(admin).cancelUpkeep(upkeepId) + + for (let i = 0; i < cancellationDelay; i++) { + await ethers.provider.send('evm_mine', []) + } + + await evmRevert( + registry.connect(owner).cancelUpkeep(upkeepId), + 'UpkeepCancelled()', + ) + }) + + it('sets the registration to invalid in 50 blocks', async () => { + const tx = await registry.connect(admin).cancelUpkeep(upkeepId) + const receipt = await tx.wait() + const registration = await registry.getUpkeep(upkeepId) + assert.equal( + registration.maxValidBlocknumber.toNumber(), + receipt.blockNumber + 50, + ) + }) + + it('emits an event', async () => { + const tx = await registry.connect(admin).cancelUpkeep(upkeepId) + const receipt = await tx.wait() + await expect(tx) + .to.emit(registry, 'UpkeepCanceled') + .withArgs( + upkeepId, + BigNumber.from(receipt.blockNumber + cancellationDelay), + ) + }) + + it('immediately prevents upkeep', async () => { + await linkToken.connect(owner).approve(registry.address, toWei('100')) + await registry.connect(owner).addFunds(upkeepId, toWei('100')) + await registry.connect(admin).cancelUpkeep(upkeepId) + + await getTransmitTx(registry, keeper1, [upkeepId]) + + for (let i = 0; i < cancellationDelay; i++) { + await ethers.provider.send('evm_mine', []) + } + + const tx = await getTransmitTx(registry, keeper1, [upkeepId]) + + const receipt = await tx.wait() + const cancelledUpkeepReportLogs = + parseCancelledUpkeepReportLogs(receipt) + // exactly 1 CancelledUpkeepReport log should be emitted + assert.equal(cancelledUpkeepReportLogs.length, 1) + }) + + describeMaybe('when an upkeep has been performed', async () => { + beforeEach(async () => { + await linkToken.connect(owner).approve(registry.address, toWei('100')) + await registry.connect(owner).addFunds(upkeepId, toWei('100')) + await getTransmitTx(registry, keeper1, [upkeepId]) + }) + + it('deducts a cancellation fee from the upkeep and gives to owner', async () => { + const minUpkeepSpend = toWei('10') + + await registry.connect(owner).setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + { + paymentPremiumPPB, + flatFeeMicroLink, + checkGasLimit, + stalenessSeconds, + gasCeilingMultiplier, + minUpkeepSpend, + maxCheckDataSize, + maxPerformDataSize, + maxRevertDataSize, + maxPerformGas, + fallbackGasPrice, + fallbackLinkPrice, + transcoder: transcoder.address, + registrars: [], + upkeepPrivilegeManager: upkeepManager, + chainModule: chainModuleBase.address, + reorgProtectionEnabled: true, + }, + offchainVersion, + offchainBytes, + ) + + const payee1Before = await linkToken.balanceOf( + await payee1.getAddress(), + ) + const upkeepBefore = (await registry.getUpkeep(upkeepId)).balance + const ownerBefore = (await registry.getState()).state.ownerLinkBalance + + const amountSpent = toWei('100').sub(upkeepBefore) + const cancellationFee = minUpkeepSpend.sub(amountSpent) + + await registry.connect(admin).cancelUpkeep(upkeepId) + + const payee1After = await linkToken.balanceOf( + await payee1.getAddress(), + ) + const upkeepAfter = (await registry.getUpkeep(upkeepId)).balance + const ownerAfter = (await registry.getState()).state.ownerLinkBalance + + // post upkeep balance should be previous balance minus cancellation fee + assert.isTrue(upkeepBefore.sub(cancellationFee).eq(upkeepAfter)) + // payee balance should not change + assert.isTrue(payee1Before.eq(payee1After)) + // owner should receive the cancellation fee + assert.isTrue(ownerAfter.sub(ownerBefore).eq(cancellationFee)) + }) + + it('deducts up to balance as cancellation fee', async () => { + // Very high min spend, should deduct whole balance as cancellation fees + const minUpkeepSpend = toWei('1000') + await registry.connect(owner).setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + { + paymentPremiumPPB, + flatFeeMicroLink, + checkGasLimit, + stalenessSeconds, + gasCeilingMultiplier, + minUpkeepSpend, + maxCheckDataSize, + maxPerformDataSize, + maxRevertDataSize, + maxPerformGas, + fallbackGasPrice, + fallbackLinkPrice, + transcoder: transcoder.address, + registrars: [], + upkeepPrivilegeManager: upkeepManager, + chainModule: chainModuleBase.address, + reorgProtectionEnabled: true, + }, + offchainVersion, + offchainBytes, + ) + const payee1Before = await linkToken.balanceOf( + await payee1.getAddress(), + ) + const upkeepBefore = (await registry.getUpkeep(upkeepId)).balance + const ownerBefore = (await registry.getState()).state.ownerLinkBalance + + await registry.connect(admin).cancelUpkeep(upkeepId) + const payee1After = await linkToken.balanceOf( + await payee1.getAddress(), + ) + const ownerAfter = (await registry.getState()).state.ownerLinkBalance + const upkeepAfter = (await registry.getUpkeep(upkeepId)).balance + + // all upkeep balance is deducted for cancellation fee + assert.equal(upkeepAfter.toNumber(), 0) + // payee balance should not change + assert.isTrue(payee1After.eq(payee1Before)) + // all upkeep balance is transferred to the owner + assert.isTrue(ownerAfter.sub(ownerBefore).eq(upkeepBefore)) + }) + + it('does not deduct cancellation fee if more than minUpkeepSpend is spent', async () => { + // Very low min spend, already spent in one perform upkeep + const minUpkeepSpend = BigNumber.from(420) + await registry.connect(owner).setConfigTypeSafe( + signerAddresses, + keeperAddresses, + f, + { + paymentPremiumPPB, + flatFeeMicroLink, + checkGasLimit, + stalenessSeconds, + gasCeilingMultiplier, + minUpkeepSpend, + maxCheckDataSize, + maxPerformDataSize, + maxRevertDataSize, + maxPerformGas, + fallbackGasPrice, + fallbackLinkPrice, + transcoder: transcoder.address, + registrars: [], + upkeepPrivilegeManager: upkeepManager, + chainModule: chainModuleBase.address, + reorgProtectionEnabled: true, + }, + offchainVersion, + offchainBytes, + ) + const payee1Before = await linkToken.balanceOf( + await payee1.getAddress(), + ) + const upkeepBefore = (await registry.getUpkeep(upkeepId)).balance + const ownerBefore = (await registry.getState()).state.ownerLinkBalance + + await registry.connect(admin).cancelUpkeep(upkeepId) + const payee1After = await linkToken.balanceOf( + await payee1.getAddress(), + ) + const ownerAfter = (await registry.getState()).state.ownerLinkBalance + const upkeepAfter = (await registry.getUpkeep(upkeepId)).balance + + // upkeep does not pay cancellation fee after cancellation because minimum upkeep spent is met + assert.isTrue(upkeepBefore.eq(upkeepAfter)) + // owner balance does not change + assert.isTrue(ownerAfter.eq(ownerBefore)) + // payee balance does not change + assert.isTrue(payee1Before.eq(payee1After)) + }) + }) + }) + }) + + describe('#withdrawPayment', () => { + beforeEach(async () => { + await linkToken.connect(owner).approve(registry.address, toWei('100')) + await registry.connect(owner).addFunds(upkeepId, toWei('100')) + await getTransmitTx(registry, keeper1, [upkeepId]) + }) + + it('reverts if called by anyone but the payee', async () => { + await evmRevert( + registry + .connect(payee2) + .withdrawPayment( + await keeper1.getAddress(), + await nonkeeper.getAddress(), + ), + 'OnlyCallableByPayee()', + ) + }) + + it('reverts if called with the 0 address', async () => { + await evmRevert( + registry + .connect(payee2) + .withdrawPayment(await keeper1.getAddress(), zeroAddress), + 'InvalidRecipient()', + ) + }) + + it('updates the balances', async () => { + const to = await nonkeeper.getAddress() + const keeperBefore = await registry.getTransmitterInfo( + await keeper1.getAddress(), + ) + const registrationBefore = (await registry.getUpkeep(upkeepId)).balance + const toLinkBefore = await linkToken.balanceOf(to) + const registryLinkBefore = await linkToken.balanceOf(registry.address) + const registryPremiumBefore = (await registry.getState()).state + .totalPremium + const ownerBefore = (await registry.getState()).state.ownerLinkBalance + + // Withdrawing for first time, last collected = 0 + assert.equal(keeperBefore.lastCollected.toString(), '0') + + //// Do the thing + await registry + .connect(payee1) + .withdrawPayment(await keeper1.getAddress(), to) + + const keeperAfter = await registry.getTransmitterInfo( + await keeper1.getAddress(), + ) + const registrationAfter = (await registry.getUpkeep(upkeepId)).balance + const toLinkAfter = await linkToken.balanceOf(to) + const registryLinkAfter = await linkToken.balanceOf(registry.address) + const registryPremiumAfter = (await registry.getState()).state + .totalPremium + const ownerAfter = (await registry.getState()).state.ownerLinkBalance + + // registry total premium should not change + assert.isTrue(registryPremiumBefore.eq(registryPremiumAfter)) + + // Last collected should be updated to premium-change + assert.isTrue( + keeperAfter.lastCollected.eq( + registryPremiumBefore.sub( + registryPremiumBefore.mod(keeperAddresses.length), + ), + ), + ) + + // owner balance should remain unchanged + assert.isTrue(ownerAfter.eq(ownerBefore)) + + assert.isTrue(keeperAfter.balance.eq(BigNumber.from(0))) + assert.isTrue(registrationBefore.eq(registrationAfter)) + assert.isTrue(toLinkBefore.add(keeperBefore.balance).eq(toLinkAfter)) + assert.isTrue( + registryLinkBefore.sub(keeperBefore.balance).eq(registryLinkAfter), + ) + }) + + it('emits a log announcing the withdrawal', async () => { + const balance = ( + await registry.getTransmitterInfo(await keeper1.getAddress()) + ).balance + const tx = await registry + .connect(payee1) + .withdrawPayment( + await keeper1.getAddress(), + await nonkeeper.getAddress(), + ) + await expect(tx) + .to.emit(registry, 'PaymentWithdrawn') + .withArgs( + await keeper1.getAddress(), + balance, + await nonkeeper.getAddress(), + await payee1.getAddress(), + ) + }) + }) + + describe('#checkCallback', () => { + it('returns false with appropriate failure reason when target callback reverts', async () => { + await streamsLookupUpkeep.setShouldRevertCallback(true) + + const values: any[] = ['0x1234', '0xabcd'] + const res = await registry + .connect(zeroAddress) + .callStatic.checkCallback(streamsLookupUpkeepId, values, '0x') + + assert.isFalse(res.upkeepNeeded) + assert.equal(res.performData, '0x') + assert.equal( + res.upkeepFailureReason, + UpkeepFailureReason.CHECK_CALLBACK_REVERTED, + ) + assert.isTrue(res.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + }) + + it('returns false with appropriate failure reason when target callback returns big performData', async () => { + let longBytes = '0x' + for (let i = 0; i <= maxPerformDataSize.toNumber(); i++) { + longBytes += '11' + } + const values: any[] = [longBytes, longBytes] + const res = await registry + .connect(zeroAddress) + .callStatic.checkCallback(streamsLookupUpkeepId, values, '0x') + + assert.isFalse(res.upkeepNeeded) + assert.equal(res.performData, '0x') + assert.equal( + res.upkeepFailureReason, + UpkeepFailureReason.PERFORM_DATA_EXCEEDS_LIMIT, + ) + assert.isTrue(res.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + }) + + it('returns false with appropriate failure reason when target callback returns false', async () => { + await streamsLookupUpkeep.setCallbackReturnBool(false) + const values: any[] = ['0x1234', '0xabcd'] + const res = await registry + .connect(zeroAddress) + .callStatic.checkCallback(streamsLookupUpkeepId, values, '0x') + + assert.isFalse(res.upkeepNeeded) + assert.equal(res.performData, '0x') + assert.equal( + res.upkeepFailureReason, + UpkeepFailureReason.UPKEEP_NOT_NEEDED, + ) + assert.isTrue(res.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + }) + + it('succeeds with upkeep needed', async () => { + const values: any[] = ['0x1234', '0xabcd'] + + const res = await registry + .connect(zeroAddress) + .callStatic.checkCallback(streamsLookupUpkeepId, values, '0x') + const expectedPerformData = ethers.utils.defaultAbiCoder.encode( + ['bytes[]', 'bytes'], + [values, '0x'], + ) + + assert.isTrue(res.upkeepNeeded) + assert.equal(res.performData, expectedPerformData) + assert.equal(res.upkeepFailureReason, UpkeepFailureReason.NONE) + assert.isTrue(res.gasUsed.gt(BigNumber.from('0'))) // Some gas should be used + }) + }) + + describe('#setUpkeepPrivilegeConfig() / #getUpkeepPrivilegeConfig()', () => { + it('reverts when non manager tries to set privilege config', async () => { + await evmRevert( + registry.connect(payee3).setUpkeepPrivilegeConfig(upkeepId, '0x1234'), + 'OnlyCallableByUpkeepPrivilegeManager()', + ) + }) + + it('returns empty bytes for upkeep privilege config before setting', async () => { + const cfg = await registry.getUpkeepPrivilegeConfig(upkeepId) + assert.equal(cfg, '0x') + }) + + it('allows upkeep manager to set privilege config', async () => { + const tx = await registry + .connect(personas.Norbert) + .setUpkeepPrivilegeConfig(upkeepId, '0x1234') + await expect(tx) + .to.emit(registry, 'UpkeepPrivilegeConfigSet') + .withArgs(upkeepId, '0x1234') + + const cfg = await registry.getUpkeepPrivilegeConfig(upkeepId) + assert.equal(cfg, '0x1234') + }) + }) + + describe('#setAdminPrivilegeConfig() / #getAdminPrivilegeConfig()', () => { + const admin = randomAddress() + + it('reverts when non manager tries to set privilege config', async () => { + await evmRevert( + registry.connect(payee3).setAdminPrivilegeConfig(admin, '0x1234'), + 'OnlyCallableByUpkeepPrivilegeManager()', + ) + }) + + it('returns empty bytes for upkeep privilege config before setting', async () => { + const cfg = await registry.getAdminPrivilegeConfig(admin) + assert.equal(cfg, '0x') + }) + + it('allows upkeep manager to set privilege config', async () => { + const tx = await registry + .connect(personas.Norbert) + .setAdminPrivilegeConfig(admin, '0x1234') + await expect(tx) + .to.emit(registry, 'AdminPrivilegeConfigSet') + .withArgs(admin, '0x1234') + + const cfg = await registry.getAdminPrivilegeConfig(admin) + assert.equal(cfg, '0x1234') + }) + }) + + describe('transmitterPremiumSplit [ @skip-coverage ]', () => { + beforeEach(async () => { + await linkToken.connect(owner).approve(registry.address, toWei('100')) + await registry.connect(owner).addFunds(upkeepId, toWei('100')) + }) + + it('splits premium evenly across transmitters', async () => { + // Do a transmit from keeper1 + await getTransmitTx(registry, keeper1, [upkeepId]) + + const registryPremium = (await registry.getState()).state.totalPremium + assert.isTrue(registryPremium.gt(BigNumber.from(0))) + + const premiumPerTransmitter = registryPremium.div( + BigNumber.from(keeperAddresses.length), + ) + const k1Balance = ( + await registry.getTransmitterInfo(await keeper1.getAddress()) + ).balance + // transmitter should be reimbursed for gas and get the premium + assert.isTrue(k1Balance.gt(premiumPerTransmitter)) + const k1GasReimbursement = k1Balance.sub(premiumPerTransmitter) + + const k2Balance = ( + await registry.getTransmitterInfo(await keeper2.getAddress()) + ).balance + // non transmitter should get its share of premium + assert.isTrue(k2Balance.eq(premiumPerTransmitter)) + + // Now do a transmit from keeper 2 + await getTransmitTx(registry, keeper2, [upkeepId]) + const registryPremiumNew = (await registry.getState()).state.totalPremium + assert.isTrue(registryPremiumNew.gt(registryPremium)) + const premiumPerTransmitterNew = registryPremiumNew.div( + BigNumber.from(keeperAddresses.length), + ) + const additionalPremium = premiumPerTransmitterNew.sub( + premiumPerTransmitter, + ) + + const k1BalanceNew = ( + await registry.getTransmitterInfo(await keeper1.getAddress()) + ).balance + // k1 should get the new premium + assert.isTrue( + k1BalanceNew.eq(k1GasReimbursement.add(premiumPerTransmitterNew)), + ) + + const k2BalanceNew = ( + await registry.getTransmitterInfo(await keeper2.getAddress()) + ).balance + // k2 should get gas reimbursement in addition to new premium + assert.isTrue(k2BalanceNew.gt(k2Balance.add(additionalPremium))) + }) + + it('updates last collected upon payment withdrawn', async () => { + // Do a transmit from keeper1 + await getTransmitTx(registry, keeper1, [upkeepId]) + + const registryPremium = (await registry.getState()).state.totalPremium + const k1 = await registry.getTransmitterInfo(await keeper1.getAddress()) + const k2 = await registry.getTransmitterInfo(await keeper2.getAddress()) + + // Withdrawing for first time, last collected = 0 + assert.isTrue(k1.lastCollected.eq(BigNumber.from(0))) + assert.isTrue(k2.lastCollected.eq(BigNumber.from(0))) + + //// Do the thing + await registry + .connect(payee1) + .withdrawPayment( + await keeper1.getAddress(), + await nonkeeper.getAddress(), + ) + + const k1New = await registry.getTransmitterInfo( + await keeper1.getAddress(), + ) + const k2New = await registry.getTransmitterInfo( + await keeper2.getAddress(), + ) + + // transmitter info lastCollected should be updated for k1, not for k2 + assert.isTrue( + k1New.lastCollected.eq( + registryPremium.sub(registryPremium.mod(keeperAddresses.length)), + ), + ) + assert.isTrue(k2New.lastCollected.eq(BigNumber.from(0))) + }) + + itMaybe( + 'maintains consistent balance information across all parties', + async () => { + // throughout transmits, withdrawals, setConfigs total claim on balances should remain less than expected balance + // some spare change can get lost but it should be less than maxAllowedSpareChange + + let maxAllowedSpareChange = BigNumber.from('0') + await verifyConsistentAccounting(maxAllowedSpareChange) + + await getTransmitTx(registry, keeper1, [upkeepId]) + maxAllowedSpareChange = maxAllowedSpareChange.add(BigNumber.from('31')) + await verifyConsistentAccounting(maxAllowedSpareChange) + + await registry + .connect(payee1) + .withdrawPayment( + await keeper1.getAddress(), + await nonkeeper.getAddress(), + ) + await verifyConsistentAccounting(maxAllowedSpareChange) + + await registry + .connect(payee2) + .withdrawPayment( + await keeper2.getAddress(), + await nonkeeper.getAddress(), + ) + await verifyConsistentAccounting(maxAllowedSpareChange) + + await getTransmitTx(registry, keeper1, [upkeepId]) + maxAllowedSpareChange = maxAllowedSpareChange.add(BigNumber.from('31')) + await verifyConsistentAccounting(maxAllowedSpareChange) + + await registry.connect(owner).setConfigTypeSafe( + signerAddresses.slice(2, 15), // only use 2-14th index keepers + keeperAddresses.slice(2, 15), + f, + config, + offchainVersion, + offchainBytes, + ) + await verifyConsistentAccounting(maxAllowedSpareChange) + + await getTransmitTx(registry, keeper3, [upkeepId], { + startingSignerIndex: 2, + }) + maxAllowedSpareChange = maxAllowedSpareChange.add(BigNumber.from('13')) + await verifyConsistentAccounting(maxAllowedSpareChange) + + await registry + .connect(payee1) + .withdrawPayment( + await keeper1.getAddress(), + await nonkeeper.getAddress(), + ) + await verifyConsistentAccounting(maxAllowedSpareChange) + + await registry + .connect(payee3) + .withdrawPayment( + await keeper3.getAddress(), + await nonkeeper.getAddress(), + ) + await verifyConsistentAccounting(maxAllowedSpareChange) + + await registry.connect(owner).setConfigTypeSafe( + signerAddresses.slice(0, 4), // only use 0-3rd index keepers + keeperAddresses.slice(0, 4), + f, + config, + offchainVersion, + offchainBytes, + ) + await verifyConsistentAccounting(maxAllowedSpareChange) + await getTransmitTx(registry, keeper1, [upkeepId]) + maxAllowedSpareChange = maxAllowedSpareChange.add(BigNumber.from('4')) + await getTransmitTx(registry, keeper3, [upkeepId]) + maxAllowedSpareChange = maxAllowedSpareChange.add(BigNumber.from('4')) + + await verifyConsistentAccounting(maxAllowedSpareChange) + await registry + .connect(payee5) + .withdrawPayment( + await keeper5.getAddress(), + await nonkeeper.getAddress(), + ) + await verifyConsistentAccounting(maxAllowedSpareChange) + + await registry + .connect(payee1) + .withdrawPayment( + await keeper1.getAddress(), + await nonkeeper.getAddress(), + ) + await verifyConsistentAccounting(maxAllowedSpareChange) + }, + ) + }) +}) diff --git a/contracts/test/v0.8/automation/helpers.ts b/contracts/test/v0.8/automation/helpers.ts index b3b4f0ef8b4..a7b6a582966 100644 --- a/contracts/test/v0.8/automation/helpers.ts +++ b/contracts/test/v0.8/automation/helpers.ts @@ -68,3 +68,39 @@ export const deployRegistry22 = async ( const master = await registryFactory.connect(from).deploy(logicA.address) return IAutomationRegistryMasterFactory.connect(master.address, from) } + +export const deployRegistry23 = async ( + from: Signer, + link: Parameters[0], + linkNative: Parameters[1], + fastgas: Parameters[2], + allowedReadOnlyAddress: Parameters< + AutomationRegistryLogicBFactory['deploy'] + >[3], +): Promise => { + const logicBFactory = await ethers.getContractFactory( + 'AutomationRegistryLogicB2_3', + ) + const logicAFactory = await ethers.getContractFactory( + 'AutomationRegistryLogicA2_3', + ) + const registryFactory = await ethers.getContractFactory( + 'AutomationRegistry2_3', + ) + const forwarderLogicFactory = await ethers.getContractFactory( + 'AutomationForwarderLogic', + ) + const forwarderLogic = await forwarderLogicFactory.connect(from).deploy() + const logicB = await logicBFactory + .connect(from) + .deploy( + link, + linkNative, + fastgas, + forwarderLogic.address, + allowedReadOnlyAddress, + ) + const logicA = await logicAFactory.connect(from).deploy(logicB.address) + const master = await registryFactory.connect(from).deploy(logicA.address) + return IAutomationRegistryMasterFactory.connect(master.address, from) +} diff --git a/core/gethwrappers/generated/automation_registrar_wrapper2_3/automation_registrar_wrapper2_3.go b/core/gethwrappers/generated/automation_registrar_wrapper2_3/automation_registrar_wrapper2_3.go new file mode 100644 index 00000000000..668a2235b45 --- /dev/null +++ b/core/gethwrappers/generated/automation_registrar_wrapper2_3/automation_registrar_wrapper2_3.go @@ -0,0 +1,1685 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package automation_registrar_wrapper2_3 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type AutomationRegistrar23InitialTriggerConfig struct { + TriggerType uint8 + AutoApproveType uint8 + AutoApproveMaxAllowed uint32 +} + +type AutomationRegistrar23RegistrationParams struct { + Name string + EncryptedEmail []byte + UpkeepContract common.Address + GasLimit uint32 + AdminAddress common.Address + TriggerType uint8 + CheckData []byte + TriggerConfig []byte + OffchainConfig []byte + Amount *big.Int +} + +type AutomationRegistrar23TriggerRegistrationStorage struct { + AutoApproveType uint8 + AutoApproveMaxAllowed uint32 + ApprovedCount uint32 +} + +var AutomationRegistrarMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"LINKAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"AutomationRegistry\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"minLINKJuels\",\"type\":\"uint96\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"}],\"internalType\":\"structAutomationRegistrar2_3.InitialTriggerConfig[]\",\"name\":\"triggerConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AmountMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FunctionNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HashMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientPayment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAdminAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"LinkTransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistrationRequestFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RequestNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SenderMismatch\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"AutoApproveAllowedSenderSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"AutomationRegistry\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"minLINKJuels\",\"type\":\"uint96\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"displayName\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"RegistrationApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"RegistrationRejected\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"RegistrationRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"}],\"name\":\"TriggerConfigSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"cancel\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"}],\"name\":\"getAutoApproveAllowedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"AutomationRegistry\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minLINKJuels\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"getPendingRequest\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"}],\"name\":\"getTriggerRegistrationDetails\",\"outputs\":[{\"components\":[{\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"approvedCount\",\"type\":\"uint32\"}],\"internalType\":\"structAutomationRegistrar2_3.TriggerRegistrationStorage\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"internalType\":\"structAutomationRegistrar2_3.RegistrationParams\",\"name\":\"requestParams\",\"type\":\"tuple\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"setAutoApproveAllowedSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"AutomationRegistry\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"minLINKJuels\",\"type\":\"uint96\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"}],\"name\":\"setTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b5060405162002d8238038062002d8283398101604081905262000034916200043b565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be816200017a565b5050506001600160a01b038416608052620000da838362000225565b60005b81518110156200016f576200015a82828151811062000100576200010062000598565b60200260200101516000015183838151811062000121576200012162000598565b60200260200101516020015184848151811062000142576200014262000598565b6020026020010151604001516200029e60201b60201c565b806200016681620005ae565b915050620000dd565b50505050506200062f565b336001600160a01b03821603620001d45760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200022f6200034c565b6040805180820182526001600160a01b0384168082526001600160601b0384166020928301819052600160a01b810282176004558351918252918101919091527f39ce5d867555f0b0183e358fce5b158e7ca4fecd7c01cb7e0e19f1e23285838a910160405180910390a15050565b620002a86200034c565b60ff83166000908152600360205260409020805483919060ff19166001836002811115620002da57620002da620005d6565b021790555060ff831660009081526003602052604090819020805464ffffffff00191661010063ffffffff851602179055517f830a6d06a4e2caac67eba04323de22bdb04f032dd8b3d6a0c52b503d9a7036a3906200033f90859085908590620005ec565b60405180910390a1505050565b6000546001600160a01b03163314620003a85760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b80516001600160a01b0381168114620003c257600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b0381118282101715620004025762000402620003c7565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620004335762000433620003c7565b604052919050565b600080600080608085870312156200045257600080fd5b6200045d85620003aa565b935060206200046e818701620003aa565b604087810151919550906001600160601b03811681146200048e57600080fd5b606088810151919550906001600160401b0380821115620004ae57600080fd5b818a0191508a601f830112620004c357600080fd5b815181811115620004d857620004d8620003c7565b620004e8868260051b0162000408565b818152868101925090840283018601908c8211156200050657600080fd5b928601925b81841015620005875784848e031215620005255760008081fd5b6200052f620003dd565b845160ff81168114620005425760008081fd5b81528488015160038110620005575760008081fd5b818901528487015163ffffffff81168114620005735760008081fd5b81880152835292840192918601916200050b565b999c989b5096995050505050505050565b634e487b7160e01b600052603260045260246000fd5b600060018201620005cf57634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052602160045260246000fd5b60ff8416815260608101600384106200061557634e487b7160e01b600052602160045260246000fd5b83602083015263ffffffff83166040830152949350505050565b6080516127146200066e60003960008181610177015281816105d601528181610887015281816109bd01528181610f0e015261171b01526127146000f3fe608060405234801561001057600080fd5b506004361061011b5760003560e01c8063856853e6116100b2578063b5ff5b4111610081578063c4d252f511610066578063c4d252f5146103e3578063e8d4070d146103f6578063f2fde38b1461040957600080fd5b8063b5ff5b4114610369578063c3f909d41461037c57600080fd5b8063856853e61461027857806388b12d551461028b5780638da5cb5b14610338578063a4c0ed361461035657600080fd5b80633f678e11116100ee5780633f678e11146101f35780636c4cdfc31461021457806379ba5097146102275780637e776f7f1461022f57600080fd5b8063181f5a77146101205780631b6b6d2314610172578063212d0884146101be578063367b9b4f146101de575b600080fd5b61015c6040518060400160405280601981526020017f4175746f6d6174696f6e52656769737472617220322e332e300000000000000081525081565b6040516101699190611a74565b60405180910390f35b6101997f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610169565b6101d16101cc366004611aa4565b61041c565b6040516101699190611b29565b6101f16101ec366004611b9d565b6104a9565b005b610206610201366004611bd6565b61053b565b604051908152602001610169565b6101f1610222366004611c2e565b6106d3565b6101f161076d565b61026861023d366004611c63565b73ffffffffffffffffffffffffffffffffffffffff1660009081526005602052604090205460ff1690565b6040519015158152602001610169565b6101f1610286366004611de1565b61086f565b6102ff610299366004611f40565b60009081526002602090815260409182902082518084019093525473ffffffffffffffffffffffffffffffffffffffff8116808452740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff169290910182905291565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526bffffffffffffffffffffffff909116602083015201610169565b60005473ffffffffffffffffffffffffffffffffffffffff16610199565b6101f1610364366004611f59565b6109a5565b6101f1610377366004611fb5565b610ce3565b60408051808201825260045473ffffffffffffffffffffffffffffffffffffffff8116808352740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16602092830181905283519182529181019190915201610169565b6101f16103f1366004611f40565b610dc2565b6101f1610404366004611ffe565b61104c565b6101f1610417366004611c63565b6112d9565b60408051606080820183526000808352602080840182905283850182905260ff86811683526003909152908490208451928301909452835492939192839116600281111561046c5761046c611abf565b600281111561047d5761047d611abf565b8152905463ffffffff610100820481166020840152650100000000009091041660409091015292915050565b6104b16112ed565b73ffffffffffffffffffffffffffffffffffffffff821660008181526005602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915591519182527f20c6237dac83526a849285a9f79d08a483291bdd3a056a0ef9ae94ecee1ad356910160405180910390a25050565b6004546000907401000000000000000000000000000000000000000090046bffffffffffffffffffffffff1661057961014084016101208501612109565b6bffffffffffffffffffffffff1610156105bf576040517fcd1c886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166323b872dd333061060f61014087016101208801612109565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815273ffffffffffffffffffffffffffffffffffffffff93841660048201529290911660248301526bffffffffffffffffffffffff1660448201526064016020604051808303816000875af1158015610696573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ba9190612124565b506106cd6106c783612141565b33611370565b92915050565b6106db6112ed565b60408051808201825273ffffffffffffffffffffffffffffffffffffffff84168082526bffffffffffffffffffffffff8416602092830181905274010000000000000000000000000000000000000000810282176004558351918252918101919091527f39ce5d867555f0b0183e358fce5b158e7ca4fecd7c01cb7e0e19f1e23285838a910160405180910390a15050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146107f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146108de576040517f018d10be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109966040518061014001604052808e81526020018d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525073ffffffffffffffffffffffffffffffffffffffff808d16602083015263ffffffff8c1660408301528a16606082015260ff8916608082015260a0810188905260c0810187905260e081018690526bffffffffffffffffffffffff85166101009091015282611370565b50505050505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610a14576040517f018d10be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81818080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050505060208101517fffffffff0000000000000000000000000000000000000000000000000000000081167f856853e60000000000000000000000000000000000000000000000000000000014610aca576040517fe3d6792100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8484846000610adc8260048186612276565b810190610ae991906122a0565b509950505050505050505050806bffffffffffffffffffffffff168414610b3c576040517f55e97b0d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8988886000610b4e8260048186612276565b810190610b5b91906122a0565b9a50505050505050505050508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610bcc576040517ff8c5638e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004547401000000000000000000000000000000000000000090046bffffffffffffffffffffffff168d1015610c2e576040517fcd1c886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60003073ffffffffffffffffffffffffffffffffffffffff168d8d604051610c579291906123dd565b600060405180830381855af49150503d8060008114610c92576040519150601f19603f3d011682016040523d82523d6000602084013e610c97565b606091505b5050905080610cd2576040517f649bf81000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050505050565b610ceb6112ed565b60ff8316600090815260036020526040902080548391907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836002811115610d3857610d38611abf565b021790555060ff83166000908152600360205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010063ffffffff851602179055517f830a6d06a4e2caac67eba04323de22bdb04f032dd8b3d6a0c52b503d9a7036a390610db5908590859085906123ed565b60405180910390a1505050565b60008181526002602090815260409182902082518084019093525473ffffffffffffffffffffffffffffffffffffffff8116808452740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff1691830191909152331480610e49575060005473ffffffffffffffffffffffffffffffffffffffff1633145b610e7f576040517f61685c2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805173ffffffffffffffffffffffffffffffffffffffff16610ecd576040517f4b13b31e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260026020908152604080832083905583519184015190517fa9059cbb0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169263a9059cbb92610f859260040173ffffffffffffffffffffffffffffffffffffffff9290921682526bffffffffffffffffffffffff16602082015260400190565b6020604051808303816000875af1158015610fa4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc89190612124565b90508061101c5781516040517fc2e4dce800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016107ea565b60405183907f3663fb28ebc87645eb972c9dad8521bf665c623f287e79f1c56f1eb374b82a2290600090a2505050565b6110546112ed565b60008181526002602090815260409182902082518084019093525473ffffffffffffffffffffffffffffffffffffffff8116808452740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16918301919091526110ed576040517f4b13b31e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008b8b8b8b8b8b8b8b8b60405160200161111099989796959493929190612461565b604051602081830303815290604052805190602001209050808314611161576040517f3f4d605300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026000848152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a8154906bffffffffffffffffffffffff021916905550506112c96040518061014001604052808f81526020016040518060200160405280600081525081526020018e73ffffffffffffffffffffffffffffffffffffffff1681526020018d63ffffffff1681526020018c73ffffffffffffffffffffffffffffffffffffffff1681526020018b60ff1681526020018a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060208082018a905260408051601f8a0183900483028101830182528981529201919089908990819084018382808284376000920191909152505050908252506020858101516bffffffffffffffffffffffff1691015282611647565b5050505050505050505050505050565b6112e16112ed565b6112ea81611876565b50565b60005473ffffffffffffffffffffffffffffffffffffffff16331461136e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107ea565b565b608082015160009073ffffffffffffffffffffffffffffffffffffffff166113c4576040517f05bb467c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008360400151846060015185608001518660a001518760c001518860e0015189610100015160405160200161140097969594939291906124e7565b604051602081830303815290604052805190602001209050836040015173ffffffffffffffffffffffffffffffffffffffff16817f7684390ebb103102f7f48c71439c2408713f8d437782a6fab2756acc0e42c1b786600001518760200151886060015189608001518a60a001518b60e001518c61010001518d60c001518e610120015160405161149999989796959493929190612569565b60405180910390a360a084015160ff9081166000908152600360205260408082208151606081019092528054929361151c9383911660028111156114df576114df611abf565b60028111156114f0576114f0611abf565b8152905463ffffffff61010082048116602084015265010000000000909104166040909101528561196b565b156115845760a085015160ff166000908152600360205260409020805465010000000000900463ffffffff1690600561155483612653565b91906101000a81548163ffffffff021916908363ffffffff1602179055505061157d8583611647565b905061163f565b61012085015160008381526002602052604081205490916115ca917401000000000000000000000000000000000000000090046bffffffffffffffffffffffff16612676565b604080518082018252608089015173ffffffffffffffffffffffffffffffffffffffff90811682526bffffffffffffffffffffffff9384166020808401918252600089815260029091529390932091519251909316740100000000000000000000000000000000000000000291909216179055505b949350505050565b600480546040808501516060860151608087015160a088015160c089015160e08a01516101008b015196517f28f32f3800000000000000000000000000000000000000000000000000000000815260009973ffffffffffffffffffffffffffffffffffffffff909916988a988a986328f32f38986116d29891979096919590949193909291016124e7565b6020604051808303816000875af11580156116f1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171591906126a2565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634000aea0848861012001518560405160200161176f91815260200190565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161179c939291906126bb565b6020604051808303816000875af11580156117bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117df9190612124565b905080611830576040517fc2e4dce800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024016107ea565b81857fb9a292fb7e3edd920cd2d2829a3615a640c43fd7de0a0820aa0668feb4c37d4b88600001516040516118659190611a74565b60405180910390a350949350505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036118f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107ea565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000808351600281111561198157611981611abf565b0361198e575060006106cd565b6001835160028111156119a3576119a3611abf565b1480156119d6575073ffffffffffffffffffffffffffffffffffffffff821660009081526005602052604090205460ff16155b156119e3575060006106cd565b826020015163ffffffff16836040015163ffffffff161015611a07575060016106cd565b50600092915050565b6000815180845260005b81811015611a3657602081850181015186830182015201611a1a565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611a876020830184611a10565b9392505050565b803560ff81168114611a9f57600080fd5b919050565b600060208284031215611ab657600080fd5b611a8782611a8e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110611b25577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b6000606082019050611b3c828451611aee565b602083015163ffffffff8082166020850152806040860151166040850152505092915050565b73ffffffffffffffffffffffffffffffffffffffff811681146112ea57600080fd5b8035611a9f81611b62565b80151581146112ea57600080fd5b60008060408385031215611bb057600080fd5b8235611bbb81611b62565b91506020830135611bcb81611b8f565b809150509250929050565b600060208284031215611be857600080fd5b813567ffffffffffffffff811115611bff57600080fd5b82016101408185031215611a8757600080fd5b80356bffffffffffffffffffffffff81168114611a9f57600080fd5b60008060408385031215611c4157600080fd5b8235611c4c81611b62565b9150611c5a60208401611c12565b90509250929050565b600060208284031215611c7557600080fd5b8135611a8781611b62565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611cd357611cd3611c80565b60405290565b600082601f830112611cea57600080fd5b813567ffffffffffffffff80821115611d0557611d05611c80565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715611d4b57611d4b611c80565b81604052838152866020858801011115611d6457600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008083601f840112611d9657600080fd5b50813567ffffffffffffffff811115611dae57600080fd5b602083019150836020828501011115611dc657600080fd5b9250929050565b803563ffffffff81168114611a9f57600080fd5b6000806000806000806000806000806000806101608d8f031215611e0457600080fd5b67ffffffffffffffff8d351115611e1a57600080fd5b611e278e8e358f01611cd9565b9b5067ffffffffffffffff60208e01351115611e4257600080fd5b611e528e60208f01358f01611d84565b909b509950611e6360408e01611b84565b9850611e7160608e01611dcd565b9750611e7f60808e01611b84565b9650611e8d60a08e01611a8e565b955067ffffffffffffffff60c08e01351115611ea857600080fd5b611eb88e60c08f01358f01611cd9565b945067ffffffffffffffff60e08e01351115611ed357600080fd5b611ee38e60e08f01358f01611cd9565b935067ffffffffffffffff6101008e01351115611eff57600080fd5b611f108e6101008f01358f01611cd9565b9250611f1f6101208e01611c12565b9150611f2e6101408e01611b84565b90509295989b509295989b509295989b565b600060208284031215611f5257600080fd5b5035919050565b60008060008060608587031215611f6f57600080fd5b8435611f7a81611b62565b935060208501359250604085013567ffffffffffffffff811115611f9d57600080fd5b611fa987828801611d84565b95989497509550505050565b600080600060608486031215611fca57600080fd5b611fd384611a8e565b9250602084013560038110611fe757600080fd5b9150611ff560408501611dcd565b90509250925092565b60008060008060008060008060008060006101208c8e03121561202057600080fd5b67ffffffffffffffff808d35111561203757600080fd5b6120448e8e358f01611cd9565b9b5061205260208e01611b84565b9a5061206060408e01611dcd565b995061206e60608e01611b84565b985061207c60808e01611a8e565b97508060a08e0135111561208f57600080fd5b61209f8e60a08f01358f01611d84565b909750955060c08d01358110156120b557600080fd5b6120c58e60c08f01358f01611cd9565b94508060e08e013511156120d857600080fd5b506120e98d60e08e01358e01611d84565b81945080935050506101008c013590509295989b509295989b9093969950565b60006020828403121561211b57600080fd5b611a8782611c12565b60006020828403121561213657600080fd5b8151611a8781611b8f565b6000610140823603121561215457600080fd5b61215c611caf565b823567ffffffffffffffff8082111561217457600080fd5b61218036838701611cd9565b8352602085013591508082111561219657600080fd5b6121a236838701611cd9565b60208401526121b360408601611b84565b60408401526121c460608601611dcd565b60608401526121d560808601611b84565b60808401526121e660a08601611a8e565b60a084015260c08501359150808211156121ff57600080fd5b61220b36838701611cd9565b60c084015260e085013591508082111561222457600080fd5b61223036838701611cd9565b60e08401526101009150818501358181111561224b57600080fd5b61225736828801611cd9565b8385015250505061012061226c818501611c12565b9082015292915050565b6000808585111561228657600080fd5b8386111561229357600080fd5b5050820193919092039150565b60008060008060008060008060008060006101608c8e0312156122c257600080fd5b67ffffffffffffffff808d3511156122d957600080fd5b6122e68e8e358f01611cd9565b9b508060208e013511156122f957600080fd5b6123098e60208f01358f01611cd9565b9a5061231760408e01611b84565b995061232560608e01611dcd565b985061233360808e01611b84565b975061234160a08e01611a8e565b96508060c08e0135111561235457600080fd5b6123648e60c08f01358f01611cd9565b95508060e08e0135111561237757600080fd5b6123878e60e08f01358f01611cd9565b9450806101008e0135111561239b57600080fd5b506123ad8d6101008e01358e01611cd9565b92506123bc6101208d01611c12565b91506123cb6101408d01611b84565b90509295989b509295989b9093969950565b8183823760009101908152919050565b60ff84168152606081016124046020830185611aee565b63ffffffff83166040830152949350505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b600073ffffffffffffffffffffffffffffffffffffffff808c16835263ffffffff8b166020840152808a1660408401525060ff8816606083015260e060808301526124b060e083018789612418565b82810360a08401526124c28187611a10565b905082810360c08401526124d7818587612418565b9c9b505050505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835263ffffffff8916602084015280881660408401525060ff8616606083015260e0608083015261253560e0830186611a10565b82810360a08401526125478186611a10565b905082810360c084015261255b8185611a10565b9a9950505050505050505050565b600061012080835261257d8184018d611a10565b90508281036020840152612591818c611a10565b905063ffffffff8a16604084015273ffffffffffffffffffffffffffffffffffffffff8916606084015260ff8816608084015282810360a08401526125d68188611a10565b905082810360c08401526125ea8187611a10565b905082810360e08401526125fe8186611a10565b9150506bffffffffffffffffffffffff83166101008301529a9950505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600063ffffffff80831681810361266c5761266c612624565b6001019392505050565b6bffffffffffffffffffffffff81811683821601908082111561269b5761269b612624565b5092915050565b6000602082840312156126b457600080fd5b5051919050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff831660208201526060604082015260006126fe6060830184611a10565b9594505050505056fea164736f6c6343000813000a", +} + +var AutomationRegistrarABI = AutomationRegistrarMetaData.ABI + +var AutomationRegistrarBin = AutomationRegistrarMetaData.Bin + +func DeployAutomationRegistrar(auth *bind.TransactOpts, backend bind.ContractBackend, LINKAddress common.Address, AutomationRegistry common.Address, minLINKJuels *big.Int, triggerConfigs []AutomationRegistrar23InitialTriggerConfig) (common.Address, *types.Transaction, *AutomationRegistrar, error) { + parsed, err := AutomationRegistrarMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(AutomationRegistrarBin), backend, LINKAddress, AutomationRegistry, minLINKJuels, triggerConfigs) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &AutomationRegistrar{address: address, abi: *parsed, AutomationRegistrarCaller: AutomationRegistrarCaller{contract: contract}, AutomationRegistrarTransactor: AutomationRegistrarTransactor{contract: contract}, AutomationRegistrarFilterer: AutomationRegistrarFilterer{contract: contract}}, nil +} + +type AutomationRegistrar struct { + address common.Address + abi abi.ABI + AutomationRegistrarCaller + AutomationRegistrarTransactor + AutomationRegistrarFilterer +} + +type AutomationRegistrarCaller struct { + contract *bind.BoundContract +} + +type AutomationRegistrarTransactor struct { + contract *bind.BoundContract +} + +type AutomationRegistrarFilterer struct { + contract *bind.BoundContract +} + +type AutomationRegistrarSession struct { + Contract *AutomationRegistrar + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type AutomationRegistrarCallerSession struct { + Contract *AutomationRegistrarCaller + CallOpts bind.CallOpts +} + +type AutomationRegistrarTransactorSession struct { + Contract *AutomationRegistrarTransactor + TransactOpts bind.TransactOpts +} + +type AutomationRegistrarRaw struct { + Contract *AutomationRegistrar +} + +type AutomationRegistrarCallerRaw struct { + Contract *AutomationRegistrarCaller +} + +type AutomationRegistrarTransactorRaw struct { + Contract *AutomationRegistrarTransactor +} + +func NewAutomationRegistrar(address common.Address, backend bind.ContractBackend) (*AutomationRegistrar, error) { + abi, err := abi.JSON(strings.NewReader(AutomationRegistrarABI)) + if err != nil { + return nil, err + } + contract, err := bindAutomationRegistrar(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AutomationRegistrar{address: address, abi: abi, AutomationRegistrarCaller: AutomationRegistrarCaller{contract: contract}, AutomationRegistrarTransactor: AutomationRegistrarTransactor{contract: contract}, AutomationRegistrarFilterer: AutomationRegistrarFilterer{contract: contract}}, nil +} + +func NewAutomationRegistrarCaller(address common.Address, caller bind.ContractCaller) (*AutomationRegistrarCaller, error) { + contract, err := bindAutomationRegistrar(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AutomationRegistrarCaller{contract: contract}, nil +} + +func NewAutomationRegistrarTransactor(address common.Address, transactor bind.ContractTransactor) (*AutomationRegistrarTransactor, error) { + contract, err := bindAutomationRegistrar(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AutomationRegistrarTransactor{contract: contract}, nil +} + +func NewAutomationRegistrarFilterer(address common.Address, filterer bind.ContractFilterer) (*AutomationRegistrarFilterer, error) { + contract, err := bindAutomationRegistrar(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AutomationRegistrarFilterer{contract: contract}, nil +} + +func bindAutomationRegistrar(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := AutomationRegistrarMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_AutomationRegistrar *AutomationRegistrarRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AutomationRegistrar.Contract.AutomationRegistrarCaller.contract.Call(opts, result, method, params...) +} + +func (_AutomationRegistrar *AutomationRegistrarRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.AutomationRegistrarTransactor.contract.Transfer(opts) +} + +func (_AutomationRegistrar *AutomationRegistrarRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.AutomationRegistrarTransactor.contract.Transact(opts, method, params...) +} + +func (_AutomationRegistrar *AutomationRegistrarCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AutomationRegistrar.Contract.contract.Call(opts, result, method, params...) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.contract.Transfer(opts) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.contract.Transact(opts, method, params...) +} + +func (_AutomationRegistrar *AutomationRegistrarCaller) LINK(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AutomationRegistrar.contract.Call(opts, &out, "LINK") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_AutomationRegistrar *AutomationRegistrarSession) LINK() (common.Address, error) { + return _AutomationRegistrar.Contract.LINK(&_AutomationRegistrar.CallOpts) +} + +func (_AutomationRegistrar *AutomationRegistrarCallerSession) LINK() (common.Address, error) { + return _AutomationRegistrar.Contract.LINK(&_AutomationRegistrar.CallOpts) +} + +func (_AutomationRegistrar *AutomationRegistrarCaller) GetAutoApproveAllowedSender(opts *bind.CallOpts, senderAddress common.Address) (bool, error) { + var out []interface{} + err := _AutomationRegistrar.contract.Call(opts, &out, "getAutoApproveAllowedSender", senderAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_AutomationRegistrar *AutomationRegistrarSession) GetAutoApproveAllowedSender(senderAddress common.Address) (bool, error) { + return _AutomationRegistrar.Contract.GetAutoApproveAllowedSender(&_AutomationRegistrar.CallOpts, senderAddress) +} + +func (_AutomationRegistrar *AutomationRegistrarCallerSession) GetAutoApproveAllowedSender(senderAddress common.Address) (bool, error) { + return _AutomationRegistrar.Contract.GetAutoApproveAllowedSender(&_AutomationRegistrar.CallOpts, senderAddress) +} + +func (_AutomationRegistrar *AutomationRegistrarCaller) GetConfig(opts *bind.CallOpts) (GetConfig, + + error) { + var out []interface{} + err := _AutomationRegistrar.contract.Call(opts, &out, "getConfig") + + outstruct := new(GetConfig) + if err != nil { + return *outstruct, err + } + + outstruct.AutomationRegistry = *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + outstruct.MinLINKJuels = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_AutomationRegistrar *AutomationRegistrarSession) GetConfig() (GetConfig, + + error) { + return _AutomationRegistrar.Contract.GetConfig(&_AutomationRegistrar.CallOpts) +} + +func (_AutomationRegistrar *AutomationRegistrarCallerSession) GetConfig() (GetConfig, + + error) { + return _AutomationRegistrar.Contract.GetConfig(&_AutomationRegistrar.CallOpts) +} + +func (_AutomationRegistrar *AutomationRegistrarCaller) GetPendingRequest(opts *bind.CallOpts, hash [32]byte) (common.Address, *big.Int, error) { + var out []interface{} + err := _AutomationRegistrar.contract.Call(opts, &out, "getPendingRequest", hash) + + if err != nil { + return *new(common.Address), *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return out0, out1, err + +} + +func (_AutomationRegistrar *AutomationRegistrarSession) GetPendingRequest(hash [32]byte) (common.Address, *big.Int, error) { + return _AutomationRegistrar.Contract.GetPendingRequest(&_AutomationRegistrar.CallOpts, hash) +} + +func (_AutomationRegistrar *AutomationRegistrarCallerSession) GetPendingRequest(hash [32]byte) (common.Address, *big.Int, error) { + return _AutomationRegistrar.Contract.GetPendingRequest(&_AutomationRegistrar.CallOpts, hash) +} + +func (_AutomationRegistrar *AutomationRegistrarCaller) GetTriggerRegistrationDetails(opts *bind.CallOpts, triggerType uint8) (AutomationRegistrar23TriggerRegistrationStorage, error) { + var out []interface{} + err := _AutomationRegistrar.contract.Call(opts, &out, "getTriggerRegistrationDetails", triggerType) + + if err != nil { + return *new(AutomationRegistrar23TriggerRegistrationStorage), err + } + + out0 := *abi.ConvertType(out[0], new(AutomationRegistrar23TriggerRegistrationStorage)).(*AutomationRegistrar23TriggerRegistrationStorage) + + return out0, err + +} + +func (_AutomationRegistrar *AutomationRegistrarSession) GetTriggerRegistrationDetails(triggerType uint8) (AutomationRegistrar23TriggerRegistrationStorage, error) { + return _AutomationRegistrar.Contract.GetTriggerRegistrationDetails(&_AutomationRegistrar.CallOpts, triggerType) +} + +func (_AutomationRegistrar *AutomationRegistrarCallerSession) GetTriggerRegistrationDetails(triggerType uint8) (AutomationRegistrar23TriggerRegistrationStorage, error) { + return _AutomationRegistrar.Contract.GetTriggerRegistrationDetails(&_AutomationRegistrar.CallOpts, triggerType) +} + +func (_AutomationRegistrar *AutomationRegistrarCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AutomationRegistrar.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_AutomationRegistrar *AutomationRegistrarSession) Owner() (common.Address, error) { + return _AutomationRegistrar.Contract.Owner(&_AutomationRegistrar.CallOpts) +} + +func (_AutomationRegistrar *AutomationRegistrarCallerSession) Owner() (common.Address, error) { + return _AutomationRegistrar.Contract.Owner(&_AutomationRegistrar.CallOpts) +} + +func (_AutomationRegistrar *AutomationRegistrarCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _AutomationRegistrar.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_AutomationRegistrar *AutomationRegistrarSession) TypeAndVersion() (string, error) { + return _AutomationRegistrar.Contract.TypeAndVersion(&_AutomationRegistrar.CallOpts) +} + +func (_AutomationRegistrar *AutomationRegistrarCallerSession) TypeAndVersion() (string, error) { + return _AutomationRegistrar.Contract.TypeAndVersion(&_AutomationRegistrar.CallOpts) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "acceptOwnership") +} + +func (_AutomationRegistrar *AutomationRegistrarSession) AcceptOwnership() (*types.Transaction, error) { + return _AutomationRegistrar.Contract.AcceptOwnership(&_AutomationRegistrar.TransactOpts) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _AutomationRegistrar.Contract.AcceptOwnership(&_AutomationRegistrar.TransactOpts) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactor) Approve(opts *bind.TransactOpts, name string, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte, hash [32]byte) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "approve", name, upkeepContract, gasLimit, adminAddress, triggerType, checkData, triggerConfig, offchainConfig, hash) +} + +func (_AutomationRegistrar *AutomationRegistrarSession) Approve(name string, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte, hash [32]byte) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.Approve(&_AutomationRegistrar.TransactOpts, name, upkeepContract, gasLimit, adminAddress, triggerType, checkData, triggerConfig, offchainConfig, hash) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) Approve(name string, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte, hash [32]byte) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.Approve(&_AutomationRegistrar.TransactOpts, name, upkeepContract, gasLimit, adminAddress, triggerType, checkData, triggerConfig, offchainConfig, hash) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactor) Cancel(opts *bind.TransactOpts, hash [32]byte) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "cancel", hash) +} + +func (_AutomationRegistrar *AutomationRegistrarSession) Cancel(hash [32]byte) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.Cancel(&_AutomationRegistrar.TransactOpts, hash) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) Cancel(hash [32]byte) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.Cancel(&_AutomationRegistrar.TransactOpts, hash) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactor) OnTokenTransfer(opts *bind.TransactOpts, sender common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "onTokenTransfer", sender, amount, data) +} + +func (_AutomationRegistrar *AutomationRegistrarSession) OnTokenTransfer(sender common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.OnTokenTransfer(&_AutomationRegistrar.TransactOpts, sender, amount, data) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) OnTokenTransfer(sender common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.OnTokenTransfer(&_AutomationRegistrar.TransactOpts, sender, amount, data) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactor) Register(opts *bind.TransactOpts, name string, encryptedEmail []byte, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte, amount *big.Int, sender common.Address) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "register", name, encryptedEmail, upkeepContract, gasLimit, adminAddress, triggerType, checkData, triggerConfig, offchainConfig, amount, sender) +} + +func (_AutomationRegistrar *AutomationRegistrarSession) Register(name string, encryptedEmail []byte, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte, amount *big.Int, sender common.Address) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.Register(&_AutomationRegistrar.TransactOpts, name, encryptedEmail, upkeepContract, gasLimit, adminAddress, triggerType, checkData, triggerConfig, offchainConfig, amount, sender) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) Register(name string, encryptedEmail []byte, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte, amount *big.Int, sender common.Address) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.Register(&_AutomationRegistrar.TransactOpts, name, encryptedEmail, upkeepContract, gasLimit, adminAddress, triggerType, checkData, triggerConfig, offchainConfig, amount, sender) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactor) RegisterUpkeep(opts *bind.TransactOpts, requestParams AutomationRegistrar23RegistrationParams) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "registerUpkeep", requestParams) +} + +func (_AutomationRegistrar *AutomationRegistrarSession) RegisterUpkeep(requestParams AutomationRegistrar23RegistrationParams) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.RegisterUpkeep(&_AutomationRegistrar.TransactOpts, requestParams) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) RegisterUpkeep(requestParams AutomationRegistrar23RegistrationParams) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.RegisterUpkeep(&_AutomationRegistrar.TransactOpts, requestParams) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactor) SetAutoApproveAllowedSender(opts *bind.TransactOpts, senderAddress common.Address, allowed bool) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "setAutoApproveAllowedSender", senderAddress, allowed) +} + +func (_AutomationRegistrar *AutomationRegistrarSession) SetAutoApproveAllowedSender(senderAddress common.Address, allowed bool) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.SetAutoApproveAllowedSender(&_AutomationRegistrar.TransactOpts, senderAddress, allowed) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) SetAutoApproveAllowedSender(senderAddress common.Address, allowed bool) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.SetAutoApproveAllowedSender(&_AutomationRegistrar.TransactOpts, senderAddress, allowed) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactor) SetConfig(opts *bind.TransactOpts, AutomationRegistry common.Address, minLINKJuels *big.Int) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "setConfig", AutomationRegistry, minLINKJuels) +} + +func (_AutomationRegistrar *AutomationRegistrarSession) SetConfig(AutomationRegistry common.Address, minLINKJuels *big.Int) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.SetConfig(&_AutomationRegistrar.TransactOpts, AutomationRegistry, minLINKJuels) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) SetConfig(AutomationRegistry common.Address, minLINKJuels *big.Int) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.SetConfig(&_AutomationRegistrar.TransactOpts, AutomationRegistry, minLINKJuels) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactor) SetTriggerConfig(opts *bind.TransactOpts, triggerType uint8, autoApproveType uint8, autoApproveMaxAllowed uint32) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "setTriggerConfig", triggerType, autoApproveType, autoApproveMaxAllowed) +} + +func (_AutomationRegistrar *AutomationRegistrarSession) SetTriggerConfig(triggerType uint8, autoApproveType uint8, autoApproveMaxAllowed uint32) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.SetTriggerConfig(&_AutomationRegistrar.TransactOpts, triggerType, autoApproveType, autoApproveMaxAllowed) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) SetTriggerConfig(triggerType uint8, autoApproveType uint8, autoApproveMaxAllowed uint32) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.SetTriggerConfig(&_AutomationRegistrar.TransactOpts, triggerType, autoApproveType, autoApproveMaxAllowed) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "transferOwnership", to) +} + +func (_AutomationRegistrar *AutomationRegistrarSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.TransferOwnership(&_AutomationRegistrar.TransactOpts, to) +} + +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.TransferOwnership(&_AutomationRegistrar.TransactOpts, to) +} + +type AutomationRegistrarAutoApproveAllowedSenderSetIterator struct { + Event *AutomationRegistrarAutoApproveAllowedSenderSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistrarAutoApproveAllowedSenderSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarAutoApproveAllowedSenderSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarAutoApproveAllowedSenderSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistrarAutoApproveAllowedSenderSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistrarAutoApproveAllowedSenderSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistrarAutoApproveAllowedSenderSet struct { + SenderAddress common.Address + Allowed bool + Raw types.Log +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) FilterAutoApproveAllowedSenderSet(opts *bind.FilterOpts, senderAddress []common.Address) (*AutomationRegistrarAutoApproveAllowedSenderSetIterator, error) { + + var senderAddressRule []interface{} + for _, senderAddressItem := range senderAddress { + senderAddressRule = append(senderAddressRule, senderAddressItem) + } + + logs, sub, err := _AutomationRegistrar.contract.FilterLogs(opts, "AutoApproveAllowedSenderSet", senderAddressRule) + if err != nil { + return nil, err + } + return &AutomationRegistrarAutoApproveAllowedSenderSetIterator{contract: _AutomationRegistrar.contract, event: "AutoApproveAllowedSenderSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) WatchAutoApproveAllowedSenderSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarAutoApproveAllowedSenderSet, senderAddress []common.Address) (event.Subscription, error) { + + var senderAddressRule []interface{} + for _, senderAddressItem := range senderAddress { + senderAddressRule = append(senderAddressRule, senderAddressItem) + } + + logs, sub, err := _AutomationRegistrar.contract.WatchLogs(opts, "AutoApproveAllowedSenderSet", senderAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistrarAutoApproveAllowedSenderSet) + if err := _AutomationRegistrar.contract.UnpackLog(event, "AutoApproveAllowedSenderSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) ParseAutoApproveAllowedSenderSet(log types.Log) (*AutomationRegistrarAutoApproveAllowedSenderSet, error) { + event := new(AutomationRegistrarAutoApproveAllowedSenderSet) + if err := _AutomationRegistrar.contract.UnpackLog(event, "AutoApproveAllowedSenderSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistrarConfigChangedIterator struct { + Event *AutomationRegistrarConfigChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistrarConfigChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarConfigChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistrarConfigChangedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistrarConfigChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistrarConfigChanged struct { + AutomationRegistry common.Address + MinLINKJuels *big.Int + Raw types.Log +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) FilterConfigChanged(opts *bind.FilterOpts) (*AutomationRegistrarConfigChangedIterator, error) { + + logs, sub, err := _AutomationRegistrar.contract.FilterLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return &AutomationRegistrarConfigChangedIterator{contract: _AutomationRegistrar.contract, event: "ConfigChanged", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarConfigChanged) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistrar.contract.WatchLogs(opts, "ConfigChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistrarConfigChanged) + if err := _AutomationRegistrar.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) ParseConfigChanged(log types.Log) (*AutomationRegistrarConfigChanged, error) { + event := new(AutomationRegistrarConfigChanged) + if err := _AutomationRegistrar.contract.UnpackLog(event, "ConfigChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistrarOwnershipTransferRequestedIterator struct { + Event *AutomationRegistrarOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistrarOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistrarOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistrarOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistrarOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*AutomationRegistrarOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistrar.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistrarOwnershipTransferRequestedIterator{contract: _AutomationRegistrar.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistrar.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistrarOwnershipTransferRequested) + if err := _AutomationRegistrar.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) ParseOwnershipTransferRequested(log types.Log) (*AutomationRegistrarOwnershipTransferRequested, error) { + event := new(AutomationRegistrarOwnershipTransferRequested) + if err := _AutomationRegistrar.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistrarOwnershipTransferredIterator struct { + Event *AutomationRegistrarOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistrarOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistrarOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistrarOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistrarOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*AutomationRegistrarOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistrar.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistrarOwnershipTransferredIterator{contract: _AutomationRegistrar.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistrar.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistrarOwnershipTransferred) + if err := _AutomationRegistrar.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) ParseOwnershipTransferred(log types.Log) (*AutomationRegistrarOwnershipTransferred, error) { + event := new(AutomationRegistrarOwnershipTransferred) + if err := _AutomationRegistrar.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistrarRegistrationApprovedIterator struct { + Event *AutomationRegistrarRegistrationApproved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistrarRegistrationApprovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarRegistrationApproved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarRegistrationApproved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistrarRegistrationApprovedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistrarRegistrationApprovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistrarRegistrationApproved struct { + Hash [32]byte + DisplayName string + UpkeepId *big.Int + Raw types.Log +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) FilterRegistrationApproved(opts *bind.FilterOpts, hash [][32]byte, upkeepId []*big.Int) (*AutomationRegistrarRegistrationApprovedIterator, error) { + + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + + var upkeepIdRule []interface{} + for _, upkeepIdItem := range upkeepId { + upkeepIdRule = append(upkeepIdRule, upkeepIdItem) + } + + logs, sub, err := _AutomationRegistrar.contract.FilterLogs(opts, "RegistrationApproved", hashRule, upkeepIdRule) + if err != nil { + return nil, err + } + return &AutomationRegistrarRegistrationApprovedIterator{contract: _AutomationRegistrar.contract, event: "RegistrationApproved", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) WatchRegistrationApproved(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarRegistrationApproved, hash [][32]byte, upkeepId []*big.Int) (event.Subscription, error) { + + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + + var upkeepIdRule []interface{} + for _, upkeepIdItem := range upkeepId { + upkeepIdRule = append(upkeepIdRule, upkeepIdItem) + } + + logs, sub, err := _AutomationRegistrar.contract.WatchLogs(opts, "RegistrationApproved", hashRule, upkeepIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistrarRegistrationApproved) + if err := _AutomationRegistrar.contract.UnpackLog(event, "RegistrationApproved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) ParseRegistrationApproved(log types.Log) (*AutomationRegistrarRegistrationApproved, error) { + event := new(AutomationRegistrarRegistrationApproved) + if err := _AutomationRegistrar.contract.UnpackLog(event, "RegistrationApproved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistrarRegistrationRejectedIterator struct { + Event *AutomationRegistrarRegistrationRejected + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistrarRegistrationRejectedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarRegistrationRejected) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarRegistrationRejected) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistrarRegistrationRejectedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistrarRegistrationRejectedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistrarRegistrationRejected struct { + Hash [32]byte + Raw types.Log +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) FilterRegistrationRejected(opts *bind.FilterOpts, hash [][32]byte) (*AutomationRegistrarRegistrationRejectedIterator, error) { + + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + + logs, sub, err := _AutomationRegistrar.contract.FilterLogs(opts, "RegistrationRejected", hashRule) + if err != nil { + return nil, err + } + return &AutomationRegistrarRegistrationRejectedIterator{contract: _AutomationRegistrar.contract, event: "RegistrationRejected", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) WatchRegistrationRejected(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarRegistrationRejected, hash [][32]byte) (event.Subscription, error) { + + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + + logs, sub, err := _AutomationRegistrar.contract.WatchLogs(opts, "RegistrationRejected", hashRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistrarRegistrationRejected) + if err := _AutomationRegistrar.contract.UnpackLog(event, "RegistrationRejected", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) ParseRegistrationRejected(log types.Log) (*AutomationRegistrarRegistrationRejected, error) { + event := new(AutomationRegistrarRegistrationRejected) + if err := _AutomationRegistrar.contract.UnpackLog(event, "RegistrationRejected", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistrarRegistrationRequestedIterator struct { + Event *AutomationRegistrarRegistrationRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistrarRegistrationRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarRegistrationRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarRegistrationRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistrarRegistrationRequestedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistrarRegistrationRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistrarRegistrationRequested struct { + Hash [32]byte + Name string + EncryptedEmail []byte + UpkeepContract common.Address + GasLimit uint32 + AdminAddress common.Address + TriggerType uint8 + TriggerConfig []byte + OffchainConfig []byte + CheckData []byte + Amount *big.Int + Raw types.Log +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) FilterRegistrationRequested(opts *bind.FilterOpts, hash [][32]byte, upkeepContract []common.Address) (*AutomationRegistrarRegistrationRequestedIterator, error) { + + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + + var upkeepContractRule []interface{} + for _, upkeepContractItem := range upkeepContract { + upkeepContractRule = append(upkeepContractRule, upkeepContractItem) + } + + logs, sub, err := _AutomationRegistrar.contract.FilterLogs(opts, "RegistrationRequested", hashRule, upkeepContractRule) + if err != nil { + return nil, err + } + return &AutomationRegistrarRegistrationRequestedIterator{contract: _AutomationRegistrar.contract, event: "RegistrationRequested", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) WatchRegistrationRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarRegistrationRequested, hash [][32]byte, upkeepContract []common.Address) (event.Subscription, error) { + + var hashRule []interface{} + for _, hashItem := range hash { + hashRule = append(hashRule, hashItem) + } + + var upkeepContractRule []interface{} + for _, upkeepContractItem := range upkeepContract { + upkeepContractRule = append(upkeepContractRule, upkeepContractItem) + } + + logs, sub, err := _AutomationRegistrar.contract.WatchLogs(opts, "RegistrationRequested", hashRule, upkeepContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistrarRegistrationRequested) + if err := _AutomationRegistrar.contract.UnpackLog(event, "RegistrationRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) ParseRegistrationRequested(log types.Log) (*AutomationRegistrarRegistrationRequested, error) { + event := new(AutomationRegistrarRegistrationRequested) + if err := _AutomationRegistrar.contract.UnpackLog(event, "RegistrationRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistrarTriggerConfigSetIterator struct { + Event *AutomationRegistrarTriggerConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistrarTriggerConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarTriggerConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistrarTriggerConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistrarTriggerConfigSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistrarTriggerConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistrarTriggerConfigSet struct { + TriggerType uint8 + AutoApproveType uint8 + AutoApproveMaxAllowed uint32 + Raw types.Log +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) FilterTriggerConfigSet(opts *bind.FilterOpts) (*AutomationRegistrarTriggerConfigSetIterator, error) { + + logs, sub, err := _AutomationRegistrar.contract.FilterLogs(opts, "TriggerConfigSet") + if err != nil { + return nil, err + } + return &AutomationRegistrarTriggerConfigSetIterator{contract: _AutomationRegistrar.contract, event: "TriggerConfigSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) WatchTriggerConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarTriggerConfigSet) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistrar.contract.WatchLogs(opts, "TriggerConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistrarTriggerConfigSet) + if err := _AutomationRegistrar.contract.UnpackLog(event, "TriggerConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistrar *AutomationRegistrarFilterer) ParseTriggerConfigSet(log types.Log) (*AutomationRegistrarTriggerConfigSet, error) { + event := new(AutomationRegistrarTriggerConfigSet) + if err := _AutomationRegistrar.contract.UnpackLog(event, "TriggerConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetConfig struct { + AutomationRegistry common.Address + MinLINKJuels *big.Int +} + +func (_AutomationRegistrar *AutomationRegistrar) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _AutomationRegistrar.abi.Events["AutoApproveAllowedSenderSet"].ID: + return _AutomationRegistrar.ParseAutoApproveAllowedSenderSet(log) + case _AutomationRegistrar.abi.Events["ConfigChanged"].ID: + return _AutomationRegistrar.ParseConfigChanged(log) + case _AutomationRegistrar.abi.Events["OwnershipTransferRequested"].ID: + return _AutomationRegistrar.ParseOwnershipTransferRequested(log) + case _AutomationRegistrar.abi.Events["OwnershipTransferred"].ID: + return _AutomationRegistrar.ParseOwnershipTransferred(log) + case _AutomationRegistrar.abi.Events["RegistrationApproved"].ID: + return _AutomationRegistrar.ParseRegistrationApproved(log) + case _AutomationRegistrar.abi.Events["RegistrationRejected"].ID: + return _AutomationRegistrar.ParseRegistrationRejected(log) + case _AutomationRegistrar.abi.Events["RegistrationRequested"].ID: + return _AutomationRegistrar.ParseRegistrationRequested(log) + case _AutomationRegistrar.abi.Events["TriggerConfigSet"].ID: + return _AutomationRegistrar.ParseTriggerConfigSet(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (AutomationRegistrarAutoApproveAllowedSenderSet) Topic() common.Hash { + return common.HexToHash("0x20c6237dac83526a849285a9f79d08a483291bdd3a056a0ef9ae94ecee1ad356") +} + +func (AutomationRegistrarConfigChanged) Topic() common.Hash { + return common.HexToHash("0x39ce5d867555f0b0183e358fce5b158e7ca4fecd7c01cb7e0e19f1e23285838a") +} + +func (AutomationRegistrarOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (AutomationRegistrarOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (AutomationRegistrarRegistrationApproved) Topic() common.Hash { + return common.HexToHash("0xb9a292fb7e3edd920cd2d2829a3615a640c43fd7de0a0820aa0668feb4c37d4b") +} + +func (AutomationRegistrarRegistrationRejected) Topic() common.Hash { + return common.HexToHash("0x3663fb28ebc87645eb972c9dad8521bf665c623f287e79f1c56f1eb374b82a22") +} + +func (AutomationRegistrarRegistrationRequested) Topic() common.Hash { + return common.HexToHash("0x7684390ebb103102f7f48c71439c2408713f8d437782a6fab2756acc0e42c1b7") +} + +func (AutomationRegistrarTriggerConfigSet) Topic() common.Hash { + return common.HexToHash("0x830a6d06a4e2caac67eba04323de22bdb04f032dd8b3d6a0c52b503d9a7036a3") +} + +func (_AutomationRegistrar *AutomationRegistrar) Address() common.Address { + return _AutomationRegistrar.address +} + +type AutomationRegistrarInterface interface { + LINK(opts *bind.CallOpts) (common.Address, error) + + GetAutoApproveAllowedSender(opts *bind.CallOpts, senderAddress common.Address) (bool, error) + + GetConfig(opts *bind.CallOpts) (GetConfig, + + error) + + GetPendingRequest(opts *bind.CallOpts, hash [32]byte) (common.Address, *big.Int, error) + + GetTriggerRegistrationDetails(opts *bind.CallOpts, triggerType uint8) (AutomationRegistrar23TriggerRegistrationStorage, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + Approve(opts *bind.TransactOpts, name string, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte, hash [32]byte) (*types.Transaction, error) + + Cancel(opts *bind.TransactOpts, hash [32]byte) (*types.Transaction, error) + + OnTokenTransfer(opts *bind.TransactOpts, sender common.Address, amount *big.Int, data []byte) (*types.Transaction, error) + + Register(opts *bind.TransactOpts, name string, encryptedEmail []byte, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte, amount *big.Int, sender common.Address) (*types.Transaction, error) + + RegisterUpkeep(opts *bind.TransactOpts, requestParams AutomationRegistrar23RegistrationParams) (*types.Transaction, error) + + SetAutoApproveAllowedSender(opts *bind.TransactOpts, senderAddress common.Address, allowed bool) (*types.Transaction, error) + + SetConfig(opts *bind.TransactOpts, AutomationRegistry common.Address, minLINKJuels *big.Int) (*types.Transaction, error) + + SetTriggerConfig(opts *bind.TransactOpts, triggerType uint8, autoApproveType uint8, autoApproveMaxAllowed uint32) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterAutoApproveAllowedSenderSet(opts *bind.FilterOpts, senderAddress []common.Address) (*AutomationRegistrarAutoApproveAllowedSenderSetIterator, error) + + WatchAutoApproveAllowedSenderSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarAutoApproveAllowedSenderSet, senderAddress []common.Address) (event.Subscription, error) + + ParseAutoApproveAllowedSenderSet(log types.Log) (*AutomationRegistrarAutoApproveAllowedSenderSet, error) + + FilterConfigChanged(opts *bind.FilterOpts) (*AutomationRegistrarConfigChangedIterator, error) + + WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarConfigChanged) (event.Subscription, error) + + ParseConfigChanged(log types.Log) (*AutomationRegistrarConfigChanged, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*AutomationRegistrarOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*AutomationRegistrarOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*AutomationRegistrarOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*AutomationRegistrarOwnershipTransferred, error) + + FilterRegistrationApproved(opts *bind.FilterOpts, hash [][32]byte, upkeepId []*big.Int) (*AutomationRegistrarRegistrationApprovedIterator, error) + + WatchRegistrationApproved(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarRegistrationApproved, hash [][32]byte, upkeepId []*big.Int) (event.Subscription, error) + + ParseRegistrationApproved(log types.Log) (*AutomationRegistrarRegistrationApproved, error) + + FilterRegistrationRejected(opts *bind.FilterOpts, hash [][32]byte) (*AutomationRegistrarRegistrationRejectedIterator, error) + + WatchRegistrationRejected(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarRegistrationRejected, hash [][32]byte) (event.Subscription, error) + + ParseRegistrationRejected(log types.Log) (*AutomationRegistrarRegistrationRejected, error) + + FilterRegistrationRequested(opts *bind.FilterOpts, hash [][32]byte, upkeepContract []common.Address) (*AutomationRegistrarRegistrationRequestedIterator, error) + + WatchRegistrationRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarRegistrationRequested, hash [][32]byte, upkeepContract []common.Address) (event.Subscription, error) + + ParseRegistrationRequested(log types.Log) (*AutomationRegistrarRegistrationRequested, error) + + FilterTriggerConfigSet(opts *bind.FilterOpts) (*AutomationRegistrarTriggerConfigSetIterator, error) + + WatchTriggerConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistrarTriggerConfigSet) (event.Subscription, error) + + ParseTriggerConfigSet(log types.Log) (*AutomationRegistrarTriggerConfigSet, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_3/automation_registry_logic_a_wrapper_2_3.go b/core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_3/automation_registry_logic_a_wrapper_2_3.go new file mode 100644 index 00000000000..d80f65dc8d9 --- /dev/null +++ b/core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_3/automation_registry_logic_a_wrapper_2_3.go @@ -0,0 +1,4992 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package automation_registry_logic_a_wrapper_2_3 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var AutomationRegistryLogicAMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicB2_3\",\"name\":\"logicB\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_3.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_3.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_3.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"executeCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"enumAutomationRegistryBase2_3.UpkeepFailureReason\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"migrateUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedUpkeeps\",\"type\":\"bytes\"}],\"name\":\"receiveUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"enumAutomationRegistryBase2_3.Trigger\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101406040523480156200001257600080fd5b5060405162005f1538038062005f158339810160408190526200003591620003b1565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b9190620003b1565b826001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001009190620003b1565b836001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001659190620003b1565b846001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca9190620003b1565b856001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f9190620003b1565b3380600081620002865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620002b957620002b981620002ed565b5050506001600160a01b0394851660805292841660a05290831660c052821660e052811661010052166101205250620003d8565b336001600160a01b03821603620003475760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200027d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b0381168114620003ae57600080fd5b50565b600060208284031215620003c457600080fd5b8151620003d18162000398565b9392505050565b60805160a05160c05160e0516101005161012051615ad86200043d6000396000818161010e01526101a9015260006131540152600081816103e10152611ffe0152600061333d01526000613421015260008181611e40015261240c0152615ad86000f3fe60806040523480156200001157600080fd5b50600436106200010c5760003560e01c806385c1b0ba11620000a5578063c8048022116200006f578063c804802214620002b7578063ce7dc5b414620002ce578063f2fde38b14620002e5578063f7d334ba14620002fc576200010c565b806385c1b0ba14620002535780638da5cb5b146200026a5780638e86139b1462000289578063948108f714620002a0576200010c565b80634ee88d3511620000e75780634ee88d3514620001ef5780636ded9eae146200020657806371791aa0146200021d57806379ba50971462000249576200010c565b806328f32f38146200015457806329c5efad146200017e578063349e8cca14620001a7575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156200014d573d6000f35b3d6000fd5b005b6200016b6200016536600462004073565b62000313565b6040519081526020015b60405180910390f35b620001956200018f36600462004159565b6200068d565b60405162000175949392919062004281565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200162000175565b6200015262000200366004620042be565b62000931565b6200016b620002173660046200430e565b62000999565b620002346200022e36600462004159565b620009ff565b604051620001759796959493929190620043c1565b620001526200114d565b620001526200026436600462004413565b62001250565b60005473ffffffffffffffffffffffffffffffffffffffff16620001c9565b620001526200029a366004620044a0565b62001ec1565b62000152620002b136600462004503565b62002249565b62000152620002c836600462004532565b620024dc565b62000195620002df36600462004608565b62002955565b62000152620002f63660046200467f565b62002a1b565b620002346200030d36600462004532565b62002a33565b6000805473ffffffffffffffffffffffffffffffffffffffff1633148015906200034757506200034560093362002a71565b155b156200037f576040517fd48b678b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff89163b620003ce576040517f09ee12d500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b620003d98662002aa5565b9050600089307f00000000000000000000000000000000000000000000000000000000000000006040516200040e9062003dff565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f08015801562000458573d6000803e3d6000fd5b5090506200051f826040518060e001604052806000151581526020018c63ffffffff16815260200163ffffffff801681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff168152602001600063ffffffff168152508a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92508a915062002d519050565b6015805474010000000000000000000000000000000000000000900463ffffffff169060146200054f83620046ce565b91906101000a81548163ffffffff021916908363ffffffff16021790555050817fbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d0128a8a604051620005c892919063ffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a2817fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d8787604051620006049291906200473d565b60405180910390a2817f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d5664856040516200063e919062004753565b60405180910390a2817f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf48508460405162000678919062004753565b60405180910390a25098975050505050505050565b600060606000806200069e6200313c565b600086815260046020908152604091829020825160e081018452815460ff811615158252610100810463ffffffff90811694830194909452650100000000008104841694820194909452690100000000000000000090930473ffffffffffffffffffffffffffffffffffffffff166060840152600101546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a0840152780100000000000000000000000000000000000000000000000090041660c08201525a9150600080826060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620007b8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007de919062004775565b73ffffffffffffffffffffffffffffffffffffffff166014600101600c9054906101000a900463ffffffff1663ffffffff168960405162000820919062004795565b60006040518083038160008787f1925050503d806000811462000860576040519150601f19603f3d011682016040523d82523d6000602084013e62000865565b606091505b50915091505a620008779085620047b3565b935081620008a257600060405180602001604052806000815250600796509650965050505062000928565b80806020019051810190620008b8919062004824565b909750955086620008e657600060405180602001604052806000815250600496509650965050505062000928565b601654865164010000000090910463ffffffff1610156200092457600060405180602001604052806000815250600596509650965050505062000928565b5050505b92959194509250565b6200093c83620031ae565b6000838152601b602052604090206200095782848362004919565b50827f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d566483836040516200098c9291906200473d565b60405180910390a2505050565b6000620009f388888860008989604051806020016040528060008152508a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506200031392505050565b98975050505050505050565b60006060600080600080600062000a156200313c565b600062000a228a62003264565b905060006012604051806101600160405290816000820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160008201600c9054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160109054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160149054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160189054906101000a900462ffffff1662ffffff1662ffffff16815260200160008201601b9054906101000a900461ffff1661ffff1661ffff16815260200160008201601d9054906101000a900460ff1660ff1660ff16815260200160008201601e9054906101000a900460ff1615151515815260200160008201601f9054906101000a900460ff161515151581526020016001820160009054906101000a900460ff161515151581526020016001820160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505090506000600460008d81526020019081526020016000206040518060e00160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160059054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160099054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160018201600c9054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff1681526020016001820160189054906101000a900463ffffffff1663ffffffff1663ffffffff168152505090508160e001511562000db7576000604051806020016040528060008152506009600084602001516000808263ffffffff169250995099509950995099509950995050505062001141565b604081015163ffffffff9081161462000e08576000604051806020016040528060008152506001600084602001516000808263ffffffff169250995099509950995099509950995050505062001141565b80511562000e4e576000604051806020016040528060008152506002600084602001516000808263ffffffff169250995099509950995099509950995050505062001141565b62000e59826200331a565b8095508196505050600062000e768385846020015189896200350c565b9050806bffffffffffffffffffffffff168260a001516bffffffffffffffffffffffff16101562000ee0576000604051806020016040528060008152506006600085602001516000808263ffffffff1692509a509a509a509a509a509a509a505050505062001141565b600062000eef8e868f620037c1565b90505a9850600080846060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000f47573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f6d919062004775565b73ffffffffffffffffffffffffffffffffffffffff166014600101600c9054906101000a900463ffffffff1663ffffffff168460405162000faf919062004795565b60006040518083038160008787f1925050503d806000811462000fef576040519150601f19603f3d011682016040523d82523d6000602084013e62000ff4565b606091505b50915091505a62001006908c620047b3565b9a5081620010865760165481516801000000000000000090910463ffffffff1610156200106357505060408051602080820190925260008082529490910151939c509a50600899505063ffffffff90911695506200114192505050565b602090940151939b5060039a505063ffffffff9092169650620011419350505050565b808060200190518101906200109c919062004824565b909e509c508d620010dd57505060408051602080820190925260008082529490910151939c509a50600499505063ffffffff90911695506200114192505050565b6016548d5164010000000090910463ffffffff1610156200112e57505060408051602080820190925260008082529490910151939c509a50600599505063ffffffff90911695506200114192505050565b505050506020015163ffffffff16945050505b92959891949750929550565b60015473ffffffffffffffffffffffffffffffffffffffff163314620011d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600173ffffffffffffffffffffffffffffffffffffffff82166000908152601a602052604090205460ff1660038111156200128f576200128f62004216565b14158015620012db5750600373ffffffffffffffffffffffffffffffffffffffff82166000908152601a602052604090205460ff166003811115620012d857620012d862004216565b14155b1562001313576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6014546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1662001373576040517fd12d7d8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000829003620013af576040517f2c2fc94100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081018290526000808567ffffffffffffffff81111562001406576200140662003efa565b60405190808252806020026020018201604052801562001430578160200160208202803683370190505b50905060008667ffffffffffffffff81111562001451576200145162003efa565b604051908082528060200260200182016040528015620014d857816020015b6040805160e08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181620014705790505b50905060008767ffffffffffffffff811115620014f957620014f962003efa565b6040519080825280602002602001820160405280156200152e57816020015b6060815260200190600190039081620015185790505b50905060008867ffffffffffffffff8111156200154f576200154f62003efa565b6040519080825280602002602001820160405280156200158457816020015b60608152602001906001900390816200156e5790505b50905060008967ffffffffffffffff811115620015a557620015a562003efa565b604051908082528060200260200182016040528015620015da57816020015b6060815260200190600190039081620015c45790505b50905060005b8a81101562001bbe578b8b82818110620015fe57620015fe62004a41565b60209081029290920135600081815260048452604090819020815160e081018352815460ff811615158252610100810463ffffffff90811697830197909752650100000000008104871693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490931660c08401529a50909850620016dd905089620031ae565b60608801516040517f1a5da6c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c8116600483015290911690631a5da6c890602401600060405180830381600087803b1580156200174d57600080fd5b505af115801562001762573d6000803e3d6000fd5b50505050878582815181106200177c576200177c62004a41565b6020026020010181905250600560008a815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16868281518110620017d057620017d062004a41565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910182015260008a815260079091526040902080546200180f9062004871565b80601f01602080910402602001604051908101604052809291908181526020018280546200183d9062004871565b80156200188e5780601f1062001862576101008083540402835291602001916200188e565b820191906000526020600020905b8154815290600101906020018083116200187057829003601f168201915b5050505050848281518110620018a857620018a862004a41565b6020026020010181905250601b60008a81526020019081526020016000208054620018d39062004871565b80601f0160208091040260200160405190810160405280929190818152602001828054620019019062004871565b8015620019525780601f10620019265761010080835404028352916020019162001952565b820191906000526020600020905b8154815290600101906020018083116200193457829003601f168201915b50505050508382815181106200196c576200196c62004a41565b6020026020010181905250601c60008a81526020019081526020016000208054620019979062004871565b80601f0160208091040260200160405190810160405280929190818152602001828054620019c59062004871565b801562001a165780601f10620019ea5761010080835404028352916020019162001a16565b820191906000526020600020905b815481529060010190602001808311620019f857829003601f168201915b505050505082828151811062001a305762001a3062004a41565b60200260200101819052508760a001516bffffffffffffffffffffffff168762001a5b919062004a70565b60008a815260046020908152604080832080547fffffff000000000000000000000000000000000000000000000000000000000016815560010180547fffffffff000000000000000000000000000000000000000000000000000000001690556007909152812091985062001ad1919062003e0d565b6000898152601b6020526040812062001aea9162003e0d565b6000898152601c6020526040812062001b039162003e0d565b600089815260066020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905562001b4460028a620039b1565b5060a0880151604080516bffffffffffffffffffffffff909216825273ffffffffffffffffffffffffffffffffffffffff8c1660208301528a917fb38647142fbb1ea4c000fc4569b37a4e9a9f6313317b84ee3e5326c1a6cd06ff910160405180910390a28062001bb58162004a86565b915050620015e0565b508560195462001bcf9190620047b3565b60195560008b8b868167ffffffffffffffff81111562001bf35762001bf362003efa565b60405190808252806020026020018201604052801562001c1d578160200160208202803683370190505b508988888860405160200162001c3b98979695949392919062004c4d565b60405160208183030381529060405290508973ffffffffffffffffffffffffffffffffffffffff16638e86139b6014600001600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c71249ab60038e73ffffffffffffffffffffffffffffffffffffffff1663aab9edd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001cf7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001d1d919062004d2c565b866040518463ffffffff1660e01b815260040162001d3e9392919062004d51565b600060405180830381865afa15801562001d5c573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405262001da4919081019062004d78565b6040518263ffffffff1660e01b815260040162001dc2919062004753565b600060405180830381600087803b15801562001ddd57600080fd5b505af115801562001df2573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d81166004830152602482018b90527f000000000000000000000000000000000000000000000000000000000000000016925063a9059cbb91506044016020604051808303816000875af115801562001e8c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001eb2919062004db1565b50505050505050505050505050565b6002336000908152601a602052604090205460ff16600381111562001eea5762001eea62004216565b1415801562001f2057506003336000908152601a602052604090205460ff16600381111562001f1d5762001f1d62004216565b14155b1562001f58576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080808080808062001f6e888a018a62004f9c565b965096509650965096509650965060005b87518110156200223d57600073ffffffffffffffffffffffffffffffffffffffff1687828151811062001fb65762001fb662004a41565b60200260200101516060015173ffffffffffffffffffffffffffffffffffffffff1603620020ca5785818151811062001ff35762001ff362004a41565b6020026020010151307f00000000000000000000000000000000000000000000000000000000000000006040516200202b9062003dff565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f08015801562002075573d6000803e3d6000fd5b508782815181106200208b576200208b62004a41565b60200260200101516060019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b62002182888281518110620020e357620020e362004a41565b602002602001015188838151811062002100576200210062004a41565b60200260200101518784815181106200211d576200211d62004a41565b60200260200101518785815181106200213a576200213a62004a41565b602002602001015187868151811062002157576200215762004a41565b602002602001015187878151811062002174576200217462004a41565b602002602001015162002d51565b87818151811062002197576200219762004a41565b60200260200101517f74931a144e43a50694897f241d973aecb5024c0e910f9bb80a163ea3c1cf5a71888381518110620021d557620021d562004a41565b602002602001015160a0015133604051620022209291906bffffffffffffffffffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a280620022348162004a86565b91505062001f7f565b50505050505050505050565b600082815260046020908152604091829020825160e081018452815460ff81161515825263ffffffff6101008204811694830194909452650100000000008104841694820185905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a083015278010000000000000000000000000000000000000000000000009004821660c0820152911462002347576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818160a00151620023599190620050cd565b600084815260046020526040902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006bffffffffffffffffffffffff93841602179055601954620023c19184169062004a70565b6019556040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526bffffffffffffffffffffffff831660448201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906323b872dd906064016020604051808303816000875af11580156200246b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002491919062004db1565b506040516bffffffffffffffffffffffff83168152339084907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a3505050565b6000818152600460209081526040808320815160e081018352815460ff81161515825263ffffffff610100820481169583019590955265010000000000810485169382019390935273ffffffffffffffffffffffffffffffffffffffff6901000000000000000000909304929092166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c082015290620025c460005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161490506000601260010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa15801562002667573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200268d9190620050f5565b9050826040015163ffffffff16600003620026d4576040517ffbc0357800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604083015163ffffffff9081161462002719576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b811580156200274c575060008481526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b1562002784576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816200279a576200279760328262004a70565b90505b6000848152600460205260409020805463ffffffff80841665010000000000027fffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffff90921691909117909155620027f6906002908690620039b116565b5060145460808401516bffffffffffffffffffffffff91821691600091168211156200285f5760808501516200282d90836200510f565b90508460a001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff1611156200285f575060a08401515b808560a001516200287191906200510f565b600087815260046020526040902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006bffffffffffffffffffffffff93841602179055601554620028d991839116620050cd565b601580547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff9290921691909117905560405167ffffffffffffffff84169087907f91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f79118190600090a3505050505050565b600060606000806000634b56a42e60e01b8888886040516024016200297d9392919062005137565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152905062002a0889826200068d565b929c919b50995090975095505050505050565b62002a25620039bf565b62002a308162003a42565b50565b60006060600080600080600062002a5a8860405180602001604052806000815250620009ff565b959e949d50929b5090995097509550909350915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b90505b92915050565b6000806000601260010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff166385df51fd60018473ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa15801562002b3e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002b649190620050f5565b62002b709190620047b3565b6040518263ffffffff1660e01b815260040162002b8f91815260200190565b602060405180830381865afa15801562002bad573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002bd39190620050f5565b601554604080516020810193909352309083015274010000000000000000000000000000000000000000900463ffffffff166060820152608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083015201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060045b600f81101562002cdf578382828151811062002c9b5762002c9b62004a41565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508062002cd68162004a86565b91505062002c7b565b5084600181111562002cf55762002cf562004216565b60f81b81600f8151811062002d0e5762002d0e62004a41565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535062002d48816200516b565b95945050505050565b6012547e01000000000000000000000000000000000000000000000000000000000000900460ff161562002db1576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601654835163ffffffff909116101562002df7576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108fc856020015163ffffffff16108062002e355750601554602086015163ffffffff70010000000000000000000000000000000090920482169116115b1562002e6d576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152600460205260409020546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff161562002ed7576040517f6e3b930b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152600460209081526040808320885181548a8501518b85015160608d01517fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009093169315157fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff169390931761010063ffffffff92831602177fffffff000000000000000000000000000000000000000000000000ffffffffff1665010000000000938216939093027fffffff0000000000000000000000000000000000000000ffffffffffffffffff1692909217690100000000000000000073ffffffffffffffffffffffffffffffffffffffff9283160217835560808b01516001909301805460a08d015160c08e01516bffffffffffffffffffffffff9687167fffffffffffffffff000000000000000000000000000000000000000000000000909316929092176c010000000000000000000000009690911695909502949094177fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009490931693909302919091179091556005835281842080547fffffffffffffffffffffffff00000000000000000000000000000000000000001691891691909117905560079091529020620030ca8482620051ae565b508460a001516bffffffffffffffffffffffff16601954620030ed919062004a70565b6019556000868152601b602052604090206200310a8382620051ae565b506000868152601c60205260409020620031258282620051ae565b506200313360028762003b39565b50505050505050565b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614620031ac576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff1633146200320c576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090205465010000000000900463ffffffff9081161462002a30576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818160045b600f811015620032f9577fff000000000000000000000000000000000000000000000000000000000000008216838260208110620032ad57620032ad62004a41565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614620032e457506000949350505050565b80620032f08162004a86565b9150506200326b565b5081600f1a600181111562003312576200331262004216565b949350505050565b6000806000836080015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015620033a7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620033cd9190620052f0565b5094509092505050600081131580620033e557508142105b806200340a57508280156200340a5750620034018242620047b3565b8463ffffffff16105b156200341b5760175495506200341f565b8095505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156200348b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620034b19190620052f0565b5094509092505050600081131580620034c957508142105b80620034ee5750828015620034ee5750620034e58242620047b3565b8463ffffffff16105b15620034ff57601854945062003503565b8094505b50505050915091565b6000808086600181111562003525576200352562004216565b0362003535575061ea606200358f565b60018660018111156200354c576200354c62004216565b036200355d575062014c086200358f565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008760c001516001620035a4919062005345565b620035b49060ff16604062005361565b601654620035d4906103a490640100000000900463ffffffff1662004a70565b620035e0919062004a70565b601354604080517fde9ee35e00000000000000000000000000000000000000000000000000000000815281519394506000938493610100900473ffffffffffffffffffffffffffffffffffffffff169263de9ee35e92600480820193918290030181865afa15801562003657573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200367d91906200537b565b909250905081836200369183601862004a70565b6200369d919062005361565b60c08c0151620036af90600162005345565b620036c09060ff166115e062005361565b620036cc919062004a70565b620036d8919062004a70565b620036e4908562004a70565b935060008a610140015173ffffffffffffffffffffffffffffffffffffffff166312544140856040518263ffffffff1660e01b81526004016200372991815260200190565b602060405180830381865afa15801562003747573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200376d9190620050f5565b8b60a0015161ffff1662003782919062005361565b90506000806200379f8d8c63ffffffff1689868e8e600062003b47565b9092509050620037b08183620050cd565b9d9c50505050505050505050505050565b60606000836001811115620037da57620037da62004216565b03620038a7576000848152600760205260409081902090517f6e04ff0d0000000000000000000000000000000000000000000000000000000091620038229160240162005443565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050620039aa565b6001836001811115620038be57620038be62004216565b036200355d57600082806020019051810190620038dc9190620054ba565b6000868152600760205260409081902090519192507f40691db4000000000000000000000000000000000000000000000000000000009162003923918491602401620055ce565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529150620039aa9050565b9392505050565b600062002a9c838362003ca2565b60005473ffffffffffffffffffffffffffffffffffffffff163314620031ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401620011cb565b3373ffffffffffffffffffffffffffffffffffffffff82160362003ac3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620011cb565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600062002a9c838362003dad565b60008060008960a0015161ffff168662003b62919062005361565b905083801562003b715750803a105b1562003b7a57503a5b6000858862003b8a8b8d62004a70565b62003b96908562005361565b62003ba2919062004a70565b62003bb690670de0b6b3a764000062005361565b62003bc2919062005696565b905060008b6040015163ffffffff1664e8d4a5100062003be3919062005361565b60208d0151889063ffffffff168b62003bfd8f8862005361565b62003c09919062004a70565b62003c1990633b9aca0062005361565b62003c25919062005361565b62003c31919062005696565b62003c3d919062004a70565b90506b033b2e3c9fd0803ce800000062003c58828462004a70565b111562003c91576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909b909a5098505050505050505050565b6000818152600183016020526040812054801562003d9b57600062003cc9600183620047b3565b855490915060009062003cdf90600190620047b3565b905081811462003d4b57600086600001828154811062003d035762003d0362004a41565b906000526020600020015490508087600001848154811062003d295762003d2962004a41565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062003d5f5762003d5f620056d2565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062002a9f565b600091505062002a9f565b5092915050565b600081815260018301602052604081205462003df65750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562002a9f565b50600062002a9f565b6103ca806200570283390190565b50805462003e1b9062004871565b6000825580601f1062003e2c575050565b601f01602090049060005260206000209081019062002a3091905b8082111562003e5d576000815560010162003e47565b5090565b73ffffffffffffffffffffffffffffffffffffffff8116811462002a3057600080fd5b803563ffffffff8116811462003e9957600080fd5b919050565b80356002811062003e9957600080fd5b60008083601f84011262003ec157600080fd5b50813567ffffffffffffffff81111562003eda57600080fd5b60208301915083602082850101111562003ef357600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160e0810167ffffffffffffffff8111828210171562003f4f5762003f4f62003efa565b60405290565b604051610100810167ffffffffffffffff8111828210171562003f4f5762003f4f62003efa565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171562003fc65762003fc662003efa565b604052919050565b600067ffffffffffffffff82111562003feb5762003feb62003efa565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126200402957600080fd5b8135620040406200403a8262003fce565b62003f7c565b8181528460208386010111156200405657600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060008060e0898b0312156200409057600080fd5b88356200409d8162003e61565b9750620040ad60208a0162003e84565b96506040890135620040bf8162003e61565b9550620040cf60608a0162003e9e565b9450608089013567ffffffffffffffff80821115620040ed57600080fd5b620040fb8c838d0162003eae565b909650945060a08b01359150808211156200411557600080fd5b620041238c838d0162004017565b935060c08b01359150808211156200413a57600080fd5b50620041498b828c0162004017565b9150509295985092959890939650565b600080604083850312156200416d57600080fd5b82359150602083013567ffffffffffffffff8111156200418c57600080fd5b6200419a8582860162004017565b9150509250929050565b60005b83811015620041c1578181015183820152602001620041a7565b50506000910152565b60008151808452620041e4816020860160208601620041a4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600a81106200427d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b84151581526080602082015260006200429e6080830186620041ca565b9050620042af604083018562004245565b82606083015295945050505050565b600080600060408486031215620042d457600080fd5b83359250602084013567ffffffffffffffff811115620042f357600080fd5b620043018682870162003eae565b9497909650939450505050565b600080600080600080600060a0888a0312156200432a57600080fd5b8735620043378162003e61565b9650620043476020890162003e84565b95506040880135620043598162003e61565b9450606088013567ffffffffffffffff808211156200437757600080fd5b620043858b838c0162003eae565b909650945060808a01359150808211156200439f57600080fd5b50620043ae8a828b0162003eae565b989b979a50959850939692959293505050565b871515815260e060208201526000620043de60e0830189620041ca565b9050620043ef604083018862004245565b8560608301528460808301528360a08301528260c083015298975050505050505050565b6000806000604084860312156200442957600080fd5b833567ffffffffffffffff808211156200444257600080fd5b818601915086601f8301126200445757600080fd5b8135818111156200446757600080fd5b8760208260051b85010111156200447d57600080fd5b60209283019550935050840135620044958162003e61565b809150509250925092565b60008060208385031215620044b457600080fd5b823567ffffffffffffffff811115620044cc57600080fd5b620044da8582860162003eae565b90969095509350505050565b80356bffffffffffffffffffffffff8116811462003e9957600080fd5b600080604083850312156200451757600080fd5b823591506200452960208401620044e6565b90509250929050565b6000602082840312156200454557600080fd5b5035919050565b600067ffffffffffffffff82111562004569576200456962003efa565b5060051b60200190565b600082601f8301126200458557600080fd5b81356020620045986200403a836200454c565b82815260059290921b84018101918181019086841115620045b857600080fd5b8286015b84811015620045fd57803567ffffffffffffffff811115620045de5760008081fd5b620045ee8986838b010162004017565b845250918301918301620045bc565b509695505050505050565b600080600080606085870312156200461f57600080fd5b84359350602085013567ffffffffffffffff808211156200463f57600080fd5b6200464d8883890162004573565b945060408701359150808211156200466457600080fd5b50620046738782880162003eae565b95989497509550505050565b6000602082840312156200469257600080fd5b8135620039aa8162003e61565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600063ffffffff808316818103620046ea57620046ea6200469f565b6001019392505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60208152600062003312602083018486620046f4565b60208152600062002a9c6020830184620041ca565b805162003e998162003e61565b6000602082840312156200478857600080fd5b8151620039aa8162003e61565b60008251620047a9818460208701620041a4565b9190910192915050565b8181038181111562002a9f5762002a9f6200469f565b801515811462002a3057600080fd5b600082601f830112620047ea57600080fd5b8151620047fb6200403a8262003fce565b8181528460208386010111156200481157600080fd5b62003312826020830160208701620041a4565b600080604083850312156200483857600080fd5b82516200484581620047c9565b602084015190925067ffffffffffffffff8111156200486357600080fd5b6200419a85828601620047d8565b600181811c908216806200488657607f821691505b602082108103620048c0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156200491457600081815260208120601f850160051c81016020861015620048ef5750805b601f850160051c820191505b818110156200491057828155600101620048fb565b5050505b505050565b67ffffffffffffffff83111562004934576200493462003efa565b6200494c8362004945835462004871565b83620048c6565b6000601f841160018114620049a157600085156200496a5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835562004a3a565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015620049f25786850135825560209485019460019092019101620049d0565b508682101562004a2e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8082018082111562002a9f5762002a9f6200469f565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362004aba5762004aba6200469f565b5060010190565b600081518084526020808501945080840160005b8381101562004b805781518051151588528381015163ffffffff908116858a01526040808301519091169089015260608082015173ffffffffffffffffffffffffffffffffffffffff16908901526080808201516bffffffffffffffffffffffff169089015260a08082015162004b5b828b01826bffffffffffffffffffffffff169052565b505060c09081015163ffffffff169088015260e0909601959082019060010162004ad5565b509495945050505050565b600081518084526020808501945080840160005b8381101562004b8057815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010162004b9f565b600082825180855260208086019550808260051b84010181860160005b8481101562004c40577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086840301895262004c2d838351620041ca565b9884019892509083019060010162004bf0565b5090979650505050505050565b60e081528760e082015260006101007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8a111562004c8a57600080fd5b8960051b808c8386013783018381038201602085015262004cae8282018b62004ac1565b915050828103604084015262004cc5818962004b8b565b9050828103606084015262004cdb818862004b8b565b9050828103608084015262004cf1818762004bd3565b905082810360a084015262004d07818662004bd3565b905082810360c084015262004d1d818562004bd3565b9b9a5050505050505050505050565b60006020828403121562004d3f57600080fd5b815160ff81168114620039aa57600080fd5b60ff8416815260ff8316602082015260606040820152600062002d486060830184620041ca565b60006020828403121562004d8b57600080fd5b815167ffffffffffffffff81111562004da357600080fd5b6200331284828501620047d8565b60006020828403121562004dc457600080fd5b8151620039aa81620047c9565b600082601f83011262004de357600080fd5b8135602062004df66200403a836200454c565b82815260059290921b8401810191818101908684111562004e1657600080fd5b8286015b84811015620045fd578035835291830191830162004e1a565b600082601f83011262004e4557600080fd5b8135602062004e586200403a836200454c565b82815260e0928302850182019282820191908785111562004e7857600080fd5b8387015b8581101562004c405781818a03121562004e965760008081fd5b62004ea062003f29565b813562004ead81620047c9565b815262004ebc82870162003e84565b86820152604062004ecf81840162003e84565b9082015260608281013562004ee48162003e61565b90820152608062004ef7838201620044e6565b9082015260a062004f0a838201620044e6565b9082015260c062004f1d83820162003e84565b90820152845292840192810162004e7c565b600082601f83011262004f4157600080fd5b8135602062004f546200403a836200454c565b82815260059290921b8401810191818101908684111562004f7457600080fd5b8286015b84811015620045fd57803562004f8e8162003e61565b835291830191830162004f78565b600080600080600080600060e0888a03121562004fb857600080fd5b873567ffffffffffffffff8082111562004fd157600080fd5b62004fdf8b838c0162004dd1565b985060208a013591508082111562004ff657600080fd5b620050048b838c0162004e33565b975060408a01359150808211156200501b57600080fd5b620050298b838c0162004f2f565b965060608a01359150808211156200504057600080fd5b6200504e8b838c0162004f2f565b955060808a01359150808211156200506557600080fd5b620050738b838c0162004573565b945060a08a01359150808211156200508a57600080fd5b620050988b838c0162004573565b935060c08a0135915080821115620050af57600080fd5b50620050be8a828b0162004573565b91505092959891949750929550565b6bffffffffffffffffffffffff81811683821601908082111562003da65762003da66200469f565b6000602082840312156200510857600080fd5b5051919050565b6bffffffffffffffffffffffff82811682821603908082111562003da65762003da66200469f565b6040815260006200514c604083018662004bd3565b828103602084015262005161818587620046f4565b9695505050505050565b80516020808301519190811015620048c0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b815167ffffffffffffffff811115620051cb57620051cb62003efa565b620051e381620051dc845462004871565b84620048c6565b602080601f831160018114620052395760008415620052025750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855562004910565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015620052885788860151825594840194600190910190840162005267565b5085821015620052c557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b805169ffffffffffffffffffff8116811462003e9957600080fd5b600080600080600060a086880312156200530957600080fd5b6200531486620052d5565b94506020860151935060408601519250606086015191506200533960808701620052d5565b90509295509295909350565b60ff818116838216019081111562002a9f5762002a9f6200469f565b808202811582820484141762002a9f5762002a9f6200469f565b600080604083850312156200538f57600080fd5b505080516020909101519092909150565b60008154620053af8162004871565b808552602060018381168015620053cf5760018114620054085762005438565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b890101955062005438565b866000528260002060005b85811015620054305781548a820186015290830190840162005413565b890184019650505b505050505092915050565b60208152600062002a9c6020830184620053a0565b600082601f8301126200546a57600080fd5b815160206200547d6200403a836200454c565b82815260059290921b840181019181810190868411156200549d57600080fd5b8286015b84811015620045fd5780518352918301918301620054a1565b600060208284031215620054cd57600080fd5b815167ffffffffffffffff80821115620054e657600080fd5b908301906101008286031215620054fc57600080fd5b6200550662003f55565b82518152602083015160208201526040830151604082015260608301516060820152608083015160808201526200554060a0840162004768565b60a082015260c0830151828111156200555857600080fd5b620055668782860162005458565b60c08301525060e0830151828111156200557f57600080fd5b6200558d87828601620047d8565b60e08301525095945050505050565b600081518084526020808501945080840160005b8381101562004b8057815187529582019590820190600101620055b0565b60408152825160408201526020830151606082015260408301516080820152606083015160a0820152608083015160c082015273ffffffffffffffffffffffffffffffffffffffff60a08401511660e0820152600060c0840151610100808185015250620056416101408401826200559c565b905060e08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0848303016101208501526200567f8282620041ca565b915050828103602084015262002d488185620053a0565b600082620056cd577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe60c060405234801561001057600080fd5b506040516103ca3803806103ca83398101604081905261002f91610076565b600080546001600160a01b0319166001600160a01b039384161790559181166080521660a0526100b9565b80516001600160a01b038116811461007157600080fd5b919050565b60008060006060848603121561008b57600080fd5b6100948461005a565b92506100a26020850161005a565b91506100b06040850161005a565b90509250925092565b60805160a0516102e76100e36000396000603801526000818160c4015261011701526102e76000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806379188d161461007b578063f00e6a2a146100aa575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610076573d6000f35b3d6000fd5b61008e6100893660046101c1565b6100ee565b6040805192151583526020830191909152015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526020016100a1565b60008054819073ffffffffffffffffffffffffffffffffffffffff16331461011557600080fd5b7f00000000000000000000000000000000000000000000000000000000000000005a91505a61138881101561014957600080fd5b61138881039050856040820482031161016157600080fd5b50803b61016d57600080fd5b6000808551602087016000858af192505a610188908361029a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080604083850312156101d457600080fd5b82359150602083013567ffffffffffffffff808211156101f357600080fd5b818501915085601f83011261020757600080fd5b81358181111561021957610219610192565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561025f5761025f610192565b8160405282815288602084870101111561027857600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b818103818111156102d4577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9291505056fea164736f6c6343000813000aa164736f6c6343000813000a", +} + +var AutomationRegistryLogicAABI = AutomationRegistryLogicAMetaData.ABI + +var AutomationRegistryLogicABin = AutomationRegistryLogicAMetaData.Bin + +func DeployAutomationRegistryLogicA(auth *bind.TransactOpts, backend bind.ContractBackend, logicB common.Address) (common.Address, *types.Transaction, *AutomationRegistryLogicA, error) { + parsed, err := AutomationRegistryLogicAMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(AutomationRegistryLogicABin), backend, logicB) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &AutomationRegistryLogicA{address: address, abi: *parsed, AutomationRegistryLogicACaller: AutomationRegistryLogicACaller{contract: contract}, AutomationRegistryLogicATransactor: AutomationRegistryLogicATransactor{contract: contract}, AutomationRegistryLogicAFilterer: AutomationRegistryLogicAFilterer{contract: contract}}, nil +} + +type AutomationRegistryLogicA struct { + address common.Address + abi abi.ABI + AutomationRegistryLogicACaller + AutomationRegistryLogicATransactor + AutomationRegistryLogicAFilterer +} + +type AutomationRegistryLogicACaller struct { + contract *bind.BoundContract +} + +type AutomationRegistryLogicATransactor struct { + contract *bind.BoundContract +} + +type AutomationRegistryLogicAFilterer struct { + contract *bind.BoundContract +} + +type AutomationRegistryLogicASession struct { + Contract *AutomationRegistryLogicA + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type AutomationRegistryLogicACallerSession struct { + Contract *AutomationRegistryLogicACaller + CallOpts bind.CallOpts +} + +type AutomationRegistryLogicATransactorSession struct { + Contract *AutomationRegistryLogicATransactor + TransactOpts bind.TransactOpts +} + +type AutomationRegistryLogicARaw struct { + Contract *AutomationRegistryLogicA +} + +type AutomationRegistryLogicACallerRaw struct { + Contract *AutomationRegistryLogicACaller +} + +type AutomationRegistryLogicATransactorRaw struct { + Contract *AutomationRegistryLogicATransactor +} + +func NewAutomationRegistryLogicA(address common.Address, backend bind.ContractBackend) (*AutomationRegistryLogicA, error) { + abi, err := abi.JSON(strings.NewReader(AutomationRegistryLogicAABI)) + if err != nil { + return nil, err + } + contract, err := bindAutomationRegistryLogicA(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicA{address: address, abi: abi, AutomationRegistryLogicACaller: AutomationRegistryLogicACaller{contract: contract}, AutomationRegistryLogicATransactor: AutomationRegistryLogicATransactor{contract: contract}, AutomationRegistryLogicAFilterer: AutomationRegistryLogicAFilterer{contract: contract}}, nil +} + +func NewAutomationRegistryLogicACaller(address common.Address, caller bind.ContractCaller) (*AutomationRegistryLogicACaller, error) { + contract, err := bindAutomationRegistryLogicA(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicACaller{contract: contract}, nil +} + +func NewAutomationRegistryLogicATransactor(address common.Address, transactor bind.ContractTransactor) (*AutomationRegistryLogicATransactor, error) { + contract, err := bindAutomationRegistryLogicA(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicATransactor{contract: contract}, nil +} + +func NewAutomationRegistryLogicAFilterer(address common.Address, filterer bind.ContractFilterer) (*AutomationRegistryLogicAFilterer, error) { + contract, err := bindAutomationRegistryLogicA(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAFilterer{contract: contract}, nil +} + +func bindAutomationRegistryLogicA(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := AutomationRegistryLogicAMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicARaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AutomationRegistryLogicA.Contract.AutomationRegistryLogicACaller.contract.Call(opts, result, method, params...) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicARaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.AutomationRegistryLogicATransactor.contract.Transfer(opts) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicARaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.AutomationRegistryLogicATransactor.contract.Transact(opts, method, params...) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicACallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AutomationRegistryLogicA.Contract.contract.Call(opts, result, method, params...) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.contract.Transfer(opts) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.contract.Transact(opts, method, params...) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicACaller) FallbackTo(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AutomationRegistryLogicA.contract.Call(opts, &out, "fallbackTo") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicASession) FallbackTo() (common.Address, error) { + return _AutomationRegistryLogicA.Contract.FallbackTo(&_AutomationRegistryLogicA.CallOpts) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicACallerSession) FallbackTo() (common.Address, error) { + return _AutomationRegistryLogicA.Contract.FallbackTo(&_AutomationRegistryLogicA.CallOpts) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicACaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AutomationRegistryLogicA.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicASession) Owner() (common.Address, error) { + return _AutomationRegistryLogicA.Contract.Owner(&_AutomationRegistryLogicA.CallOpts) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicACallerSession) Owner() (common.Address, error) { + return _AutomationRegistryLogicA.Contract.Owner(&_AutomationRegistryLogicA.CallOpts) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationRegistryLogicA.contract.Transact(opts, "acceptOwnership") +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicASession) AcceptOwnership() (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.AcceptOwnership(&_AutomationRegistryLogicA.TransactOpts) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.AcceptOwnership(&_AutomationRegistryLogicA.TransactOpts) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactor) AddFunds(opts *bind.TransactOpts, id *big.Int, amount *big.Int) (*types.Transaction, error) { + return _AutomationRegistryLogicA.contract.Transact(opts, "addFunds", id, amount) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicASession) AddFunds(id *big.Int, amount *big.Int) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.AddFunds(&_AutomationRegistryLogicA.TransactOpts, id, amount) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactorSession) AddFunds(id *big.Int, amount *big.Int) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.AddFunds(&_AutomationRegistryLogicA.TransactOpts, id, amount) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactor) CancelUpkeep(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) { + return _AutomationRegistryLogicA.contract.Transact(opts, "cancelUpkeep", id) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicASession) CancelUpkeep(id *big.Int) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.CancelUpkeep(&_AutomationRegistryLogicA.TransactOpts, id) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactorSession) CancelUpkeep(id *big.Int) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.CancelUpkeep(&_AutomationRegistryLogicA.TransactOpts, id) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactor) CheckCallback(opts *bind.TransactOpts, id *big.Int, values [][]byte, extraData []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.contract.Transact(opts, "checkCallback", id, values, extraData) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicASession) CheckCallback(id *big.Int, values [][]byte, extraData []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.CheckCallback(&_AutomationRegistryLogicA.TransactOpts, id, values, extraData) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactorSession) CheckCallback(id *big.Int, values [][]byte, extraData []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.CheckCallback(&_AutomationRegistryLogicA.TransactOpts, id, values, extraData) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactor) CheckUpkeep(opts *bind.TransactOpts, id *big.Int, triggerData []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.contract.Transact(opts, "checkUpkeep", id, triggerData) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicASession) CheckUpkeep(id *big.Int, triggerData []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.CheckUpkeep(&_AutomationRegistryLogicA.TransactOpts, id, triggerData) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactorSession) CheckUpkeep(id *big.Int, triggerData []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.CheckUpkeep(&_AutomationRegistryLogicA.TransactOpts, id, triggerData) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactor) CheckUpkeep0(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) { + return _AutomationRegistryLogicA.contract.Transact(opts, "checkUpkeep0", id) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicASession) CheckUpkeep0(id *big.Int) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.CheckUpkeep0(&_AutomationRegistryLogicA.TransactOpts, id) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactorSession) CheckUpkeep0(id *big.Int) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.CheckUpkeep0(&_AutomationRegistryLogicA.TransactOpts, id) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactor) ExecuteCallback(opts *bind.TransactOpts, id *big.Int, payload []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.contract.Transact(opts, "executeCallback", id, payload) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicASession) ExecuteCallback(id *big.Int, payload []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.ExecuteCallback(&_AutomationRegistryLogicA.TransactOpts, id, payload) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactorSession) ExecuteCallback(id *big.Int, payload []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.ExecuteCallback(&_AutomationRegistryLogicA.TransactOpts, id, payload) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactor) MigrateUpkeeps(opts *bind.TransactOpts, ids []*big.Int, destination common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicA.contract.Transact(opts, "migrateUpkeeps", ids, destination) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicASession) MigrateUpkeeps(ids []*big.Int, destination common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.MigrateUpkeeps(&_AutomationRegistryLogicA.TransactOpts, ids, destination) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactorSession) MigrateUpkeeps(ids []*big.Int, destination common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.MigrateUpkeeps(&_AutomationRegistryLogicA.TransactOpts, ids, destination) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactor) ReceiveUpkeeps(opts *bind.TransactOpts, encodedUpkeeps []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.contract.Transact(opts, "receiveUpkeeps", encodedUpkeeps) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicASession) ReceiveUpkeeps(encodedUpkeeps []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.ReceiveUpkeeps(&_AutomationRegistryLogicA.TransactOpts, encodedUpkeeps) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactorSession) ReceiveUpkeeps(encodedUpkeeps []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.ReceiveUpkeeps(&_AutomationRegistryLogicA.TransactOpts, encodedUpkeeps) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactor) RegisterUpkeep(opts *bind.TransactOpts, target common.Address, gasLimit uint32, admin common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.contract.Transact(opts, "registerUpkeep", target, gasLimit, admin, triggerType, checkData, triggerConfig, offchainConfig) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicASession) RegisterUpkeep(target common.Address, gasLimit uint32, admin common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.RegisterUpkeep(&_AutomationRegistryLogicA.TransactOpts, target, gasLimit, admin, triggerType, checkData, triggerConfig, offchainConfig) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactorSession) RegisterUpkeep(target common.Address, gasLimit uint32, admin common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.RegisterUpkeep(&_AutomationRegistryLogicA.TransactOpts, target, gasLimit, admin, triggerType, checkData, triggerConfig, offchainConfig) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactor) RegisterUpkeep0(opts *bind.TransactOpts, target common.Address, gasLimit uint32, admin common.Address, checkData []byte, offchainConfig []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.contract.Transact(opts, "registerUpkeep0", target, gasLimit, admin, checkData, offchainConfig) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicASession) RegisterUpkeep0(target common.Address, gasLimit uint32, admin common.Address, checkData []byte, offchainConfig []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.RegisterUpkeep0(&_AutomationRegistryLogicA.TransactOpts, target, gasLimit, admin, checkData, offchainConfig) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactorSession) RegisterUpkeep0(target common.Address, gasLimit uint32, admin common.Address, checkData []byte, offchainConfig []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.RegisterUpkeep0(&_AutomationRegistryLogicA.TransactOpts, target, gasLimit, admin, checkData, offchainConfig) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactor) SetUpkeepTriggerConfig(opts *bind.TransactOpts, id *big.Int, triggerConfig []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.contract.Transact(opts, "setUpkeepTriggerConfig", id, triggerConfig) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicASession) SetUpkeepTriggerConfig(id *big.Int, triggerConfig []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.SetUpkeepTriggerConfig(&_AutomationRegistryLogicA.TransactOpts, id, triggerConfig) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactorSession) SetUpkeepTriggerConfig(id *big.Int, triggerConfig []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.SetUpkeepTriggerConfig(&_AutomationRegistryLogicA.TransactOpts, id, triggerConfig) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicA.contract.Transact(opts, "transferOwnership", to) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicASession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.TransferOwnership(&_AutomationRegistryLogicA.TransactOpts, to) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.TransferOwnership(&_AutomationRegistryLogicA.TransactOpts, to) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.contract.RawTransact(opts, calldata) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicASession) Fallback(calldata []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.Fallback(&_AutomationRegistryLogicA.TransactOpts, calldata) +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicATransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicA.Contract.Fallback(&_AutomationRegistryLogicA.TransactOpts, calldata) +} + +type AutomationRegistryLogicAAdminPrivilegeConfigSetIterator struct { + Event *AutomationRegistryLogicAAdminPrivilegeConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAAdminPrivilegeConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAAdminPrivilegeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAAdminPrivilegeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAAdminPrivilegeConfigSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAAdminPrivilegeConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAAdminPrivilegeConfigSet struct { + Admin common.Address + PrivilegeConfig []byte + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterAdminPrivilegeConfigSet(opts *bind.FilterOpts, admin []common.Address) (*AutomationRegistryLogicAAdminPrivilegeConfigSetIterator, error) { + + var adminRule []interface{} + for _, adminItem := range admin { + adminRule = append(adminRule, adminItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "AdminPrivilegeConfigSet", adminRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAAdminPrivilegeConfigSetIterator{contract: _AutomationRegistryLogicA.contract, event: "AdminPrivilegeConfigSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchAdminPrivilegeConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAAdminPrivilegeConfigSet, admin []common.Address) (event.Subscription, error) { + + var adminRule []interface{} + for _, adminItem := range admin { + adminRule = append(adminRule, adminItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "AdminPrivilegeConfigSet", adminRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAAdminPrivilegeConfigSet) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "AdminPrivilegeConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseAdminPrivilegeConfigSet(log types.Log) (*AutomationRegistryLogicAAdminPrivilegeConfigSet, error) { + event := new(AutomationRegistryLogicAAdminPrivilegeConfigSet) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "AdminPrivilegeConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicACancelledUpkeepReportIterator struct { + Event *AutomationRegistryLogicACancelledUpkeepReport + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicACancelledUpkeepReportIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicACancelledUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicACancelledUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicACancelledUpkeepReportIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicACancelledUpkeepReportIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicACancelledUpkeepReport struct { + Id *big.Int + Trigger []byte + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterCancelledUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicACancelledUpkeepReportIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "CancelledUpkeepReport", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicACancelledUpkeepReportIterator{contract: _AutomationRegistryLogicA.contract, event: "CancelledUpkeepReport", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchCancelledUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicACancelledUpkeepReport, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "CancelledUpkeepReport", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicACancelledUpkeepReport) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "CancelledUpkeepReport", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseCancelledUpkeepReport(log types.Log) (*AutomationRegistryLogicACancelledUpkeepReport, error) { + event := new(AutomationRegistryLogicACancelledUpkeepReport) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "CancelledUpkeepReport", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAChainSpecificModuleUpdatedIterator struct { + Event *AutomationRegistryLogicAChainSpecificModuleUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAChainSpecificModuleUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAChainSpecificModuleUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAChainSpecificModuleUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAChainSpecificModuleUpdatedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAChainSpecificModuleUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAChainSpecificModuleUpdated struct { + NewModule common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterChainSpecificModuleUpdated(opts *bind.FilterOpts) (*AutomationRegistryLogicAChainSpecificModuleUpdatedIterator, error) { + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "ChainSpecificModuleUpdated") + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAChainSpecificModuleUpdatedIterator{contract: _AutomationRegistryLogicA.contract, event: "ChainSpecificModuleUpdated", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchChainSpecificModuleUpdated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAChainSpecificModuleUpdated) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "ChainSpecificModuleUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAChainSpecificModuleUpdated) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "ChainSpecificModuleUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseChainSpecificModuleUpdated(log types.Log) (*AutomationRegistryLogicAChainSpecificModuleUpdated, error) { + event := new(AutomationRegistryLogicAChainSpecificModuleUpdated) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "ChainSpecificModuleUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicADedupKeyAddedIterator struct { + Event *AutomationRegistryLogicADedupKeyAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicADedupKeyAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicADedupKeyAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicADedupKeyAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicADedupKeyAddedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicADedupKeyAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicADedupKeyAdded struct { + DedupKey [32]byte + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterDedupKeyAdded(opts *bind.FilterOpts, dedupKey [][32]byte) (*AutomationRegistryLogicADedupKeyAddedIterator, error) { + + var dedupKeyRule []interface{} + for _, dedupKeyItem := range dedupKey { + dedupKeyRule = append(dedupKeyRule, dedupKeyItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "DedupKeyAdded", dedupKeyRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicADedupKeyAddedIterator{contract: _AutomationRegistryLogicA.contract, event: "DedupKeyAdded", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchDedupKeyAdded(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicADedupKeyAdded, dedupKey [][32]byte) (event.Subscription, error) { + + var dedupKeyRule []interface{} + for _, dedupKeyItem := range dedupKey { + dedupKeyRule = append(dedupKeyRule, dedupKeyItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "DedupKeyAdded", dedupKeyRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicADedupKeyAdded) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "DedupKeyAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseDedupKeyAdded(log types.Log) (*AutomationRegistryLogicADedupKeyAdded, error) { + event := new(AutomationRegistryLogicADedupKeyAdded) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "DedupKeyAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAFundsAddedIterator struct { + Event *AutomationRegistryLogicAFundsAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAFundsAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAFundsAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAFundsAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAFundsAddedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAFundsAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAFundsAdded struct { + Id *big.Int + From common.Address + Amount *big.Int + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterFundsAdded(opts *bind.FilterOpts, id []*big.Int, from []common.Address) (*AutomationRegistryLogicAFundsAddedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "FundsAdded", idRule, fromRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAFundsAddedIterator{contract: _AutomationRegistryLogicA.contract, event: "FundsAdded", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchFundsAdded(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAFundsAdded, id []*big.Int, from []common.Address) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "FundsAdded", idRule, fromRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAFundsAdded) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "FundsAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseFundsAdded(log types.Log) (*AutomationRegistryLogicAFundsAdded, error) { + event := new(AutomationRegistryLogicAFundsAdded) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "FundsAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAFundsWithdrawnIterator struct { + Event *AutomationRegistryLogicAFundsWithdrawn + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAFundsWithdrawnIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAFundsWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAFundsWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAFundsWithdrawnIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAFundsWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAFundsWithdrawn struct { + Id *big.Int + Amount *big.Int + To common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterFundsWithdrawn(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAFundsWithdrawnIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "FundsWithdrawn", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAFundsWithdrawnIterator{contract: _AutomationRegistryLogicA.contract, event: "FundsWithdrawn", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchFundsWithdrawn(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAFundsWithdrawn, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "FundsWithdrawn", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAFundsWithdrawn) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "FundsWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseFundsWithdrawn(log types.Log) (*AutomationRegistryLogicAFundsWithdrawn, error) { + event := new(AutomationRegistryLogicAFundsWithdrawn) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "FundsWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAInsufficientFundsUpkeepReportIterator struct { + Event *AutomationRegistryLogicAInsufficientFundsUpkeepReport + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAInsufficientFundsUpkeepReportIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAInsufficientFundsUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAInsufficientFundsUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAInsufficientFundsUpkeepReportIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAInsufficientFundsUpkeepReportIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAInsufficientFundsUpkeepReport struct { + Id *big.Int + Trigger []byte + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterInsufficientFundsUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAInsufficientFundsUpkeepReportIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "InsufficientFundsUpkeepReport", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAInsufficientFundsUpkeepReportIterator{contract: _AutomationRegistryLogicA.contract, event: "InsufficientFundsUpkeepReport", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchInsufficientFundsUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAInsufficientFundsUpkeepReport, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "InsufficientFundsUpkeepReport", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAInsufficientFundsUpkeepReport) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "InsufficientFundsUpkeepReport", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseInsufficientFundsUpkeepReport(log types.Log) (*AutomationRegistryLogicAInsufficientFundsUpkeepReport, error) { + event := new(AutomationRegistryLogicAInsufficientFundsUpkeepReport) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "InsufficientFundsUpkeepReport", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAOwnerFundsWithdrawnIterator struct { + Event *AutomationRegistryLogicAOwnerFundsWithdrawn + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAOwnerFundsWithdrawnIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAOwnerFundsWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAOwnerFundsWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAOwnerFundsWithdrawnIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAOwnerFundsWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAOwnerFundsWithdrawn struct { + Amount *big.Int + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterOwnerFundsWithdrawn(opts *bind.FilterOpts) (*AutomationRegistryLogicAOwnerFundsWithdrawnIterator, error) { + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "OwnerFundsWithdrawn") + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAOwnerFundsWithdrawnIterator{contract: _AutomationRegistryLogicA.contract, event: "OwnerFundsWithdrawn", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchOwnerFundsWithdrawn(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAOwnerFundsWithdrawn) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "OwnerFundsWithdrawn") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAOwnerFundsWithdrawn) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "OwnerFundsWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseOwnerFundsWithdrawn(log types.Log) (*AutomationRegistryLogicAOwnerFundsWithdrawn, error) { + event := new(AutomationRegistryLogicAOwnerFundsWithdrawn) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "OwnerFundsWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAOwnershipTransferRequestedIterator struct { + Event *AutomationRegistryLogicAOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*AutomationRegistryLogicAOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAOwnershipTransferRequestedIterator{contract: _AutomationRegistryLogicA.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAOwnershipTransferRequested) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseOwnershipTransferRequested(log types.Log) (*AutomationRegistryLogicAOwnershipTransferRequested, error) { + event := new(AutomationRegistryLogicAOwnershipTransferRequested) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAOwnershipTransferredIterator struct { + Event *AutomationRegistryLogicAOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*AutomationRegistryLogicAOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAOwnershipTransferredIterator{contract: _AutomationRegistryLogicA.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAOwnershipTransferred) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseOwnershipTransferred(log types.Log) (*AutomationRegistryLogicAOwnershipTransferred, error) { + event := new(AutomationRegistryLogicAOwnershipTransferred) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAPausedIterator struct { + Event *AutomationRegistryLogicAPaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAPausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAPausedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAPaused struct { + Account common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterPaused(opts *bind.FilterOpts) (*AutomationRegistryLogicAPausedIterator, error) { + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAPausedIterator{contract: _AutomationRegistryLogicA.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAPaused) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "Paused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAPaused) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "Paused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParsePaused(log types.Log) (*AutomationRegistryLogicAPaused, error) { + event := new(AutomationRegistryLogicAPaused) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAPayeesUpdatedIterator struct { + Event *AutomationRegistryLogicAPayeesUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAPayeesUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAPayeesUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAPayeesUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAPayeesUpdatedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAPayeesUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAPayeesUpdated struct { + Transmitters []common.Address + Payees []common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterPayeesUpdated(opts *bind.FilterOpts) (*AutomationRegistryLogicAPayeesUpdatedIterator, error) { + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "PayeesUpdated") + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAPayeesUpdatedIterator{contract: _AutomationRegistryLogicA.contract, event: "PayeesUpdated", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchPayeesUpdated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAPayeesUpdated) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "PayeesUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAPayeesUpdated) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "PayeesUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParsePayeesUpdated(log types.Log) (*AutomationRegistryLogicAPayeesUpdated, error) { + event := new(AutomationRegistryLogicAPayeesUpdated) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "PayeesUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAPayeeshipTransferRequestedIterator struct { + Event *AutomationRegistryLogicAPayeeshipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAPayeeshipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAPayeeshipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAPayeeshipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAPayeeshipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAPayeeshipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAPayeeshipTransferRequested struct { + Transmitter common.Address + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterPayeeshipTransferRequested(opts *bind.FilterOpts, transmitter []common.Address, from []common.Address, to []common.Address) (*AutomationRegistryLogicAPayeeshipTransferRequestedIterator, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "PayeeshipTransferRequested", transmitterRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAPayeeshipTransferRequestedIterator{contract: _AutomationRegistryLogicA.contract, event: "PayeeshipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchPayeeshipTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAPayeeshipTransferRequested, transmitter []common.Address, from []common.Address, to []common.Address) (event.Subscription, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "PayeeshipTransferRequested", transmitterRule, fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAPayeeshipTransferRequested) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "PayeeshipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParsePayeeshipTransferRequested(log types.Log) (*AutomationRegistryLogicAPayeeshipTransferRequested, error) { + event := new(AutomationRegistryLogicAPayeeshipTransferRequested) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "PayeeshipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAPayeeshipTransferredIterator struct { + Event *AutomationRegistryLogicAPayeeshipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAPayeeshipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAPayeeshipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAPayeeshipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAPayeeshipTransferredIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAPayeeshipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAPayeeshipTransferred struct { + Transmitter common.Address + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterPayeeshipTransferred(opts *bind.FilterOpts, transmitter []common.Address, from []common.Address, to []common.Address) (*AutomationRegistryLogicAPayeeshipTransferredIterator, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "PayeeshipTransferred", transmitterRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAPayeeshipTransferredIterator{contract: _AutomationRegistryLogicA.contract, event: "PayeeshipTransferred", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchPayeeshipTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAPayeeshipTransferred, transmitter []common.Address, from []common.Address, to []common.Address) (event.Subscription, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "PayeeshipTransferred", transmitterRule, fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAPayeeshipTransferred) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "PayeeshipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParsePayeeshipTransferred(log types.Log) (*AutomationRegistryLogicAPayeeshipTransferred, error) { + event := new(AutomationRegistryLogicAPayeeshipTransferred) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "PayeeshipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAPaymentWithdrawnIterator struct { + Event *AutomationRegistryLogicAPaymentWithdrawn + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAPaymentWithdrawnIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAPaymentWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAPaymentWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAPaymentWithdrawnIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAPaymentWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAPaymentWithdrawn struct { + Transmitter common.Address + Amount *big.Int + To common.Address + Payee common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterPaymentWithdrawn(opts *bind.FilterOpts, transmitter []common.Address, amount []*big.Int, to []common.Address) (*AutomationRegistryLogicAPaymentWithdrawnIterator, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "PaymentWithdrawn", transmitterRule, amountRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAPaymentWithdrawnIterator{contract: _AutomationRegistryLogicA.contract, event: "PaymentWithdrawn", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchPaymentWithdrawn(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAPaymentWithdrawn, transmitter []common.Address, amount []*big.Int, to []common.Address) (event.Subscription, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "PaymentWithdrawn", transmitterRule, amountRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAPaymentWithdrawn) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "PaymentWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParsePaymentWithdrawn(log types.Log) (*AutomationRegistryLogicAPaymentWithdrawn, error) { + event := new(AutomationRegistryLogicAPaymentWithdrawn) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "PaymentWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAReorgedUpkeepReportIterator struct { + Event *AutomationRegistryLogicAReorgedUpkeepReport + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAReorgedUpkeepReportIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAReorgedUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAReorgedUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAReorgedUpkeepReportIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAReorgedUpkeepReportIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAReorgedUpkeepReport struct { + Id *big.Int + Trigger []byte + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterReorgedUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAReorgedUpkeepReportIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "ReorgedUpkeepReport", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAReorgedUpkeepReportIterator{contract: _AutomationRegistryLogicA.contract, event: "ReorgedUpkeepReport", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchReorgedUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAReorgedUpkeepReport, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "ReorgedUpkeepReport", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAReorgedUpkeepReport) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "ReorgedUpkeepReport", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseReorgedUpkeepReport(log types.Log) (*AutomationRegistryLogicAReorgedUpkeepReport, error) { + event := new(AutomationRegistryLogicAReorgedUpkeepReport) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "ReorgedUpkeepReport", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAStaleUpkeepReportIterator struct { + Event *AutomationRegistryLogicAStaleUpkeepReport + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAStaleUpkeepReportIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAStaleUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAStaleUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAStaleUpkeepReportIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAStaleUpkeepReportIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAStaleUpkeepReport struct { + Id *big.Int + Trigger []byte + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterStaleUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAStaleUpkeepReportIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "StaleUpkeepReport", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAStaleUpkeepReportIterator{contract: _AutomationRegistryLogicA.contract, event: "StaleUpkeepReport", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchStaleUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAStaleUpkeepReport, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "StaleUpkeepReport", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAStaleUpkeepReport) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "StaleUpkeepReport", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseStaleUpkeepReport(log types.Log) (*AutomationRegistryLogicAStaleUpkeepReport, error) { + event := new(AutomationRegistryLogicAStaleUpkeepReport) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "StaleUpkeepReport", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAUnpausedIterator struct { + Event *AutomationRegistryLogicAUnpaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAUnpausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAUnpausedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAUnpaused struct { + Account common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterUnpaused(opts *bind.FilterOpts) (*AutomationRegistryLogicAUnpausedIterator, error) { + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAUnpausedIterator{contract: _AutomationRegistryLogicA.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUnpaused) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAUnpaused) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "Unpaused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseUnpaused(log types.Log) (*AutomationRegistryLogicAUnpaused, error) { + event := new(AutomationRegistryLogicAUnpaused) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAUpkeepAdminTransferRequestedIterator struct { + Event *AutomationRegistryLogicAUpkeepAdminTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAUpkeepAdminTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepAdminTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepAdminTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAUpkeepAdminTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAUpkeepAdminTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAUpkeepAdminTransferRequested struct { + Id *big.Int + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterUpkeepAdminTransferRequested(opts *bind.FilterOpts, id []*big.Int, from []common.Address, to []common.Address) (*AutomationRegistryLogicAUpkeepAdminTransferRequestedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "UpkeepAdminTransferRequested", idRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAUpkeepAdminTransferRequestedIterator{contract: _AutomationRegistryLogicA.contract, event: "UpkeepAdminTransferRequested", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchUpkeepAdminTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepAdminTransferRequested, id []*big.Int, from []common.Address, to []common.Address) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "UpkeepAdminTransferRequested", idRule, fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAUpkeepAdminTransferRequested) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepAdminTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseUpkeepAdminTransferRequested(log types.Log) (*AutomationRegistryLogicAUpkeepAdminTransferRequested, error) { + event := new(AutomationRegistryLogicAUpkeepAdminTransferRequested) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepAdminTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAUpkeepAdminTransferredIterator struct { + Event *AutomationRegistryLogicAUpkeepAdminTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAUpkeepAdminTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepAdminTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepAdminTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAUpkeepAdminTransferredIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAUpkeepAdminTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAUpkeepAdminTransferred struct { + Id *big.Int + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterUpkeepAdminTransferred(opts *bind.FilterOpts, id []*big.Int, from []common.Address, to []common.Address) (*AutomationRegistryLogicAUpkeepAdminTransferredIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "UpkeepAdminTransferred", idRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAUpkeepAdminTransferredIterator{contract: _AutomationRegistryLogicA.contract, event: "UpkeepAdminTransferred", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchUpkeepAdminTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepAdminTransferred, id []*big.Int, from []common.Address, to []common.Address) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "UpkeepAdminTransferred", idRule, fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAUpkeepAdminTransferred) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepAdminTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseUpkeepAdminTransferred(log types.Log) (*AutomationRegistryLogicAUpkeepAdminTransferred, error) { + event := new(AutomationRegistryLogicAUpkeepAdminTransferred) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepAdminTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAUpkeepCanceledIterator struct { + Event *AutomationRegistryLogicAUpkeepCanceled + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAUpkeepCanceledIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepCanceled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepCanceled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAUpkeepCanceledIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAUpkeepCanceledIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAUpkeepCanceled struct { + Id *big.Int + AtBlockHeight uint64 + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterUpkeepCanceled(opts *bind.FilterOpts, id []*big.Int, atBlockHeight []uint64) (*AutomationRegistryLogicAUpkeepCanceledIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var atBlockHeightRule []interface{} + for _, atBlockHeightItem := range atBlockHeight { + atBlockHeightRule = append(atBlockHeightRule, atBlockHeightItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "UpkeepCanceled", idRule, atBlockHeightRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAUpkeepCanceledIterator{contract: _AutomationRegistryLogicA.contract, event: "UpkeepCanceled", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchUpkeepCanceled(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepCanceled, id []*big.Int, atBlockHeight []uint64) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var atBlockHeightRule []interface{} + for _, atBlockHeightItem := range atBlockHeight { + atBlockHeightRule = append(atBlockHeightRule, atBlockHeightItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "UpkeepCanceled", idRule, atBlockHeightRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAUpkeepCanceled) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepCanceled", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseUpkeepCanceled(log types.Log) (*AutomationRegistryLogicAUpkeepCanceled, error) { + event := new(AutomationRegistryLogicAUpkeepCanceled) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepCanceled", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAUpkeepCheckDataSetIterator struct { + Event *AutomationRegistryLogicAUpkeepCheckDataSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAUpkeepCheckDataSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepCheckDataSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepCheckDataSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAUpkeepCheckDataSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAUpkeepCheckDataSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAUpkeepCheckDataSet struct { + Id *big.Int + NewCheckData []byte + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterUpkeepCheckDataSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAUpkeepCheckDataSetIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "UpkeepCheckDataSet", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAUpkeepCheckDataSetIterator{contract: _AutomationRegistryLogicA.contract, event: "UpkeepCheckDataSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchUpkeepCheckDataSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepCheckDataSet, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "UpkeepCheckDataSet", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAUpkeepCheckDataSet) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepCheckDataSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseUpkeepCheckDataSet(log types.Log) (*AutomationRegistryLogicAUpkeepCheckDataSet, error) { + event := new(AutomationRegistryLogicAUpkeepCheckDataSet) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepCheckDataSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAUpkeepGasLimitSetIterator struct { + Event *AutomationRegistryLogicAUpkeepGasLimitSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAUpkeepGasLimitSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepGasLimitSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepGasLimitSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAUpkeepGasLimitSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAUpkeepGasLimitSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAUpkeepGasLimitSet struct { + Id *big.Int + GasLimit *big.Int + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterUpkeepGasLimitSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAUpkeepGasLimitSetIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "UpkeepGasLimitSet", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAUpkeepGasLimitSetIterator{contract: _AutomationRegistryLogicA.contract, event: "UpkeepGasLimitSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchUpkeepGasLimitSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepGasLimitSet, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "UpkeepGasLimitSet", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAUpkeepGasLimitSet) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepGasLimitSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseUpkeepGasLimitSet(log types.Log) (*AutomationRegistryLogicAUpkeepGasLimitSet, error) { + event := new(AutomationRegistryLogicAUpkeepGasLimitSet) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepGasLimitSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAUpkeepMigratedIterator struct { + Event *AutomationRegistryLogicAUpkeepMigrated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAUpkeepMigratedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepMigrated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepMigrated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAUpkeepMigratedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAUpkeepMigratedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAUpkeepMigrated struct { + Id *big.Int + RemainingBalance *big.Int + Destination common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterUpkeepMigrated(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAUpkeepMigratedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "UpkeepMigrated", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAUpkeepMigratedIterator{contract: _AutomationRegistryLogicA.contract, event: "UpkeepMigrated", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchUpkeepMigrated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepMigrated, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "UpkeepMigrated", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAUpkeepMigrated) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepMigrated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseUpkeepMigrated(log types.Log) (*AutomationRegistryLogicAUpkeepMigrated, error) { + event := new(AutomationRegistryLogicAUpkeepMigrated) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepMigrated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAUpkeepOffchainConfigSetIterator struct { + Event *AutomationRegistryLogicAUpkeepOffchainConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAUpkeepOffchainConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepOffchainConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepOffchainConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAUpkeepOffchainConfigSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAUpkeepOffchainConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAUpkeepOffchainConfigSet struct { + Id *big.Int + OffchainConfig []byte + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterUpkeepOffchainConfigSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAUpkeepOffchainConfigSetIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "UpkeepOffchainConfigSet", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAUpkeepOffchainConfigSetIterator{contract: _AutomationRegistryLogicA.contract, event: "UpkeepOffchainConfigSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchUpkeepOffchainConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepOffchainConfigSet, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "UpkeepOffchainConfigSet", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAUpkeepOffchainConfigSet) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepOffchainConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseUpkeepOffchainConfigSet(log types.Log) (*AutomationRegistryLogicAUpkeepOffchainConfigSet, error) { + event := new(AutomationRegistryLogicAUpkeepOffchainConfigSet) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepOffchainConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAUpkeepPausedIterator struct { + Event *AutomationRegistryLogicAUpkeepPaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAUpkeepPausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAUpkeepPausedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAUpkeepPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAUpkeepPaused struct { + Id *big.Int + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterUpkeepPaused(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAUpkeepPausedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "UpkeepPaused", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAUpkeepPausedIterator{contract: _AutomationRegistryLogicA.contract, event: "UpkeepPaused", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchUpkeepPaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepPaused, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "UpkeepPaused", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAUpkeepPaused) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepPaused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseUpkeepPaused(log types.Log) (*AutomationRegistryLogicAUpkeepPaused, error) { + event := new(AutomationRegistryLogicAUpkeepPaused) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepPaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAUpkeepPerformedIterator struct { + Event *AutomationRegistryLogicAUpkeepPerformed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAUpkeepPerformedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepPerformed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepPerformed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAUpkeepPerformedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAUpkeepPerformedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAUpkeepPerformed struct { + Id *big.Int + Success bool + TotalPayment *big.Int + GasUsed *big.Int + GasOverhead *big.Int + Trigger []byte + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterUpkeepPerformed(opts *bind.FilterOpts, id []*big.Int, success []bool) (*AutomationRegistryLogicAUpkeepPerformedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var successRule []interface{} + for _, successItem := range success { + successRule = append(successRule, successItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "UpkeepPerformed", idRule, successRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAUpkeepPerformedIterator{contract: _AutomationRegistryLogicA.contract, event: "UpkeepPerformed", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchUpkeepPerformed(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepPerformed, id []*big.Int, success []bool) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var successRule []interface{} + for _, successItem := range success { + successRule = append(successRule, successItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "UpkeepPerformed", idRule, successRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAUpkeepPerformed) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepPerformed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseUpkeepPerformed(log types.Log) (*AutomationRegistryLogicAUpkeepPerformed, error) { + event := new(AutomationRegistryLogicAUpkeepPerformed) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepPerformed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAUpkeepPrivilegeConfigSetIterator struct { + Event *AutomationRegistryLogicAUpkeepPrivilegeConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAUpkeepPrivilegeConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepPrivilegeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepPrivilegeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAUpkeepPrivilegeConfigSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAUpkeepPrivilegeConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAUpkeepPrivilegeConfigSet struct { + Id *big.Int + PrivilegeConfig []byte + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterUpkeepPrivilegeConfigSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAUpkeepPrivilegeConfigSetIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "UpkeepPrivilegeConfigSet", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAUpkeepPrivilegeConfigSetIterator{contract: _AutomationRegistryLogicA.contract, event: "UpkeepPrivilegeConfigSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchUpkeepPrivilegeConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepPrivilegeConfigSet, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "UpkeepPrivilegeConfigSet", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAUpkeepPrivilegeConfigSet) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepPrivilegeConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseUpkeepPrivilegeConfigSet(log types.Log) (*AutomationRegistryLogicAUpkeepPrivilegeConfigSet, error) { + event := new(AutomationRegistryLogicAUpkeepPrivilegeConfigSet) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepPrivilegeConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAUpkeepReceivedIterator struct { + Event *AutomationRegistryLogicAUpkeepReceived + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAUpkeepReceivedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAUpkeepReceivedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAUpkeepReceivedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAUpkeepReceived struct { + Id *big.Int + StartingBalance *big.Int + ImportedFrom common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterUpkeepReceived(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAUpkeepReceivedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "UpkeepReceived", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAUpkeepReceivedIterator{contract: _AutomationRegistryLogicA.contract, event: "UpkeepReceived", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchUpkeepReceived(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepReceived, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "UpkeepReceived", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAUpkeepReceived) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepReceived", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseUpkeepReceived(log types.Log) (*AutomationRegistryLogicAUpkeepReceived, error) { + event := new(AutomationRegistryLogicAUpkeepReceived) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepReceived", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAUpkeepRegisteredIterator struct { + Event *AutomationRegistryLogicAUpkeepRegistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAUpkeepRegisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAUpkeepRegisteredIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAUpkeepRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAUpkeepRegistered struct { + Id *big.Int + PerformGas uint32 + Admin common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterUpkeepRegistered(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAUpkeepRegisteredIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "UpkeepRegistered", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAUpkeepRegisteredIterator{contract: _AutomationRegistryLogicA.contract, event: "UpkeepRegistered", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchUpkeepRegistered(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepRegistered, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "UpkeepRegistered", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAUpkeepRegistered) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseUpkeepRegistered(log types.Log) (*AutomationRegistryLogicAUpkeepRegistered, error) { + event := new(AutomationRegistryLogicAUpkeepRegistered) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAUpkeepTriggerConfigSetIterator struct { + Event *AutomationRegistryLogicAUpkeepTriggerConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAUpkeepTriggerConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepTriggerConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepTriggerConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAUpkeepTriggerConfigSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAUpkeepTriggerConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAUpkeepTriggerConfigSet struct { + Id *big.Int + TriggerConfig []byte + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterUpkeepTriggerConfigSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAUpkeepTriggerConfigSetIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "UpkeepTriggerConfigSet", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAUpkeepTriggerConfigSetIterator{contract: _AutomationRegistryLogicA.contract, event: "UpkeepTriggerConfigSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchUpkeepTriggerConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepTriggerConfigSet, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "UpkeepTriggerConfigSet", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAUpkeepTriggerConfigSet) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepTriggerConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseUpkeepTriggerConfigSet(log types.Log) (*AutomationRegistryLogicAUpkeepTriggerConfigSet, error) { + event := new(AutomationRegistryLogicAUpkeepTriggerConfigSet) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepTriggerConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicAUpkeepUnpausedIterator struct { + Event *AutomationRegistryLogicAUpkeepUnpaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicAUpkeepUnpausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicAUpkeepUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicAUpkeepUnpausedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicAUpkeepUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicAUpkeepUnpaused struct { + Id *big.Int + Raw types.Log +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) FilterUpkeepUnpaused(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAUpkeepUnpausedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.FilterLogs(opts, "UpkeepUnpaused", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicAUpkeepUnpausedIterator{contract: _AutomationRegistryLogicA.contract, event: "UpkeepUnpaused", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) WatchUpkeepUnpaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepUnpaused, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicA.contract.WatchLogs(opts, "UpkeepUnpaused", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicAUpkeepUnpaused) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepUnpaused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicAFilterer) ParseUpkeepUnpaused(log types.Log) (*AutomationRegistryLogicAUpkeepUnpaused, error) { + event := new(AutomationRegistryLogicAUpkeepUnpaused) + if err := _AutomationRegistryLogicA.contract.UnpackLog(event, "UpkeepUnpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicA) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _AutomationRegistryLogicA.abi.Events["AdminPrivilegeConfigSet"].ID: + return _AutomationRegistryLogicA.ParseAdminPrivilegeConfigSet(log) + case _AutomationRegistryLogicA.abi.Events["CancelledUpkeepReport"].ID: + return _AutomationRegistryLogicA.ParseCancelledUpkeepReport(log) + case _AutomationRegistryLogicA.abi.Events["ChainSpecificModuleUpdated"].ID: + return _AutomationRegistryLogicA.ParseChainSpecificModuleUpdated(log) + case _AutomationRegistryLogicA.abi.Events["DedupKeyAdded"].ID: + return _AutomationRegistryLogicA.ParseDedupKeyAdded(log) + case _AutomationRegistryLogicA.abi.Events["FundsAdded"].ID: + return _AutomationRegistryLogicA.ParseFundsAdded(log) + case _AutomationRegistryLogicA.abi.Events["FundsWithdrawn"].ID: + return _AutomationRegistryLogicA.ParseFundsWithdrawn(log) + case _AutomationRegistryLogicA.abi.Events["InsufficientFundsUpkeepReport"].ID: + return _AutomationRegistryLogicA.ParseInsufficientFundsUpkeepReport(log) + case _AutomationRegistryLogicA.abi.Events["OwnerFundsWithdrawn"].ID: + return _AutomationRegistryLogicA.ParseOwnerFundsWithdrawn(log) + case _AutomationRegistryLogicA.abi.Events["OwnershipTransferRequested"].ID: + return _AutomationRegistryLogicA.ParseOwnershipTransferRequested(log) + case _AutomationRegistryLogicA.abi.Events["OwnershipTransferred"].ID: + return _AutomationRegistryLogicA.ParseOwnershipTransferred(log) + case _AutomationRegistryLogicA.abi.Events["Paused"].ID: + return _AutomationRegistryLogicA.ParsePaused(log) + case _AutomationRegistryLogicA.abi.Events["PayeesUpdated"].ID: + return _AutomationRegistryLogicA.ParsePayeesUpdated(log) + case _AutomationRegistryLogicA.abi.Events["PayeeshipTransferRequested"].ID: + return _AutomationRegistryLogicA.ParsePayeeshipTransferRequested(log) + case _AutomationRegistryLogicA.abi.Events["PayeeshipTransferred"].ID: + return _AutomationRegistryLogicA.ParsePayeeshipTransferred(log) + case _AutomationRegistryLogicA.abi.Events["PaymentWithdrawn"].ID: + return _AutomationRegistryLogicA.ParsePaymentWithdrawn(log) + case _AutomationRegistryLogicA.abi.Events["ReorgedUpkeepReport"].ID: + return _AutomationRegistryLogicA.ParseReorgedUpkeepReport(log) + case _AutomationRegistryLogicA.abi.Events["StaleUpkeepReport"].ID: + return _AutomationRegistryLogicA.ParseStaleUpkeepReport(log) + case _AutomationRegistryLogicA.abi.Events["Unpaused"].ID: + return _AutomationRegistryLogicA.ParseUnpaused(log) + case _AutomationRegistryLogicA.abi.Events["UpkeepAdminTransferRequested"].ID: + return _AutomationRegistryLogicA.ParseUpkeepAdminTransferRequested(log) + case _AutomationRegistryLogicA.abi.Events["UpkeepAdminTransferred"].ID: + return _AutomationRegistryLogicA.ParseUpkeepAdminTransferred(log) + case _AutomationRegistryLogicA.abi.Events["UpkeepCanceled"].ID: + return _AutomationRegistryLogicA.ParseUpkeepCanceled(log) + case _AutomationRegistryLogicA.abi.Events["UpkeepCheckDataSet"].ID: + return _AutomationRegistryLogicA.ParseUpkeepCheckDataSet(log) + case _AutomationRegistryLogicA.abi.Events["UpkeepGasLimitSet"].ID: + return _AutomationRegistryLogicA.ParseUpkeepGasLimitSet(log) + case _AutomationRegistryLogicA.abi.Events["UpkeepMigrated"].ID: + return _AutomationRegistryLogicA.ParseUpkeepMigrated(log) + case _AutomationRegistryLogicA.abi.Events["UpkeepOffchainConfigSet"].ID: + return _AutomationRegistryLogicA.ParseUpkeepOffchainConfigSet(log) + case _AutomationRegistryLogicA.abi.Events["UpkeepPaused"].ID: + return _AutomationRegistryLogicA.ParseUpkeepPaused(log) + case _AutomationRegistryLogicA.abi.Events["UpkeepPerformed"].ID: + return _AutomationRegistryLogicA.ParseUpkeepPerformed(log) + case _AutomationRegistryLogicA.abi.Events["UpkeepPrivilegeConfigSet"].ID: + return _AutomationRegistryLogicA.ParseUpkeepPrivilegeConfigSet(log) + case _AutomationRegistryLogicA.abi.Events["UpkeepReceived"].ID: + return _AutomationRegistryLogicA.ParseUpkeepReceived(log) + case _AutomationRegistryLogicA.abi.Events["UpkeepRegistered"].ID: + return _AutomationRegistryLogicA.ParseUpkeepRegistered(log) + case _AutomationRegistryLogicA.abi.Events["UpkeepTriggerConfigSet"].ID: + return _AutomationRegistryLogicA.ParseUpkeepTriggerConfigSet(log) + case _AutomationRegistryLogicA.abi.Events["UpkeepUnpaused"].ID: + return _AutomationRegistryLogicA.ParseUpkeepUnpaused(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (AutomationRegistryLogicAAdminPrivilegeConfigSet) Topic() common.Hash { + return common.HexToHash("0x7c44b4eb59ee7873514e7e43e7718c269d872965938b288aa143befca62f99d2") +} + +func (AutomationRegistryLogicACancelledUpkeepReport) Topic() common.Hash { + return common.HexToHash("0xc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636") +} + +func (AutomationRegistryLogicAChainSpecificModuleUpdated) Topic() common.Hash { + return common.HexToHash("0xdefc28b11a7980dbe0c49dbbd7055a1584bc8075097d1e8b3b57fb7283df2ad7") +} + +func (AutomationRegistryLogicADedupKeyAdded) Topic() common.Hash { + return common.HexToHash("0xa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f2") +} + +func (AutomationRegistryLogicAFundsAdded) Topic() common.Hash { + return common.HexToHash("0xafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa734891506203") +} + +func (AutomationRegistryLogicAFundsWithdrawn) Topic() common.Hash { + return common.HexToHash("0xf3b5906e5672f3e524854103bcafbbdba80dbdfeca2c35e116127b1060a68318") +} + +func (AutomationRegistryLogicAInsufficientFundsUpkeepReport) Topic() common.Hash { + return common.HexToHash("0x377c8b0c126ae5248d27aca1c76fac4608aff85673ee3caf09747e1044549e02") +} + +func (AutomationRegistryLogicAOwnerFundsWithdrawn) Topic() common.Hash { + return common.HexToHash("0x1d07d0b0be43d3e5fee41a80b579af370affee03fa595bf56d5d4c19328162f1") +} + +func (AutomationRegistryLogicAOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (AutomationRegistryLogicAOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (AutomationRegistryLogicAPaused) Topic() common.Hash { + return common.HexToHash("0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258") +} + +func (AutomationRegistryLogicAPayeesUpdated) Topic() common.Hash { + return common.HexToHash("0xa46de38886467c59be07a0675f14781206a5477d871628af46c2443822fcb725") +} + +func (AutomationRegistryLogicAPayeeshipTransferRequested) Topic() common.Hash { + return common.HexToHash("0x84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e38367") +} + +func (AutomationRegistryLogicAPayeeshipTransferred) Topic() common.Hash { + return common.HexToHash("0x78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b3") +} + +func (AutomationRegistryLogicAPaymentWithdrawn) Topic() common.Hash { + return common.HexToHash("0x9819093176a1851202c7bcfa46845809b4e47c261866550e94ed3775d2f40698") +} + +func (AutomationRegistryLogicAReorgedUpkeepReport) Topic() common.Hash { + return common.HexToHash("0x6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301") +} + +func (AutomationRegistryLogicAStaleUpkeepReport) Topic() common.Hash { + return common.HexToHash("0x405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8") +} + +func (AutomationRegistryLogicAUnpaused) Topic() common.Hash { + return common.HexToHash("0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa") +} + +func (AutomationRegistryLogicAUpkeepAdminTransferRequested) Topic() common.Hash { + return common.HexToHash("0xb1cbb2c4b8480034c27e06da5f096b8233a8fd4497028593a41ff6df79726b35") +} + +func (AutomationRegistryLogicAUpkeepAdminTransferred) Topic() common.Hash { + return common.HexToHash("0x5cff4db96bef051785e999f44bfcd21c18823e034fb92dd376e3db4ce0feeb2c") +} + +func (AutomationRegistryLogicAUpkeepCanceled) Topic() common.Hash { + return common.HexToHash("0x91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f791181") +} + +func (AutomationRegistryLogicAUpkeepCheckDataSet) Topic() common.Hash { + return common.HexToHash("0xcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d") +} + +func (AutomationRegistryLogicAUpkeepGasLimitSet) Topic() common.Hash { + return common.HexToHash("0xc24c07e655ce79fba8a589778987d3c015bc6af1632bb20cf9182e02a65d972c") +} + +func (AutomationRegistryLogicAUpkeepMigrated) Topic() common.Hash { + return common.HexToHash("0xb38647142fbb1ea4c000fc4569b37a4e9a9f6313317b84ee3e5326c1a6cd06ff") +} + +func (AutomationRegistryLogicAUpkeepOffchainConfigSet) Topic() common.Hash { + return common.HexToHash("0x3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf4850") +} + +func (AutomationRegistryLogicAUpkeepPaused) Topic() common.Hash { + return common.HexToHash("0x8ab10247ce168c27748e656ecf852b951fcaac790c18106b19aa0ae57a8b741f") +} + +func (AutomationRegistryLogicAUpkeepPerformed) Topic() common.Hash { + return common.HexToHash("0xad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b") +} + +func (AutomationRegistryLogicAUpkeepPrivilegeConfigSet) Topic() common.Hash { + return common.HexToHash("0x2fd8d70753a007014349d4591843cc031c2dd7a260d7dd82eca8253686ae7769") +} + +func (AutomationRegistryLogicAUpkeepReceived) Topic() common.Hash { + return common.HexToHash("0x74931a144e43a50694897f241d973aecb5024c0e910f9bb80a163ea3c1cf5a71") +} + +func (AutomationRegistryLogicAUpkeepRegistered) Topic() common.Hash { + return common.HexToHash("0xbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d012") +} + +func (AutomationRegistryLogicAUpkeepTriggerConfigSet) Topic() common.Hash { + return common.HexToHash("0x2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d5664") +} + +func (AutomationRegistryLogicAUpkeepUnpaused) Topic() common.Hash { + return common.HexToHash("0x7bada562044eb163f6b4003c4553e4e62825344c0418eea087bed5ee05a47456") +} + +func (_AutomationRegistryLogicA *AutomationRegistryLogicA) Address() common.Address { + return _AutomationRegistryLogicA.address +} + +type AutomationRegistryLogicAInterface interface { + FallbackTo(opts *bind.CallOpts) (common.Address, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + AddFunds(opts *bind.TransactOpts, id *big.Int, amount *big.Int) (*types.Transaction, error) + + CancelUpkeep(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) + + CheckCallback(opts *bind.TransactOpts, id *big.Int, values [][]byte, extraData []byte) (*types.Transaction, error) + + CheckUpkeep(opts *bind.TransactOpts, id *big.Int, triggerData []byte) (*types.Transaction, error) + + CheckUpkeep0(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) + + ExecuteCallback(opts *bind.TransactOpts, id *big.Int, payload []byte) (*types.Transaction, error) + + MigrateUpkeeps(opts *bind.TransactOpts, ids []*big.Int, destination common.Address) (*types.Transaction, error) + + ReceiveUpkeeps(opts *bind.TransactOpts, encodedUpkeeps []byte) (*types.Transaction, error) + + RegisterUpkeep(opts *bind.TransactOpts, target common.Address, gasLimit uint32, admin common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte) (*types.Transaction, error) + + RegisterUpkeep0(opts *bind.TransactOpts, target common.Address, gasLimit uint32, admin common.Address, checkData []byte, offchainConfig []byte) (*types.Transaction, error) + + SetUpkeepTriggerConfig(opts *bind.TransactOpts, id *big.Int, triggerConfig []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) + + FilterAdminPrivilegeConfigSet(opts *bind.FilterOpts, admin []common.Address) (*AutomationRegistryLogicAAdminPrivilegeConfigSetIterator, error) + + WatchAdminPrivilegeConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAAdminPrivilegeConfigSet, admin []common.Address) (event.Subscription, error) + + ParseAdminPrivilegeConfigSet(log types.Log) (*AutomationRegistryLogicAAdminPrivilegeConfigSet, error) + + FilterCancelledUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicACancelledUpkeepReportIterator, error) + + WatchCancelledUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicACancelledUpkeepReport, id []*big.Int) (event.Subscription, error) + + ParseCancelledUpkeepReport(log types.Log) (*AutomationRegistryLogicACancelledUpkeepReport, error) + + FilterChainSpecificModuleUpdated(opts *bind.FilterOpts) (*AutomationRegistryLogicAChainSpecificModuleUpdatedIterator, error) + + WatchChainSpecificModuleUpdated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAChainSpecificModuleUpdated) (event.Subscription, error) + + ParseChainSpecificModuleUpdated(log types.Log) (*AutomationRegistryLogicAChainSpecificModuleUpdated, error) + + FilterDedupKeyAdded(opts *bind.FilterOpts, dedupKey [][32]byte) (*AutomationRegistryLogicADedupKeyAddedIterator, error) + + WatchDedupKeyAdded(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicADedupKeyAdded, dedupKey [][32]byte) (event.Subscription, error) + + ParseDedupKeyAdded(log types.Log) (*AutomationRegistryLogicADedupKeyAdded, error) + + FilterFundsAdded(opts *bind.FilterOpts, id []*big.Int, from []common.Address) (*AutomationRegistryLogicAFundsAddedIterator, error) + + WatchFundsAdded(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAFundsAdded, id []*big.Int, from []common.Address) (event.Subscription, error) + + ParseFundsAdded(log types.Log) (*AutomationRegistryLogicAFundsAdded, error) + + FilterFundsWithdrawn(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAFundsWithdrawnIterator, error) + + WatchFundsWithdrawn(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAFundsWithdrawn, id []*big.Int) (event.Subscription, error) + + ParseFundsWithdrawn(log types.Log) (*AutomationRegistryLogicAFundsWithdrawn, error) + + FilterInsufficientFundsUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAInsufficientFundsUpkeepReportIterator, error) + + WatchInsufficientFundsUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAInsufficientFundsUpkeepReport, id []*big.Int) (event.Subscription, error) + + ParseInsufficientFundsUpkeepReport(log types.Log) (*AutomationRegistryLogicAInsufficientFundsUpkeepReport, error) + + FilterOwnerFundsWithdrawn(opts *bind.FilterOpts) (*AutomationRegistryLogicAOwnerFundsWithdrawnIterator, error) + + WatchOwnerFundsWithdrawn(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAOwnerFundsWithdrawn) (event.Subscription, error) + + ParseOwnerFundsWithdrawn(log types.Log) (*AutomationRegistryLogicAOwnerFundsWithdrawn, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*AutomationRegistryLogicAOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*AutomationRegistryLogicAOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*AutomationRegistryLogicAOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*AutomationRegistryLogicAOwnershipTransferred, error) + + FilterPaused(opts *bind.FilterOpts) (*AutomationRegistryLogicAPausedIterator, error) + + WatchPaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAPaused) (event.Subscription, error) + + ParsePaused(log types.Log) (*AutomationRegistryLogicAPaused, error) + + FilterPayeesUpdated(opts *bind.FilterOpts) (*AutomationRegistryLogicAPayeesUpdatedIterator, error) + + WatchPayeesUpdated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAPayeesUpdated) (event.Subscription, error) + + ParsePayeesUpdated(log types.Log) (*AutomationRegistryLogicAPayeesUpdated, error) + + FilterPayeeshipTransferRequested(opts *bind.FilterOpts, transmitter []common.Address, from []common.Address, to []common.Address) (*AutomationRegistryLogicAPayeeshipTransferRequestedIterator, error) + + WatchPayeeshipTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAPayeeshipTransferRequested, transmitter []common.Address, from []common.Address, to []common.Address) (event.Subscription, error) + + ParsePayeeshipTransferRequested(log types.Log) (*AutomationRegistryLogicAPayeeshipTransferRequested, error) + + FilterPayeeshipTransferred(opts *bind.FilterOpts, transmitter []common.Address, from []common.Address, to []common.Address) (*AutomationRegistryLogicAPayeeshipTransferredIterator, error) + + WatchPayeeshipTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAPayeeshipTransferred, transmitter []common.Address, from []common.Address, to []common.Address) (event.Subscription, error) + + ParsePayeeshipTransferred(log types.Log) (*AutomationRegistryLogicAPayeeshipTransferred, error) + + FilterPaymentWithdrawn(opts *bind.FilterOpts, transmitter []common.Address, amount []*big.Int, to []common.Address) (*AutomationRegistryLogicAPaymentWithdrawnIterator, error) + + WatchPaymentWithdrawn(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAPaymentWithdrawn, transmitter []common.Address, amount []*big.Int, to []common.Address) (event.Subscription, error) + + ParsePaymentWithdrawn(log types.Log) (*AutomationRegistryLogicAPaymentWithdrawn, error) + + FilterReorgedUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAReorgedUpkeepReportIterator, error) + + WatchReorgedUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAReorgedUpkeepReport, id []*big.Int) (event.Subscription, error) + + ParseReorgedUpkeepReport(log types.Log) (*AutomationRegistryLogicAReorgedUpkeepReport, error) + + FilterStaleUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAStaleUpkeepReportIterator, error) + + WatchStaleUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAStaleUpkeepReport, id []*big.Int) (event.Subscription, error) + + ParseStaleUpkeepReport(log types.Log) (*AutomationRegistryLogicAStaleUpkeepReport, error) + + FilterUnpaused(opts *bind.FilterOpts) (*AutomationRegistryLogicAUnpausedIterator, error) + + WatchUnpaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUnpaused) (event.Subscription, error) + + ParseUnpaused(log types.Log) (*AutomationRegistryLogicAUnpaused, error) + + FilterUpkeepAdminTransferRequested(opts *bind.FilterOpts, id []*big.Int, from []common.Address, to []common.Address) (*AutomationRegistryLogicAUpkeepAdminTransferRequestedIterator, error) + + WatchUpkeepAdminTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepAdminTransferRequested, id []*big.Int, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseUpkeepAdminTransferRequested(log types.Log) (*AutomationRegistryLogicAUpkeepAdminTransferRequested, error) + + FilterUpkeepAdminTransferred(opts *bind.FilterOpts, id []*big.Int, from []common.Address, to []common.Address) (*AutomationRegistryLogicAUpkeepAdminTransferredIterator, error) + + WatchUpkeepAdminTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepAdminTransferred, id []*big.Int, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseUpkeepAdminTransferred(log types.Log) (*AutomationRegistryLogicAUpkeepAdminTransferred, error) + + FilterUpkeepCanceled(opts *bind.FilterOpts, id []*big.Int, atBlockHeight []uint64) (*AutomationRegistryLogicAUpkeepCanceledIterator, error) + + WatchUpkeepCanceled(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepCanceled, id []*big.Int, atBlockHeight []uint64) (event.Subscription, error) + + ParseUpkeepCanceled(log types.Log) (*AutomationRegistryLogicAUpkeepCanceled, error) + + FilterUpkeepCheckDataSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAUpkeepCheckDataSetIterator, error) + + WatchUpkeepCheckDataSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepCheckDataSet, id []*big.Int) (event.Subscription, error) + + ParseUpkeepCheckDataSet(log types.Log) (*AutomationRegistryLogicAUpkeepCheckDataSet, error) + + FilterUpkeepGasLimitSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAUpkeepGasLimitSetIterator, error) + + WatchUpkeepGasLimitSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepGasLimitSet, id []*big.Int) (event.Subscription, error) + + ParseUpkeepGasLimitSet(log types.Log) (*AutomationRegistryLogicAUpkeepGasLimitSet, error) + + FilterUpkeepMigrated(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAUpkeepMigratedIterator, error) + + WatchUpkeepMigrated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepMigrated, id []*big.Int) (event.Subscription, error) + + ParseUpkeepMigrated(log types.Log) (*AutomationRegistryLogicAUpkeepMigrated, error) + + FilterUpkeepOffchainConfigSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAUpkeepOffchainConfigSetIterator, error) + + WatchUpkeepOffchainConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepOffchainConfigSet, id []*big.Int) (event.Subscription, error) + + ParseUpkeepOffchainConfigSet(log types.Log) (*AutomationRegistryLogicAUpkeepOffchainConfigSet, error) + + FilterUpkeepPaused(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAUpkeepPausedIterator, error) + + WatchUpkeepPaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepPaused, id []*big.Int) (event.Subscription, error) + + ParseUpkeepPaused(log types.Log) (*AutomationRegistryLogicAUpkeepPaused, error) + + FilterUpkeepPerformed(opts *bind.FilterOpts, id []*big.Int, success []bool) (*AutomationRegistryLogicAUpkeepPerformedIterator, error) + + WatchUpkeepPerformed(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepPerformed, id []*big.Int, success []bool) (event.Subscription, error) + + ParseUpkeepPerformed(log types.Log) (*AutomationRegistryLogicAUpkeepPerformed, error) + + FilterUpkeepPrivilegeConfigSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAUpkeepPrivilegeConfigSetIterator, error) + + WatchUpkeepPrivilegeConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepPrivilegeConfigSet, id []*big.Int) (event.Subscription, error) + + ParseUpkeepPrivilegeConfigSet(log types.Log) (*AutomationRegistryLogicAUpkeepPrivilegeConfigSet, error) + + FilterUpkeepReceived(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAUpkeepReceivedIterator, error) + + WatchUpkeepReceived(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepReceived, id []*big.Int) (event.Subscription, error) + + ParseUpkeepReceived(log types.Log) (*AutomationRegistryLogicAUpkeepReceived, error) + + FilterUpkeepRegistered(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAUpkeepRegisteredIterator, error) + + WatchUpkeepRegistered(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepRegistered, id []*big.Int) (event.Subscription, error) + + ParseUpkeepRegistered(log types.Log) (*AutomationRegistryLogicAUpkeepRegistered, error) + + FilterUpkeepTriggerConfigSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAUpkeepTriggerConfigSetIterator, error) + + WatchUpkeepTriggerConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepTriggerConfigSet, id []*big.Int) (event.Subscription, error) + + ParseUpkeepTriggerConfigSet(log types.Log) (*AutomationRegistryLogicAUpkeepTriggerConfigSet, error) + + FilterUpkeepUnpaused(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicAUpkeepUnpausedIterator, error) + + WatchUpkeepUnpaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicAUpkeepUnpaused, id []*big.Int) (event.Subscription, error) + + ParseUpkeepUnpaused(log types.Log) (*AutomationRegistryLogicAUpkeepUnpaused, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/automation_registry_logic_b_wrapper_2_3/automation_registry_logic_b_wrapper_2_3.go b/core/gethwrappers/generated/automation_registry_logic_b_wrapper_2_3/automation_registry_logic_b_wrapper_2_3.go new file mode 100644 index 00000000000..2ce7932cae2 --- /dev/null +++ b/core/gethwrappers/generated/automation_registry_logic_b_wrapper_2_3/automation_registry_logic_b_wrapper_2_3.go @@ -0,0 +1,5933 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package automation_registry_logic_b_wrapper_2_3 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type AutomationRegistryBase23OnchainConfigLegacy struct { + PaymentPremiumPPB uint32 + FlatFeeMicroLink uint32 + CheckGasLimit uint32 + StalenessSeconds *big.Int + GasCeilingMultiplier uint16 + MinUpkeepSpend *big.Int + MaxPerformGas uint32 + MaxCheckDataSize uint32 + MaxPerformDataSize uint32 + MaxRevertDataSize uint32 + FallbackGasPrice *big.Int + FallbackLinkPrice *big.Int + Transcoder common.Address + Registrars []common.Address + UpkeepPrivilegeManager common.Address +} + +type AutomationRegistryBase23State struct { + Nonce uint32 + OwnerLinkBalance *big.Int + ExpectedLinkBalance *big.Int + TotalPremium *big.Int + NumUpkeeps *big.Int + ConfigCount uint32 + LatestConfigBlockNumber uint32 + LatestConfigDigest [32]byte + LatestEpoch uint32 + Paused bool +} + +type AutomationRegistryBase23UpkeepInfo struct { + Target common.Address + PerformGas uint32 + CheckData []byte + Balance *big.Int + Admin common.Address + MaxValidBlocknumber uint64 + LastPerformedBlockNumber uint32 + AmountSpent *big.Int + Paused bool + OffchainConfig []byte +} + +var AutomationRegistryLogicBMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fastGasFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"automationForwarderLogic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"allowedReadOnlyAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"acceptPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"acceptUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"getAdminPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedReadOnlyAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAutomationForwarderLogic\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCancellationDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainModule\",\"outputs\":[{\"internalType\":\"contractIChainModule\",\"name\":\"chainModule\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConditionalGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFastGasFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getForwarder\",\"outputs\":[{\"internalType\":\"contractIAutomationForwarder\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkNativeFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLogGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enumAutomationRegistryBase2_3.Trigger\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"getMaxPaymentForGas\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"maxPayment\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"minBalance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"}],\"name\":\"getPeerRegistryMigrationPermission\",\"outputs\":[{\"internalType\":\"enumAutomationRegistryBase2_3.MigrationPermission\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerPerformByteGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerSignerGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getReorgProtectionEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getSignerInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"ownerLinkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"expectedLinkBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"totalPremium\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"numUpkeeps\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"latestConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"latestConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"latestEpoch\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_3.State\",\"name\":\"state\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.OnchainConfigLegacy\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitCalldataFixedBytesOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitCalldataPerSignerBytesOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getTransmitterInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"lastCollected\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTriggerType\",\"outputs\":[{\"internalType\":\"enumAutomationRegistryBase2_3.Trigger\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getUpkeep\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"maxValidBlocknumber\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"lastPerformedBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"amountSpent\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structAutomationRegistryBase2_3.UpkeepInfo\",\"name\":\"upkeepInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"hasDedupKey\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"pauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setAdminPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"setPayees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"},{\"internalType\":\"enumAutomationRegistryBase2_3.MigrationPermission\",\"name\":\"permission\",\"type\":\"uint8\"}],\"name\":\"setPeerRegistryMigrationPermission\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"setUpkeepCheckData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"setUpkeepOffchainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"unpauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTranscoderVersion\",\"outputs\":[{\"internalType\":\"enumUpkeepFormat\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawOwnerFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101206040523480156200001257600080fd5b5060405162004daf38038062004daf8339810160408190526200003591620001bf565b84848484843380600081620000915760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c457620000c481620000f7565b5050506001600160a01b0394851660805292841660a05290831660c052821660e0521661010052506200022f9350505050565b336001600160a01b03821603620001515760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000088565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001ba57600080fd5b919050565b600080600080600060a08688031215620001d857600080fd5b620001e386620001a2565b9450620001f360208701620001a2565b93506200020360408701620001a2565b92506200021360608701620001a2565b91506200022360808701620001a2565b90509295509295909350565b60805160a05160c05160e05161010051614b0a620002a56000396000610715015260006105920152600081816105ff01526132df01526000818161077801526133b901526000818161080601528181611d490152818161201e015281816124870152818161299a0152612a1e0152614b0a6000f3fe608060405234801561001057600080fd5b50600436106103625760003560e01c80637d9b97e0116101c8578063b121e14711610104578063cd7f71b5116100a2578063ed56b3e11161007c578063ed56b3e114610863578063f2fde38b146108d6578063f777ff06146108e9578063faa3e996146108f057600080fd5b8063cd7f71b51461082a578063d76326481461083d578063eb5dcd6c1461085057600080fd5b8063b657bc9c116100de578063b657bc9c146107c9578063b79550be146107dc578063c7c3a19a146107e4578063ca30e6031461080457600080fd5b8063b121e1471461079c578063b148ab6b146107af578063b6511a2a146107c257600080fd5b80639e0a99ed11610171578063a72aa27e1161014b578063a72aa27e1461074c578063aab9edd61461075f578063abc76ae01461076e578063b10b673c1461077657600080fd5b80639e0a99ed1461070b578063a08714c014610713578063a710b2211461073957600080fd5b80638da5cb5b116101a25780638da5cb5b146106b75780638dcf0fe7146106d55780638ed02bab146106e857600080fd5b80637d9b97e0146106945780638456cb591461069c5780638765ecbe146106a457600080fd5b806343cc055c116102a25780635b6aa71c11610240578063671d36ed1161021a578063671d36ed14610623578063744bfe611461063657806379ba50971461064957806379ea99431461065157600080fd5b80635b6aa71c146105d75780636209e1e9146105ea5780636709d0e5146105fd57600080fd5b80634ca16c521161027c5780634ca16c52146105555780635147cd591461055d5780635165f2f51461057d5780635425d8ac1461059057600080fd5b806343cc055c1461050c57806344cb70b81461052357806348013d7b1461054657600080fd5b80631a2af0111161030f578063232c1cc5116102e9578063232c1cc5146104845780633b9cce591461048b5780633f4ba83a1461049e578063421d183b146104a657600080fd5b80631a2af011146104005780631e01043914610413578063207b65161461047157600080fd5b80631865c57d116103405780631865c57d146103b4578063187256e8146103cd57806319d97a94146103e057600080fd5b8063050ee65d1461036757806306e3b6321461037f5780630b7d33e61461039f575b600080fd5b62014c085b6040519081526020015b60405180910390f35b61039261038d366004613d35565b610936565b6040516103769190613d57565b6103b26103ad366004613de4565b610a53565b005b6103bc610b0d565b604051610376959493929190613fe7565b6103b26103db36600461411e565b610f57565b6103f36103ee36600461415b565b610fc8565b60405161037691906141d8565b6103b261040e3660046141eb565b61106a565b61045461042136600461415b565b6000908152600460205260409020600101546c0100000000000000000000000090046bffffffffffffffffffffffff1690565b6040516bffffffffffffffffffffffff9091168152602001610376565b6103f361047f36600461415b565b611170565b601861036c565b6103b2610499366004614210565b61118d565b6103b26113e3565b6104b96104b4366004614285565b611449565b60408051951515865260ff90941660208601526bffffffffffffffffffffffff9283169385019390935216606083015273ffffffffffffffffffffffffffffffffffffffff16608082015260a001610376565b60135460ff165b6040519015158152602001610376565b61051361053136600461415b565b60009081526008602052604090205460ff1690565b600060405161037691906142d1565b61ea6061036c565b61057061056b36600461415b565b611568565b60405161037691906142eb565b6103b261058b36600461415b565b611573565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610376565b6104546105e5366004614318565b6116ea565b6103f36105f8366004614285565b61188f565b7f00000000000000000000000000000000000000000000000000000000000000006105b2565b6103b2610631366004614351565b6118c3565b6103b26106443660046141eb565b61199d565b6103b2611e44565b6105b261065f36600461415b565b6000908152600460205260409020546901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690565b6103b2611f46565b6103b26120a1565b6103b26106b236600461415b565b612122565b60005473ffffffffffffffffffffffffffffffffffffffff166105b2565b6103b26106e3366004613de4565b61229c565b601354610100900473ffffffffffffffffffffffffffffffffffffffff166105b2565b6103a461036c565b7f00000000000000000000000000000000000000000000000000000000000000006105b2565b6103b261074736600461438d565b6122f1565b6103b261075a3660046143bb565b612559565b60405160038152602001610376565b6115e061036c565b7f00000000000000000000000000000000000000000000000000000000000000006105b2565b6103b26107aa366004614285565b61264e565b6103b26107bd36600461415b565b612746565b603261036c565b6104546107d736600461415b565b612934565b6103b2612961565b6107f76107f236600461415b565b612abd565b60405161037691906143de565b7f00000000000000000000000000000000000000000000000000000000000000006105b2565b6103b2610838366004613de4565b612e90565b61045461084b36600461415b565b612f27565b6103b261085e36600461438d565b612f32565b6108bd610871366004614285565b73ffffffffffffffffffffffffffffffffffffffff166000908152600c602090815260409182902082518084019093525460ff8082161515808552610100909204169290910182905291565b60408051921515835260ff909116602083015201610376565b6103b26108e4366004614285565b613090565b604061036c565b6109296108fe366004614285565b73ffffffffffffffffffffffffffffffffffffffff166000908152601a602052604090205460ff1690565b6040516103769190614515565b6060600061094460026130a4565b905080841061097f576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061098b8486614558565b905081811180610999575083155b6109a357806109a5565b815b905060006109b3868361456b565b67ffffffffffffffff8111156109cb576109cb61457e565b6040519080825280602002602001820160405280156109f4578160200160208202803683370190505b50905060005b8151811015610a4757610a18610a108883614558565b6002906130ae565b828281518110610a2a57610a2a6145ad565b602090810291909101015280610a3f816145dc565b9150506109fa565b50925050505b92915050565b6016546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610ab4576040517f77c3599200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152601d60205260409020610acd8284836146b6565b50827f2fd8d70753a007014349d4591843cc031c2dd7a260d7dd82eca8253686ae77698383604051610b009291906147d1565b60405180910390a2505050565b6040805161014081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810191909152604080516101e08101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201839052610100820183905261012082018390526101408201839052610160820183905261018082018390526101a08201526101c0810191909152604080516101408101825260155463ffffffff7401000000000000000000000000000000000000000082041682526bffffffffffffffffffffffff90811660208301526019549282019290925260125490911660608281019190915290819060009060808101610c4660026130a4565b8152601554780100000000000000000000000000000000000000000000000080820463ffffffff9081166020808601919091527c01000000000000000000000000000000000000000000000000000000008404821660408087019190915260115460608088019190915260125474010000000000000000000000000000000000000000810485166080808a01919091527e01000000000000000000000000000000000000000000000000000000000000820460ff16151560a0998a015283516101e0810185526c0100000000000000000000000080840488168252700100000000000000000000000000000000808504891697830197909752808a0488169582019590955296820462ffffff16928701929092527b01000000000000000000000000000000000000000000000000000000900461ffff16908501526014546bffffffffffffffffffffffff8116968501969096529304811660c083015260165480821660e08401526401000000008104821661010084015268010000000000000000900416610120820152601754610140820152601854610160820152910473ffffffffffffffffffffffffffffffffffffffff166101808201529095506101a08101610e1360096130c1565b81526016546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16602091820152601254600d80546040805182860281018601909152818152949850899489949293600e937d01000000000000000000000000000000000000000000000000000000000090910460ff16928591830182828015610ed657602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610eab575b5050505050925081805480602002602001604051908101604052809291908181526020018280548015610f3f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610f14575b50505050509150945094509450945094509091929394565b610f5f6130ce565b73ffffffffffffffffffffffffffffffffffffffff82166000908152601a6020526040902080548291907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836003811115610fbf57610fbf6142a2565b02179055505050565b6000818152601d60205260409020805460609190610fe590614614565b80601f016020809104026020016040519081016040528092919081815260200182805461101190614614565b801561105e5780601f106110335761010080835404028352916020019161105e565b820191906000526020600020905b81548152906001019060200180831161104157829003601f168201915b50505050509050919050565b61107382613151565b3373ffffffffffffffffffffffffffffffffffffffff8216036110c2576040517f8c8728c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff82811691161461116c5760008281526006602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851690811790915590519091339185917fb1cbb2c4b8480034c27e06da5f096b8233a8fd4497028593a41ff6df79726b3591a45b5050565b6000818152601b60205260409020805460609190610fe590614614565b6111956130ce565b600e5481146111d0576040517fcf54c06a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b600e548110156113a2576000600e82815481106111f2576111f26145ad565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff908116808452600f9092526040832054919350169085858581811061123c5761123c6145ad565b90506020020160208101906112519190614285565b905073ffffffffffffffffffffffffffffffffffffffff811615806112e4575073ffffffffffffffffffffffffffffffffffffffff8216158015906112c257508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b80156112e4575073ffffffffffffffffffffffffffffffffffffffff81811614155b1561131b576040517fb387a23800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8181161461138c5773ffffffffffffffffffffffffffffffffffffffff8381166000908152600f6020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169183169190911790555b505050808061139a906145dc565b9150506111d3565b507fa46de38886467c59be07a0675f14781206a5477d871628af46c2443822fcb725600e83836040516113d79392919061481e565b60405180910390a15050565b6113eb6130ce565b601280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e01000000000000000000000000000090049091166060820152829182918291829190829061150f5760608201516012546000916114fb916bffffffffffffffffffffffff166148d0565b600e5490915061150b9082614924565b9150505b81516020830151604084015161152690849061494f565b6060949094015173ffffffffffffffffffffffffffffffffffffffff9a8b166000908152600f6020526040902054929b919a9499509750921694509092505050565b6000610a4d82613205565b61157c81613151565b600081815260046020908152604091829020825160e081018452815460ff8116151580835263ffffffff610100830481169584019590955265010000000000820485169583019590955273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c08201529061167b576040517f1b88a78400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556116ba6002836132b0565b5060405182907f7bada562044eb163f6b4003c4553e4e62825344c0418eea087bed5ee05a4745690600090a25050565b60408051610160810182526012546bffffffffffffffffffffffff8116825263ffffffff6c010000000000000000000000008204811660208401527001000000000000000000000000000000008204811693830193909352740100000000000000000000000000000000000000008104909216606082015262ffffff7801000000000000000000000000000000000000000000000000830416608082015261ffff7b0100000000000000000000000000000000000000000000000000000083041660a082015260ff7d0100000000000000000000000000000000000000000000000000000000008304811660c08301527e0100000000000000000000000000000000000000000000000000000000000083048116151560e08301527f01000000000000000000000000000000000000000000000000000000000000009092048216151561010080830191909152601354928316151561012083015273ffffffffffffffffffffffffffffffffffffffff9204919091166101408201526000908180611874836132bc565b91509150611885838787858561349a565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152601e60205260409020805460609190610fe590614614565b6016546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314611924576040517f77c3599200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152601e602052604090206119548284836146b6565b508273ffffffffffffffffffffffffffffffffffffffff167f7c44b4eb59ee7873514e7e43e7718c269d872965938b288aa143befca62f99d28383604051610b009291906147d1565b6012547f0100000000000000000000000000000000000000000000000000000000000000900460ff16156119fd576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f010000000000000000000000000000000000000000000000000000000000000017905573ffffffffffffffffffffffffffffffffffffffff8116611a93576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600460209081526040808320815160e081018352815460ff81161515825263ffffffff610100820481168387015265010000000000820481168386015273ffffffffffffffffffffffffffffffffffffffff6901000000000000000000909204821660608401526001909301546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a08401527801000000000000000000000000000000000000000000000000900490921660c082015286855260059093529220549091163314611b9a576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601260010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c2e9190614974565b816040015163ffffffff161115611c71576040517fff84e5dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600460205260409020600101546019546c010000000000000000000000009091046bffffffffffffffffffffffff1690611cb190829061456b565b60195560008481526004602081905260409182902060010180547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff16905590517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116928201929092526bffffffffffffffffffffffff831660248201527f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303816000875af1158015611d94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db8919061498d565b50604080516bffffffffffffffffffffffff8316815273ffffffffffffffffffffffffffffffffffffffff8516602082015285917ff3b5906e5672f3e524854103bcafbbdba80dbdfeca2c35e116127b1060a68318910160405180910390a25050601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611eca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611f4e6130ce565b6015546019546bffffffffffffffffffffffff90911690611f7090829061456b565b601955601580547fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001690556040516bffffffffffffffffffffffff821681527f1d07d0b0be43d3e5fee41a80b579af370affee03fa595bf56d5d4c19328162f19060200160405180910390a16040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526bffffffffffffffffffffffff821660248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044015b6020604051808303816000875af115801561207d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116c919061498d565b6120a96130ce565b601280547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e010000000000000000000000000000000000000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589060200161143f565b61212b81613151565b600081815260046020908152604091829020825160e081018452815460ff8116158015835263ffffffff610100830481169584019590955265010000000000820485169583019590955273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c08201529061222a576040517f514b6c2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561226c600283613722565b5060405182907f8ab10247ce168c27748e656ecf852b951fcaac790c18106b19aa0ae57a8b741f90600090a25050565b6122a583613151565b6000838152601c602052604090206122be8284836146b6565b50827f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf48508383604051610b009291906147d1565b73ffffffffffffffffffffffffffffffffffffffff811661233e576040517f9c8d2cd200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600f602052604090205416331461239e576040517fcebf515b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254600e546000916123c19185916bffffffffffffffffffffffff169061372e565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff16905560195490915061242b906bffffffffffffffffffffffff83169061456b565b6019556040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526bffffffffffffffffffffffff831660248301527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af11580156124d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f4919061498d565b5060405133815273ffffffffffffffffffffffffffffffffffffffff808416916bffffffffffffffffffffffff8416918616907f9819093176a1851202c7bcfa46845809b4e47c261866550e94ed3775d2f406989060200160405180910390a4505050565b6108fc8163ffffffff16108061258e575060155463ffffffff7001000000000000000000000000000000009091048116908216115b156125c5576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6125ce82613151565b60008281526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010063ffffffff861690810291909117909155915191825283917fc24c07e655ce79fba8a589778987d3c015bc6af1632bb20cf9182e02a65d972c910160405180910390a25050565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152601060205260409020541633146126ae576040517f6752e7aa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8181166000818152600f602090815260408083208054337fffffffffffffffffffffffff000000000000000000000000000000000000000080831682179093556010909452828520805490921690915590519416939092849290917f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b39190a45050565b600081815260046020908152604091829020825160e081018452815460ff81161515825263ffffffff6101008204811694830194909452650100000000008104841694820185905273ffffffffffffffffffffffffffffffffffffffff69010000000000000000009091041660608201526001909101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a083015278010000000000000000000000000000000000000000000000009004821660c08201529114612843576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090205473ffffffffffffffffffffffffffffffffffffffff1633146128a0576040517f6352a85300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526005602090815260408083208054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821790935560069094528285208054909216909155905173ffffffffffffffffffffffffffffffffffffffff90911692839186917f5cff4db96bef051785e999f44bfcd21c18823e034fb92dd376e3db4ce0feeb2c91a4505050565b6000610a4d61294283613205565b600084815260046020526040902054610100900463ffffffff166116ea565b6129696130ce565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156129f6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a1a9190614974565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb3360195484612a67919061456b565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff9092166004830152602482015260440161205e565b604080516101408101825260008082526020820181905260609282018390528282018190526080820181905260a0820181905260c0820181905260e082018190526101008201526101208101919091526000828152600460209081526040808320815160e081018352815460ff811615158252610100810463ffffffff90811695830195909552650100000000008104851693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff16606083018190526001909101546bffffffffffffffffffffffff80821660808501526c0100000000000000000000000082041660a08401527801000000000000000000000000000000000000000000000000900490921660c0820152919015612c5557816060015173ffffffffffffffffffffffffffffffffffffffff1663f00e6a2a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c5091906149af565b612c58565b60005b90506040518061014001604052808273ffffffffffffffffffffffffffffffffffffffff168152602001836020015163ffffffff168152602001600760008781526020019081526020016000208054612cb090614614565b80601f0160208091040260200160405190810160405280929190818152602001828054612cdc90614614565b8015612d295780601f10612cfe57610100808354040283529160200191612d29565b820191906000526020600020905b815481529060010190602001808311612d0c57829003601f168201915b505050505081526020018360a001516bffffffffffffffffffffffff1681526020016005600087815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001836040015163ffffffff1667ffffffffffffffff1681526020018360c0015163ffffffff16815260200183608001516bffffffffffffffffffffffff168152602001836000015115158152602001601c60008781526020019081526020016000208054612e0690614614565b80601f0160208091040260200160405190810160405280929190818152602001828054612e3290614614565b8015612e7f5780601f10612e5457610100808354040283529160200191612e7f565b820191906000526020600020905b815481529060010190602001808311612e6257829003601f168201915b505050505081525092505050919050565b612e9983613151565b60165463ffffffff16811115612edb576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152600760205260409020612ef48284836146b6565b50827fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d8383604051610b009291906147d1565b6000610a4d82612934565b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600f6020526040902054163314612f92576040517fcebf515b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603612fe1576040517f8c8728c700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82811660009081526010602052604090205481169082161461116c5773ffffffffffffffffffffffffffffffffffffffff82811660008181526010602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169486169485179055513392917f84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e3836791a45050565b6130986130ce565b6130a181613936565b50565b6000610a4d825490565b60006130ba8383613a2b565b9392505050565b606060006130ba83613a55565b60005473ffffffffffffffffffffffffffffffffffffffff16331461314f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401611ec1565b565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff1633146131ae576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090205465010000000000900463ffffffff908116146130a1576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818160045b600f811015613292577fff00000000000000000000000000000000000000000000000000000000000000821683826020811061324a5761324a6145ad565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461328057506000949350505050565b8061328a816145dc565b91505061320c565b5081600f1a60018111156132a8576132a86142a2565b949350505050565b60006130ba8383613ab0565b6000806000836080015162ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613348573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061336c91906149e6565b509450909250505060008113158061338357508142105b806133a457508280156133a4575061339b824261456b565b8463ffffffff16105b156133b35760175495506133b7565b8095505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613422573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061344691906149e6565b509450909250505060008113158061345d57508142105b8061347e575082801561347e5750613475824261456b565b8463ffffffff16105b1561348d576018549450613491565b8094505b50505050915091565b600080808660018111156134b0576134b06142a2565b036134be575061ea60613513565b60018660018111156134d2576134d26142a2565b036134e1575062014c08613513565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008760c0015160016135269190614a36565b6135349060ff166040614a4f565b601654613552906103a490640100000000900463ffffffff16614558565b61355c9190614558565b601354604080517fde9ee35e00000000000000000000000000000000000000000000000000000000815281519394506000938493610100900473ffffffffffffffffffffffffffffffffffffffff169263de9ee35e92600480820193918290030181865afa1580156135d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135f69190614a66565b90925090508183613608836018614558565b6136129190614a4f565b60c08c0151613622906001614a36565b6136319060ff166115e0614a4f565b61363b9190614558565b6136459190614558565b61364f9085614558565b935060008a610140015173ffffffffffffffffffffffffffffffffffffffff166312544140856040518263ffffffff1660e01b815260040161369391815260200190565b602060405180830381865afa1580156136b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136d49190614974565b8b60a0015161ffff166136e79190614a4f565b90506000806137028d8c63ffffffff1689868e8e6000613aff565b9092509050613711818361494f565b9d9c50505050505050505050505050565b60006130ba8383613c3b565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e010000000000000000000000000000900490911660608201529061392a5760008160600151856137c691906148d0565b905060006137d48583614924565b905080836040018181516137e8919061494f565b6bffffffffffffffffffffffff169052506138038582614a8a565b83606001818151613814919061494f565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036139b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401611ec1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110613a4257613a426145ad565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561105e57602002820191906000526020600020905b815481526020019060010190808311613a915750505050509050919050565b6000818152600183016020526040812054613af757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610a4d565b506000610a4d565b60008060008960a0015161ffff1686613b189190614a4f565b9050838015613b265750803a105b15613b2e57503a5b60008588613b3c8b8d614558565b613b469085614a4f565b613b509190614558565b613b6290670de0b6b3a7640000614a4f565b613b6c9190614aba565b905060008b6040015163ffffffff1664e8d4a51000613b8b9190614a4f565b60208d0151889063ffffffff168b613ba38f88614a4f565b613bad9190614558565b613bbb90633b9aca00614a4f565b613bc59190614a4f565b613bcf9190614aba565b613bd99190614558565b90506b033b2e3c9fd0803ce8000000613bf28284614558565b1115613c2a576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909b909a5098505050505050505050565b60008181526001830160205260408120548015613d24576000613c5f60018361456b565b8554909150600090613c739060019061456b565b9050818114613cd8576000866000018281548110613c9357613c936145ad565b9060005260206000200154905080876000018481548110613cb657613cb66145ad565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613ce957613ce9614ace565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610a4d565b6000915050610a4d565b5092915050565b60008060408385031215613d4857600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b81811015613d8f57835183529284019291840191600101613d73565b50909695505050505050565b60008083601f840112613dad57600080fd5b50813567ffffffffffffffff811115613dc557600080fd5b602083019150836020828501011115613ddd57600080fd5b9250929050565b600080600060408486031215613df957600080fd5b83359250602084013567ffffffffffffffff811115613e1757600080fd5b613e2386828701613d9b565b9497909650939450505050565b600081518084526020808501945080840160005b83811015613e7657815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613e44565b509495945050505050565b805163ffffffff16825260006101e06020830151613ea7602086018263ffffffff169052565b506040830151613ebf604086018263ffffffff169052565b506060830151613ed6606086018262ffffff169052565b506080830151613eec608086018261ffff169052565b5060a0830151613f0c60a08601826bffffffffffffffffffffffff169052565b5060c0830151613f2460c086018263ffffffff169052565b5060e0830151613f3c60e086018263ffffffff169052565b506101008381015163ffffffff908116918601919091526101208085015190911690850152610140808401519085015261016080840151908501526101808084015173ffffffffffffffffffffffffffffffffffffffff16908501526101a080840151818601839052613fb183870182613e30565b925050506101c080840151613fdd8287018273ffffffffffffffffffffffffffffffffffffffff169052565b5090949350505050565b855163ffffffff16815260006101c0602088015161401560208501826bffffffffffffffffffffffff169052565b5060408801516040840152606088015161403f60608501826bffffffffffffffffffffffff169052565b506080880151608084015260a088015161406160a085018263ffffffff169052565b5060c088015161407960c085018263ffffffff169052565b5060e088015160e08401526101008089015161409c8286018263ffffffff169052565b50506101208881015115159084015261014083018190526140bf81840188613e81565b90508281036101608401526140d48187613e30565b90508281036101808401526140e98186613e30565b9150506118856101a083018460ff169052565b73ffffffffffffffffffffffffffffffffffffffff811681146130a157600080fd5b6000806040838503121561413157600080fd5b823561413c816140fc565b915060208301356004811061415057600080fd5b809150509250929050565b60006020828403121561416d57600080fd5b5035919050565b6000815180845260005b8181101561419a5760208185018101518683018201520161417e565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006130ba6020830184614174565b600080604083850312156141fe57600080fd5b823591506020830135614150816140fc565b6000806020838503121561422357600080fd5b823567ffffffffffffffff8082111561423b57600080fd5b818501915085601f83011261424f57600080fd5b81358181111561425e57600080fd5b8660208260051b850101111561427357600080fd5b60209290920196919550909350505050565b60006020828403121561429757600080fd5b81356130ba816140fc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106142e5576142e56142a2565b91905290565b60208101600283106142e5576142e56142a2565b803563ffffffff8116811461431357600080fd5b919050565b6000806040838503121561432b57600080fd5b82356002811061433a57600080fd5b9150614348602084016142ff565b90509250929050565b60008060006040848603121561436657600080fd5b8335614371816140fc565b9250602084013567ffffffffffffffff811115613e1757600080fd5b600080604083850312156143a057600080fd5b82356143ab816140fc565b91506020830135614150816140fc565b600080604083850312156143ce57600080fd5b82359150614348602084016142ff565b6020815261440560208201835173ffffffffffffffffffffffffffffffffffffffff169052565b6000602083015161441e604084018263ffffffff169052565b50604083015161014080606085015261443b610160850183614174565b9150606085015161445c60808601826bffffffffffffffffffffffff169052565b50608085015173ffffffffffffffffffffffffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015163ffffffff811660e08601525060e08501516101006144c8818701836bffffffffffffffffffffffff169052565b86015190506101206144dd8682018315159052565b8601518584037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018387015290506118858382614174565b60208101600483106142e5576142e56142a2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610a4d57610a4d614529565b81810381811115610a4d57610a4d614529565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361460d5761460d614529565b5060010190565b600181811c9082168061462857607f821691505b602082108103614661577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156146b157600081815260208120601f850160051c8101602086101561468e5750805b601f850160051c820191505b818110156146ad5782815560010161469a565b5050505b505050565b67ffffffffffffffff8311156146ce576146ce61457e565b6146e2836146dc8354614614565b83614667565b6000601f84116001811461473457600085156146fe5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556147ca565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156147835786850135825560209485019460019092019101614763565b50868210156147be577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b6000604082016040835280865480835260608501915087600052602092508260002060005b8281101561487557815473ffffffffffffffffffffffffffffffffffffffff1684529284019260019182019101614843565b505050838103828501528481528590820160005b868110156148c457823561489c816140fc565b73ffffffffffffffffffffffffffffffffffffffff1682529183019190830190600101614889565b50979650505050505050565b6bffffffffffffffffffffffff828116828216039080821115613d2e57613d2e614529565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006bffffffffffffffffffffffff80841680614943576149436148f5565b92169190910492915050565b6bffffffffffffffffffffffff818116838216019080821115613d2e57613d2e614529565b60006020828403121561498657600080fd5b5051919050565b60006020828403121561499f57600080fd5b815180151581146130ba57600080fd5b6000602082840312156149c157600080fd5b81516130ba816140fc565b805169ffffffffffffffffffff8116811461431357600080fd5b600080600080600060a086880312156149fe57600080fd5b614a07866149cc565b9450602086015193506040860151925060608601519150614a2a608087016149cc565b90509295509295909350565b60ff8181168382160190811115610a4d57610a4d614529565b8082028115828204841417610a4d57610a4d614529565b60008060408385031215614a7957600080fd5b505080516020909101519092909150565b6bffffffffffffffffffffffff818116838216028082169190828114614ab257614ab2614529565b505092915050565b600082614ac957614ac96148f5565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", +} + +var AutomationRegistryLogicBABI = AutomationRegistryLogicBMetaData.ABI + +var AutomationRegistryLogicBBin = AutomationRegistryLogicBMetaData.Bin + +func DeployAutomationRegistryLogicB(auth *bind.TransactOpts, backend bind.ContractBackend, link common.Address, linkNativeFeed common.Address, fastGasFeed common.Address, automationForwarderLogic common.Address, allowedReadOnlyAddress common.Address) (common.Address, *types.Transaction, *AutomationRegistryLogicB, error) { + parsed, err := AutomationRegistryLogicBMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(AutomationRegistryLogicBBin), backend, link, linkNativeFeed, fastGasFeed, automationForwarderLogic, allowedReadOnlyAddress) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &AutomationRegistryLogicB{address: address, abi: *parsed, AutomationRegistryLogicBCaller: AutomationRegistryLogicBCaller{contract: contract}, AutomationRegistryLogicBTransactor: AutomationRegistryLogicBTransactor{contract: contract}, AutomationRegistryLogicBFilterer: AutomationRegistryLogicBFilterer{contract: contract}}, nil +} + +type AutomationRegistryLogicB struct { + address common.Address + abi abi.ABI + AutomationRegistryLogicBCaller + AutomationRegistryLogicBTransactor + AutomationRegistryLogicBFilterer +} + +type AutomationRegistryLogicBCaller struct { + contract *bind.BoundContract +} + +type AutomationRegistryLogicBTransactor struct { + contract *bind.BoundContract +} + +type AutomationRegistryLogicBFilterer struct { + contract *bind.BoundContract +} + +type AutomationRegistryLogicBSession struct { + Contract *AutomationRegistryLogicB + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type AutomationRegistryLogicBCallerSession struct { + Contract *AutomationRegistryLogicBCaller + CallOpts bind.CallOpts +} + +type AutomationRegistryLogicBTransactorSession struct { + Contract *AutomationRegistryLogicBTransactor + TransactOpts bind.TransactOpts +} + +type AutomationRegistryLogicBRaw struct { + Contract *AutomationRegistryLogicB +} + +type AutomationRegistryLogicBCallerRaw struct { + Contract *AutomationRegistryLogicBCaller +} + +type AutomationRegistryLogicBTransactorRaw struct { + Contract *AutomationRegistryLogicBTransactor +} + +func NewAutomationRegistryLogicB(address common.Address, backend bind.ContractBackend) (*AutomationRegistryLogicB, error) { + abi, err := abi.JSON(strings.NewReader(AutomationRegistryLogicBABI)) + if err != nil { + return nil, err + } + contract, err := bindAutomationRegistryLogicB(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicB{address: address, abi: abi, AutomationRegistryLogicBCaller: AutomationRegistryLogicBCaller{contract: contract}, AutomationRegistryLogicBTransactor: AutomationRegistryLogicBTransactor{contract: contract}, AutomationRegistryLogicBFilterer: AutomationRegistryLogicBFilterer{contract: contract}}, nil +} + +func NewAutomationRegistryLogicBCaller(address common.Address, caller bind.ContractCaller) (*AutomationRegistryLogicBCaller, error) { + contract, err := bindAutomationRegistryLogicB(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBCaller{contract: contract}, nil +} + +func NewAutomationRegistryLogicBTransactor(address common.Address, transactor bind.ContractTransactor) (*AutomationRegistryLogicBTransactor, error) { + contract, err := bindAutomationRegistryLogicB(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBTransactor{contract: contract}, nil +} + +func NewAutomationRegistryLogicBFilterer(address common.Address, filterer bind.ContractFilterer) (*AutomationRegistryLogicBFilterer, error) { + contract, err := bindAutomationRegistryLogicB(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBFilterer{contract: contract}, nil +} + +func bindAutomationRegistryLogicB(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := AutomationRegistryLogicBMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AutomationRegistryLogicB.Contract.AutomationRegistryLogicBCaller.contract.Call(opts, result, method, params...) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.AutomationRegistryLogicBTransactor.contract.Transfer(opts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.AutomationRegistryLogicBTransactor.contract.Transact(opts, method, params...) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AutomationRegistryLogicB.Contract.contract.Call(opts, result, method, params...) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.contract.Transfer(opts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.contract.Transact(opts, method, params...) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetActiveUpkeepIDs(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getActiveUpkeepIDs", startIndex, maxCount) + + if err != nil { + return *new([]*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetActiveUpkeepIDs(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetActiveUpkeepIDs(&_AutomationRegistryLogicB.CallOpts, startIndex, maxCount) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetActiveUpkeepIDs(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetActiveUpkeepIDs(&_AutomationRegistryLogicB.CallOpts, startIndex, maxCount) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetAdminPrivilegeConfig(opts *bind.CallOpts, admin common.Address) ([]byte, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getAdminPrivilegeConfig", admin) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetAdminPrivilegeConfig(admin common.Address) ([]byte, error) { + return _AutomationRegistryLogicB.Contract.GetAdminPrivilegeConfig(&_AutomationRegistryLogicB.CallOpts, admin) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetAdminPrivilegeConfig(admin common.Address) ([]byte, error) { + return _AutomationRegistryLogicB.Contract.GetAdminPrivilegeConfig(&_AutomationRegistryLogicB.CallOpts, admin) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetAllowedReadOnlyAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getAllowedReadOnlyAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetAllowedReadOnlyAddress() (common.Address, error) { + return _AutomationRegistryLogicB.Contract.GetAllowedReadOnlyAddress(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetAllowedReadOnlyAddress() (common.Address, error) { + return _AutomationRegistryLogicB.Contract.GetAllowedReadOnlyAddress(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetAutomationForwarderLogic(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getAutomationForwarderLogic") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetAutomationForwarderLogic() (common.Address, error) { + return _AutomationRegistryLogicB.Contract.GetAutomationForwarderLogic(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetAutomationForwarderLogic() (common.Address, error) { + return _AutomationRegistryLogicB.Contract.GetAutomationForwarderLogic(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getBalance", id) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetBalance(id *big.Int) (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetBalance(&_AutomationRegistryLogicB.CallOpts, id) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetBalance(id *big.Int) (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetBalance(&_AutomationRegistryLogicB.CallOpts, id) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetCancellationDelay(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getCancellationDelay") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetCancellationDelay() (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetCancellationDelay(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetCancellationDelay() (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetCancellationDelay(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetChainModule(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getChainModule") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetChainModule() (common.Address, error) { + return _AutomationRegistryLogicB.Contract.GetChainModule(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetChainModule() (common.Address, error) { + return _AutomationRegistryLogicB.Contract.GetChainModule(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetConditionalGasOverhead(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getConditionalGasOverhead") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetConditionalGasOverhead() (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetConditionalGasOverhead(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetConditionalGasOverhead() (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetConditionalGasOverhead(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetFastGasFeedAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getFastGasFeedAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetFastGasFeedAddress() (common.Address, error) { + return _AutomationRegistryLogicB.Contract.GetFastGasFeedAddress(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetFastGasFeedAddress() (common.Address, error) { + return _AutomationRegistryLogicB.Contract.GetFastGasFeedAddress(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetForwarder(opts *bind.CallOpts, upkeepID *big.Int) (common.Address, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getForwarder", upkeepID) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetForwarder(upkeepID *big.Int) (common.Address, error) { + return _AutomationRegistryLogicB.Contract.GetForwarder(&_AutomationRegistryLogicB.CallOpts, upkeepID) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetForwarder(upkeepID *big.Int) (common.Address, error) { + return _AutomationRegistryLogicB.Contract.GetForwarder(&_AutomationRegistryLogicB.CallOpts, upkeepID) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetLinkAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getLinkAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetLinkAddress() (common.Address, error) { + return _AutomationRegistryLogicB.Contract.GetLinkAddress(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetLinkAddress() (common.Address, error) { + return _AutomationRegistryLogicB.Contract.GetLinkAddress(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetLinkNativeFeedAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getLinkNativeFeedAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetLinkNativeFeedAddress() (common.Address, error) { + return _AutomationRegistryLogicB.Contract.GetLinkNativeFeedAddress(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetLinkNativeFeedAddress() (common.Address, error) { + return _AutomationRegistryLogicB.Contract.GetLinkNativeFeedAddress(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetLogGasOverhead(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getLogGasOverhead") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetLogGasOverhead() (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetLogGasOverhead(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetLogGasOverhead() (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetLogGasOverhead(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetMaxPaymentForGas(opts *bind.CallOpts, triggerType uint8, gasLimit uint32) (*big.Int, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getMaxPaymentForGas", triggerType, gasLimit) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetMaxPaymentForGas(triggerType uint8, gasLimit uint32) (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetMaxPaymentForGas(&_AutomationRegistryLogicB.CallOpts, triggerType, gasLimit) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetMaxPaymentForGas(triggerType uint8, gasLimit uint32) (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetMaxPaymentForGas(&_AutomationRegistryLogicB.CallOpts, triggerType, gasLimit) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetMinBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getMinBalance", id) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetMinBalance(id *big.Int) (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetMinBalance(&_AutomationRegistryLogicB.CallOpts, id) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetMinBalance(id *big.Int) (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetMinBalance(&_AutomationRegistryLogicB.CallOpts, id) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetMinBalanceForUpkeep(opts *bind.CallOpts, id *big.Int) (*big.Int, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getMinBalanceForUpkeep", id) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetMinBalanceForUpkeep(id *big.Int) (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetMinBalanceForUpkeep(&_AutomationRegistryLogicB.CallOpts, id) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetMinBalanceForUpkeep(id *big.Int) (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetMinBalanceForUpkeep(&_AutomationRegistryLogicB.CallOpts, id) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetPeerRegistryMigrationPermission(opts *bind.CallOpts, peer common.Address) (uint8, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getPeerRegistryMigrationPermission", peer) + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetPeerRegistryMigrationPermission(peer common.Address) (uint8, error) { + return _AutomationRegistryLogicB.Contract.GetPeerRegistryMigrationPermission(&_AutomationRegistryLogicB.CallOpts, peer) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetPeerRegistryMigrationPermission(peer common.Address) (uint8, error) { + return _AutomationRegistryLogicB.Contract.GetPeerRegistryMigrationPermission(&_AutomationRegistryLogicB.CallOpts, peer) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetPerPerformByteGasOverhead(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getPerPerformByteGasOverhead") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetPerPerformByteGasOverhead() (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetPerPerformByteGasOverhead(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetPerPerformByteGasOverhead() (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetPerPerformByteGasOverhead(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetPerSignerGasOverhead(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getPerSignerGasOverhead") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetPerSignerGasOverhead() (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetPerSignerGasOverhead(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetPerSignerGasOverhead() (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetPerSignerGasOverhead(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetReorgProtectionEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getReorgProtectionEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetReorgProtectionEnabled() (bool, error) { + return _AutomationRegistryLogicB.Contract.GetReorgProtectionEnabled(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetReorgProtectionEnabled() (bool, error) { + return _AutomationRegistryLogicB.Contract.GetReorgProtectionEnabled(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetSignerInfo(opts *bind.CallOpts, query common.Address) (GetSignerInfo, + + error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getSignerInfo", query) + + outstruct := new(GetSignerInfo) + if err != nil { + return *outstruct, err + } + + outstruct.Active = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.Index = *abi.ConvertType(out[1], new(uint8)).(*uint8) + + return *outstruct, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetSignerInfo(query common.Address) (GetSignerInfo, + + error) { + return _AutomationRegistryLogicB.Contract.GetSignerInfo(&_AutomationRegistryLogicB.CallOpts, query) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetSignerInfo(query common.Address) (GetSignerInfo, + + error) { + return _AutomationRegistryLogicB.Contract.GetSignerInfo(&_AutomationRegistryLogicB.CallOpts, query) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetState(opts *bind.CallOpts) (GetState, + + error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getState") + + outstruct := new(GetState) + if err != nil { + return *outstruct, err + } + + outstruct.State = *abi.ConvertType(out[0], new(AutomationRegistryBase23State)).(*AutomationRegistryBase23State) + outstruct.Config = *abi.ConvertType(out[1], new(AutomationRegistryBase23OnchainConfigLegacy)).(*AutomationRegistryBase23OnchainConfigLegacy) + outstruct.Signers = *abi.ConvertType(out[2], new([]common.Address)).(*[]common.Address) + outstruct.Transmitters = *abi.ConvertType(out[3], new([]common.Address)).(*[]common.Address) + outstruct.F = *abi.ConvertType(out[4], new(uint8)).(*uint8) + + return *outstruct, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetState() (GetState, + + error) { + return _AutomationRegistryLogicB.Contract.GetState(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetState() (GetState, + + error) { + return _AutomationRegistryLogicB.Contract.GetState(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetTransmitCalldataFixedBytesOverhead(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getTransmitCalldataFixedBytesOverhead") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetTransmitCalldataFixedBytesOverhead() (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetTransmitCalldataFixedBytesOverhead(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetTransmitCalldataFixedBytesOverhead() (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetTransmitCalldataFixedBytesOverhead(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetTransmitCalldataPerSignerBytesOverhead(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getTransmitCalldataPerSignerBytesOverhead") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetTransmitCalldataPerSignerBytesOverhead() (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetTransmitCalldataPerSignerBytesOverhead(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetTransmitCalldataPerSignerBytesOverhead() (*big.Int, error) { + return _AutomationRegistryLogicB.Contract.GetTransmitCalldataPerSignerBytesOverhead(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetTransmitterInfo(opts *bind.CallOpts, query common.Address) (GetTransmitterInfo, + + error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getTransmitterInfo", query) + + outstruct := new(GetTransmitterInfo) + if err != nil { + return *outstruct, err + } + + outstruct.Active = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.Index = *abi.ConvertType(out[1], new(uint8)).(*uint8) + outstruct.Balance = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + outstruct.LastCollected = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.Payee = *abi.ConvertType(out[4], new(common.Address)).(*common.Address) + + return *outstruct, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetTransmitterInfo(query common.Address) (GetTransmitterInfo, + + error) { + return _AutomationRegistryLogicB.Contract.GetTransmitterInfo(&_AutomationRegistryLogicB.CallOpts, query) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetTransmitterInfo(query common.Address) (GetTransmitterInfo, + + error) { + return _AutomationRegistryLogicB.Contract.GetTransmitterInfo(&_AutomationRegistryLogicB.CallOpts, query) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetTriggerType(opts *bind.CallOpts, upkeepId *big.Int) (uint8, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getTriggerType", upkeepId) + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetTriggerType(upkeepId *big.Int) (uint8, error) { + return _AutomationRegistryLogicB.Contract.GetTriggerType(&_AutomationRegistryLogicB.CallOpts, upkeepId) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetTriggerType(upkeepId *big.Int) (uint8, error) { + return _AutomationRegistryLogicB.Contract.GetTriggerType(&_AutomationRegistryLogicB.CallOpts, upkeepId) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetUpkeep(opts *bind.CallOpts, id *big.Int) (AutomationRegistryBase23UpkeepInfo, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getUpkeep", id) + + if err != nil { + return *new(AutomationRegistryBase23UpkeepInfo), err + } + + out0 := *abi.ConvertType(out[0], new(AutomationRegistryBase23UpkeepInfo)).(*AutomationRegistryBase23UpkeepInfo) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetUpkeep(id *big.Int) (AutomationRegistryBase23UpkeepInfo, error) { + return _AutomationRegistryLogicB.Contract.GetUpkeep(&_AutomationRegistryLogicB.CallOpts, id) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetUpkeep(id *big.Int) (AutomationRegistryBase23UpkeepInfo, error) { + return _AutomationRegistryLogicB.Contract.GetUpkeep(&_AutomationRegistryLogicB.CallOpts, id) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetUpkeepPrivilegeConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getUpkeepPrivilegeConfig", upkeepId) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetUpkeepPrivilegeConfig(upkeepId *big.Int) ([]byte, error) { + return _AutomationRegistryLogicB.Contract.GetUpkeepPrivilegeConfig(&_AutomationRegistryLogicB.CallOpts, upkeepId) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetUpkeepPrivilegeConfig(upkeepId *big.Int) ([]byte, error) { + return _AutomationRegistryLogicB.Contract.GetUpkeepPrivilegeConfig(&_AutomationRegistryLogicB.CallOpts, upkeepId) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) GetUpkeepTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "getUpkeepTriggerConfig", upkeepId) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) GetUpkeepTriggerConfig(upkeepId *big.Int) ([]byte, error) { + return _AutomationRegistryLogicB.Contract.GetUpkeepTriggerConfig(&_AutomationRegistryLogicB.CallOpts, upkeepId) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) GetUpkeepTriggerConfig(upkeepId *big.Int) ([]byte, error) { + return _AutomationRegistryLogicB.Contract.GetUpkeepTriggerConfig(&_AutomationRegistryLogicB.CallOpts, upkeepId) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) HasDedupKey(opts *bind.CallOpts, dedupKey [32]byte) (bool, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "hasDedupKey", dedupKey) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) HasDedupKey(dedupKey [32]byte) (bool, error) { + return _AutomationRegistryLogicB.Contract.HasDedupKey(&_AutomationRegistryLogicB.CallOpts, dedupKey) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) HasDedupKey(dedupKey [32]byte) (bool, error) { + return _AutomationRegistryLogicB.Contract.HasDedupKey(&_AutomationRegistryLogicB.CallOpts, dedupKey) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) Owner() (common.Address, error) { + return _AutomationRegistryLogicB.Contract.Owner(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) Owner() (common.Address, error) { + return _AutomationRegistryLogicB.Contract.Owner(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) UpkeepTranscoderVersion(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "upkeepTranscoderVersion") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) UpkeepTranscoderVersion() (uint8, error) { + return _AutomationRegistryLogicB.Contract.UpkeepTranscoderVersion(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) UpkeepTranscoderVersion() (uint8, error) { + return _AutomationRegistryLogicB.Contract.UpkeepTranscoderVersion(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCaller) UpkeepVersion(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _AutomationRegistryLogicB.contract.Call(opts, &out, "upkeepVersion") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) UpkeepVersion() (uint8, error) { + return _AutomationRegistryLogicB.Contract.UpkeepVersion(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBCallerSession) UpkeepVersion() (uint8, error) { + return _AutomationRegistryLogicB.Contract.UpkeepVersion(&_AutomationRegistryLogicB.CallOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "acceptOwnership") +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) AcceptOwnership() (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.AcceptOwnership(&_AutomationRegistryLogicB.TransactOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.AcceptOwnership(&_AutomationRegistryLogicB.TransactOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) AcceptPayeeship(opts *bind.TransactOpts, transmitter common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "acceptPayeeship", transmitter) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) AcceptPayeeship(transmitter common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.AcceptPayeeship(&_AutomationRegistryLogicB.TransactOpts, transmitter) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) AcceptPayeeship(transmitter common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.AcceptPayeeship(&_AutomationRegistryLogicB.TransactOpts, transmitter) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) AcceptUpkeepAdmin(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "acceptUpkeepAdmin", id) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) AcceptUpkeepAdmin(id *big.Int) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.AcceptUpkeepAdmin(&_AutomationRegistryLogicB.TransactOpts, id) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) AcceptUpkeepAdmin(id *big.Int) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.AcceptUpkeepAdmin(&_AutomationRegistryLogicB.TransactOpts, id) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "pause") +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) Pause() (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.Pause(&_AutomationRegistryLogicB.TransactOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) Pause() (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.Pause(&_AutomationRegistryLogicB.TransactOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) PauseUpkeep(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "pauseUpkeep", id) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) PauseUpkeep(id *big.Int) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.PauseUpkeep(&_AutomationRegistryLogicB.TransactOpts, id) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) PauseUpkeep(id *big.Int) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.PauseUpkeep(&_AutomationRegistryLogicB.TransactOpts, id) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) RecoverFunds(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "recoverFunds") +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) RecoverFunds() (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.RecoverFunds(&_AutomationRegistryLogicB.TransactOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) RecoverFunds() (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.RecoverFunds(&_AutomationRegistryLogicB.TransactOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) SetAdminPrivilegeConfig(opts *bind.TransactOpts, admin common.Address, newPrivilegeConfig []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "setAdminPrivilegeConfig", admin, newPrivilegeConfig) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) SetAdminPrivilegeConfig(admin common.Address, newPrivilegeConfig []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.SetAdminPrivilegeConfig(&_AutomationRegistryLogicB.TransactOpts, admin, newPrivilegeConfig) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) SetAdminPrivilegeConfig(admin common.Address, newPrivilegeConfig []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.SetAdminPrivilegeConfig(&_AutomationRegistryLogicB.TransactOpts, admin, newPrivilegeConfig) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) SetPayees(opts *bind.TransactOpts, payees []common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "setPayees", payees) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) SetPayees(payees []common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.SetPayees(&_AutomationRegistryLogicB.TransactOpts, payees) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) SetPayees(payees []common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.SetPayees(&_AutomationRegistryLogicB.TransactOpts, payees) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) SetPeerRegistryMigrationPermission(opts *bind.TransactOpts, peer common.Address, permission uint8) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "setPeerRegistryMigrationPermission", peer, permission) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) SetPeerRegistryMigrationPermission(peer common.Address, permission uint8) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.SetPeerRegistryMigrationPermission(&_AutomationRegistryLogicB.TransactOpts, peer, permission) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) SetPeerRegistryMigrationPermission(peer common.Address, permission uint8) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.SetPeerRegistryMigrationPermission(&_AutomationRegistryLogicB.TransactOpts, peer, permission) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) SetUpkeepCheckData(opts *bind.TransactOpts, id *big.Int, newCheckData []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "setUpkeepCheckData", id, newCheckData) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) SetUpkeepCheckData(id *big.Int, newCheckData []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.SetUpkeepCheckData(&_AutomationRegistryLogicB.TransactOpts, id, newCheckData) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) SetUpkeepCheckData(id *big.Int, newCheckData []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.SetUpkeepCheckData(&_AutomationRegistryLogicB.TransactOpts, id, newCheckData) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) SetUpkeepGasLimit(opts *bind.TransactOpts, id *big.Int, gasLimit uint32) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "setUpkeepGasLimit", id, gasLimit) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) SetUpkeepGasLimit(id *big.Int, gasLimit uint32) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.SetUpkeepGasLimit(&_AutomationRegistryLogicB.TransactOpts, id, gasLimit) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) SetUpkeepGasLimit(id *big.Int, gasLimit uint32) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.SetUpkeepGasLimit(&_AutomationRegistryLogicB.TransactOpts, id, gasLimit) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) SetUpkeepOffchainConfig(opts *bind.TransactOpts, id *big.Int, config []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "setUpkeepOffchainConfig", id, config) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) SetUpkeepOffchainConfig(id *big.Int, config []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.SetUpkeepOffchainConfig(&_AutomationRegistryLogicB.TransactOpts, id, config) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) SetUpkeepOffchainConfig(id *big.Int, config []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.SetUpkeepOffchainConfig(&_AutomationRegistryLogicB.TransactOpts, id, config) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) SetUpkeepPrivilegeConfig(opts *bind.TransactOpts, upkeepId *big.Int, newPrivilegeConfig []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "setUpkeepPrivilegeConfig", upkeepId, newPrivilegeConfig) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) SetUpkeepPrivilegeConfig(upkeepId *big.Int, newPrivilegeConfig []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.SetUpkeepPrivilegeConfig(&_AutomationRegistryLogicB.TransactOpts, upkeepId, newPrivilegeConfig) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) SetUpkeepPrivilegeConfig(upkeepId *big.Int, newPrivilegeConfig []byte) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.SetUpkeepPrivilegeConfig(&_AutomationRegistryLogicB.TransactOpts, upkeepId, newPrivilegeConfig) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "transferOwnership", to) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.TransferOwnership(&_AutomationRegistryLogicB.TransactOpts, to) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.TransferOwnership(&_AutomationRegistryLogicB.TransactOpts, to) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) TransferPayeeship(opts *bind.TransactOpts, transmitter common.Address, proposed common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "transferPayeeship", transmitter, proposed) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) TransferPayeeship(transmitter common.Address, proposed common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.TransferPayeeship(&_AutomationRegistryLogicB.TransactOpts, transmitter, proposed) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) TransferPayeeship(transmitter common.Address, proposed common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.TransferPayeeship(&_AutomationRegistryLogicB.TransactOpts, transmitter, proposed) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) TransferUpkeepAdmin(opts *bind.TransactOpts, id *big.Int, proposed common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "transferUpkeepAdmin", id, proposed) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) TransferUpkeepAdmin(id *big.Int, proposed common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.TransferUpkeepAdmin(&_AutomationRegistryLogicB.TransactOpts, id, proposed) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) TransferUpkeepAdmin(id *big.Int, proposed common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.TransferUpkeepAdmin(&_AutomationRegistryLogicB.TransactOpts, id, proposed) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "unpause") +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) Unpause() (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.Unpause(&_AutomationRegistryLogicB.TransactOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) Unpause() (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.Unpause(&_AutomationRegistryLogicB.TransactOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) UnpauseUpkeep(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "unpauseUpkeep", id) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) UnpauseUpkeep(id *big.Int) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.UnpauseUpkeep(&_AutomationRegistryLogicB.TransactOpts, id) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) UnpauseUpkeep(id *big.Int) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.UnpauseUpkeep(&_AutomationRegistryLogicB.TransactOpts, id) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) WithdrawFunds(opts *bind.TransactOpts, id *big.Int, to common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "withdrawFunds", id, to) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) WithdrawFunds(id *big.Int, to common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.WithdrawFunds(&_AutomationRegistryLogicB.TransactOpts, id, to) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) WithdrawFunds(id *big.Int, to common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.WithdrawFunds(&_AutomationRegistryLogicB.TransactOpts, id, to) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) WithdrawOwnerFunds(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "withdrawOwnerFunds") +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) WithdrawOwnerFunds() (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.WithdrawOwnerFunds(&_AutomationRegistryLogicB.TransactOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) WithdrawOwnerFunds() (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.WithdrawOwnerFunds(&_AutomationRegistryLogicB.TransactOpts) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactor) WithdrawPayment(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.contract.Transact(opts, "withdrawPayment", from, to) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBSession) WithdrawPayment(from common.Address, to common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.WithdrawPayment(&_AutomationRegistryLogicB.TransactOpts, from, to) +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBTransactorSession) WithdrawPayment(from common.Address, to common.Address) (*types.Transaction, error) { + return _AutomationRegistryLogicB.Contract.WithdrawPayment(&_AutomationRegistryLogicB.TransactOpts, from, to) +} + +type AutomationRegistryLogicBAdminPrivilegeConfigSetIterator struct { + Event *AutomationRegistryLogicBAdminPrivilegeConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBAdminPrivilegeConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBAdminPrivilegeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBAdminPrivilegeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBAdminPrivilegeConfigSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBAdminPrivilegeConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBAdminPrivilegeConfigSet struct { + Admin common.Address + PrivilegeConfig []byte + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterAdminPrivilegeConfigSet(opts *bind.FilterOpts, admin []common.Address) (*AutomationRegistryLogicBAdminPrivilegeConfigSetIterator, error) { + + var adminRule []interface{} + for _, adminItem := range admin { + adminRule = append(adminRule, adminItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "AdminPrivilegeConfigSet", adminRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBAdminPrivilegeConfigSetIterator{contract: _AutomationRegistryLogicB.contract, event: "AdminPrivilegeConfigSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchAdminPrivilegeConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBAdminPrivilegeConfigSet, admin []common.Address) (event.Subscription, error) { + + var adminRule []interface{} + for _, adminItem := range admin { + adminRule = append(adminRule, adminItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "AdminPrivilegeConfigSet", adminRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBAdminPrivilegeConfigSet) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "AdminPrivilegeConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseAdminPrivilegeConfigSet(log types.Log) (*AutomationRegistryLogicBAdminPrivilegeConfigSet, error) { + event := new(AutomationRegistryLogicBAdminPrivilegeConfigSet) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "AdminPrivilegeConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBCancelledUpkeepReportIterator struct { + Event *AutomationRegistryLogicBCancelledUpkeepReport + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBCancelledUpkeepReportIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBCancelledUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBCancelledUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBCancelledUpkeepReportIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBCancelledUpkeepReportIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBCancelledUpkeepReport struct { + Id *big.Int + Trigger []byte + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterCancelledUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBCancelledUpkeepReportIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "CancelledUpkeepReport", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBCancelledUpkeepReportIterator{contract: _AutomationRegistryLogicB.contract, event: "CancelledUpkeepReport", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchCancelledUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBCancelledUpkeepReport, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "CancelledUpkeepReport", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBCancelledUpkeepReport) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "CancelledUpkeepReport", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseCancelledUpkeepReport(log types.Log) (*AutomationRegistryLogicBCancelledUpkeepReport, error) { + event := new(AutomationRegistryLogicBCancelledUpkeepReport) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "CancelledUpkeepReport", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBChainSpecificModuleUpdatedIterator struct { + Event *AutomationRegistryLogicBChainSpecificModuleUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBChainSpecificModuleUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBChainSpecificModuleUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBChainSpecificModuleUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBChainSpecificModuleUpdatedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBChainSpecificModuleUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBChainSpecificModuleUpdated struct { + NewModule common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterChainSpecificModuleUpdated(opts *bind.FilterOpts) (*AutomationRegistryLogicBChainSpecificModuleUpdatedIterator, error) { + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "ChainSpecificModuleUpdated") + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBChainSpecificModuleUpdatedIterator{contract: _AutomationRegistryLogicB.contract, event: "ChainSpecificModuleUpdated", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchChainSpecificModuleUpdated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBChainSpecificModuleUpdated) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "ChainSpecificModuleUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBChainSpecificModuleUpdated) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "ChainSpecificModuleUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseChainSpecificModuleUpdated(log types.Log) (*AutomationRegistryLogicBChainSpecificModuleUpdated, error) { + event := new(AutomationRegistryLogicBChainSpecificModuleUpdated) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "ChainSpecificModuleUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBDedupKeyAddedIterator struct { + Event *AutomationRegistryLogicBDedupKeyAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBDedupKeyAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBDedupKeyAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBDedupKeyAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBDedupKeyAddedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBDedupKeyAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBDedupKeyAdded struct { + DedupKey [32]byte + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterDedupKeyAdded(opts *bind.FilterOpts, dedupKey [][32]byte) (*AutomationRegistryLogicBDedupKeyAddedIterator, error) { + + var dedupKeyRule []interface{} + for _, dedupKeyItem := range dedupKey { + dedupKeyRule = append(dedupKeyRule, dedupKeyItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "DedupKeyAdded", dedupKeyRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBDedupKeyAddedIterator{contract: _AutomationRegistryLogicB.contract, event: "DedupKeyAdded", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchDedupKeyAdded(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBDedupKeyAdded, dedupKey [][32]byte) (event.Subscription, error) { + + var dedupKeyRule []interface{} + for _, dedupKeyItem := range dedupKey { + dedupKeyRule = append(dedupKeyRule, dedupKeyItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "DedupKeyAdded", dedupKeyRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBDedupKeyAdded) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "DedupKeyAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseDedupKeyAdded(log types.Log) (*AutomationRegistryLogicBDedupKeyAdded, error) { + event := new(AutomationRegistryLogicBDedupKeyAdded) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "DedupKeyAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBFundsAddedIterator struct { + Event *AutomationRegistryLogicBFundsAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBFundsAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBFundsAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBFundsAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBFundsAddedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBFundsAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBFundsAdded struct { + Id *big.Int + From common.Address + Amount *big.Int + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterFundsAdded(opts *bind.FilterOpts, id []*big.Int, from []common.Address) (*AutomationRegistryLogicBFundsAddedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "FundsAdded", idRule, fromRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBFundsAddedIterator{contract: _AutomationRegistryLogicB.contract, event: "FundsAdded", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchFundsAdded(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBFundsAdded, id []*big.Int, from []common.Address) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "FundsAdded", idRule, fromRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBFundsAdded) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "FundsAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseFundsAdded(log types.Log) (*AutomationRegistryLogicBFundsAdded, error) { + event := new(AutomationRegistryLogicBFundsAdded) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "FundsAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBFundsWithdrawnIterator struct { + Event *AutomationRegistryLogicBFundsWithdrawn + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBFundsWithdrawnIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBFundsWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBFundsWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBFundsWithdrawnIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBFundsWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBFundsWithdrawn struct { + Id *big.Int + Amount *big.Int + To common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterFundsWithdrawn(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBFundsWithdrawnIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "FundsWithdrawn", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBFundsWithdrawnIterator{contract: _AutomationRegistryLogicB.contract, event: "FundsWithdrawn", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchFundsWithdrawn(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBFundsWithdrawn, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "FundsWithdrawn", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBFundsWithdrawn) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "FundsWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseFundsWithdrawn(log types.Log) (*AutomationRegistryLogicBFundsWithdrawn, error) { + event := new(AutomationRegistryLogicBFundsWithdrawn) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "FundsWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBInsufficientFundsUpkeepReportIterator struct { + Event *AutomationRegistryLogicBInsufficientFundsUpkeepReport + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBInsufficientFundsUpkeepReportIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBInsufficientFundsUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBInsufficientFundsUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBInsufficientFundsUpkeepReportIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBInsufficientFundsUpkeepReportIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBInsufficientFundsUpkeepReport struct { + Id *big.Int + Trigger []byte + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterInsufficientFundsUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBInsufficientFundsUpkeepReportIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "InsufficientFundsUpkeepReport", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBInsufficientFundsUpkeepReportIterator{contract: _AutomationRegistryLogicB.contract, event: "InsufficientFundsUpkeepReport", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchInsufficientFundsUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBInsufficientFundsUpkeepReport, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "InsufficientFundsUpkeepReport", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBInsufficientFundsUpkeepReport) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "InsufficientFundsUpkeepReport", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseInsufficientFundsUpkeepReport(log types.Log) (*AutomationRegistryLogicBInsufficientFundsUpkeepReport, error) { + event := new(AutomationRegistryLogicBInsufficientFundsUpkeepReport) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "InsufficientFundsUpkeepReport", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBOwnerFundsWithdrawnIterator struct { + Event *AutomationRegistryLogicBOwnerFundsWithdrawn + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBOwnerFundsWithdrawnIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBOwnerFundsWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBOwnerFundsWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBOwnerFundsWithdrawnIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBOwnerFundsWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBOwnerFundsWithdrawn struct { + Amount *big.Int + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterOwnerFundsWithdrawn(opts *bind.FilterOpts) (*AutomationRegistryLogicBOwnerFundsWithdrawnIterator, error) { + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "OwnerFundsWithdrawn") + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBOwnerFundsWithdrawnIterator{contract: _AutomationRegistryLogicB.contract, event: "OwnerFundsWithdrawn", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchOwnerFundsWithdrawn(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBOwnerFundsWithdrawn) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "OwnerFundsWithdrawn") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBOwnerFundsWithdrawn) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "OwnerFundsWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseOwnerFundsWithdrawn(log types.Log) (*AutomationRegistryLogicBOwnerFundsWithdrawn, error) { + event := new(AutomationRegistryLogicBOwnerFundsWithdrawn) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "OwnerFundsWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBOwnershipTransferRequestedIterator struct { + Event *AutomationRegistryLogicBOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*AutomationRegistryLogicBOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBOwnershipTransferRequestedIterator{contract: _AutomationRegistryLogicB.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBOwnershipTransferRequested) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseOwnershipTransferRequested(log types.Log) (*AutomationRegistryLogicBOwnershipTransferRequested, error) { + event := new(AutomationRegistryLogicBOwnershipTransferRequested) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBOwnershipTransferredIterator struct { + Event *AutomationRegistryLogicBOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*AutomationRegistryLogicBOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBOwnershipTransferredIterator{contract: _AutomationRegistryLogicB.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBOwnershipTransferred) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseOwnershipTransferred(log types.Log) (*AutomationRegistryLogicBOwnershipTransferred, error) { + event := new(AutomationRegistryLogicBOwnershipTransferred) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBPausedIterator struct { + Event *AutomationRegistryLogicBPaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBPausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBPausedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBPaused struct { + Account common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterPaused(opts *bind.FilterOpts) (*AutomationRegistryLogicBPausedIterator, error) { + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBPausedIterator{contract: _AutomationRegistryLogicB.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBPaused) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "Paused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBPaused) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "Paused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParsePaused(log types.Log) (*AutomationRegistryLogicBPaused, error) { + event := new(AutomationRegistryLogicBPaused) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBPayeesUpdatedIterator struct { + Event *AutomationRegistryLogicBPayeesUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBPayeesUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBPayeesUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBPayeesUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBPayeesUpdatedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBPayeesUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBPayeesUpdated struct { + Transmitters []common.Address + Payees []common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterPayeesUpdated(opts *bind.FilterOpts) (*AutomationRegistryLogicBPayeesUpdatedIterator, error) { + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "PayeesUpdated") + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBPayeesUpdatedIterator{contract: _AutomationRegistryLogicB.contract, event: "PayeesUpdated", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchPayeesUpdated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBPayeesUpdated) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "PayeesUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBPayeesUpdated) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "PayeesUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParsePayeesUpdated(log types.Log) (*AutomationRegistryLogicBPayeesUpdated, error) { + event := new(AutomationRegistryLogicBPayeesUpdated) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "PayeesUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBPayeeshipTransferRequestedIterator struct { + Event *AutomationRegistryLogicBPayeeshipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBPayeeshipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBPayeeshipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBPayeeshipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBPayeeshipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBPayeeshipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBPayeeshipTransferRequested struct { + Transmitter common.Address + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterPayeeshipTransferRequested(opts *bind.FilterOpts, transmitter []common.Address, from []common.Address, to []common.Address) (*AutomationRegistryLogicBPayeeshipTransferRequestedIterator, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "PayeeshipTransferRequested", transmitterRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBPayeeshipTransferRequestedIterator{contract: _AutomationRegistryLogicB.contract, event: "PayeeshipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchPayeeshipTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBPayeeshipTransferRequested, transmitter []common.Address, from []common.Address, to []common.Address) (event.Subscription, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "PayeeshipTransferRequested", transmitterRule, fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBPayeeshipTransferRequested) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "PayeeshipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParsePayeeshipTransferRequested(log types.Log) (*AutomationRegistryLogicBPayeeshipTransferRequested, error) { + event := new(AutomationRegistryLogicBPayeeshipTransferRequested) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "PayeeshipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBPayeeshipTransferredIterator struct { + Event *AutomationRegistryLogicBPayeeshipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBPayeeshipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBPayeeshipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBPayeeshipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBPayeeshipTransferredIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBPayeeshipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBPayeeshipTransferred struct { + Transmitter common.Address + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterPayeeshipTransferred(opts *bind.FilterOpts, transmitter []common.Address, from []common.Address, to []common.Address) (*AutomationRegistryLogicBPayeeshipTransferredIterator, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "PayeeshipTransferred", transmitterRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBPayeeshipTransferredIterator{contract: _AutomationRegistryLogicB.contract, event: "PayeeshipTransferred", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchPayeeshipTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBPayeeshipTransferred, transmitter []common.Address, from []common.Address, to []common.Address) (event.Subscription, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "PayeeshipTransferred", transmitterRule, fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBPayeeshipTransferred) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "PayeeshipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParsePayeeshipTransferred(log types.Log) (*AutomationRegistryLogicBPayeeshipTransferred, error) { + event := new(AutomationRegistryLogicBPayeeshipTransferred) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "PayeeshipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBPaymentWithdrawnIterator struct { + Event *AutomationRegistryLogicBPaymentWithdrawn + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBPaymentWithdrawnIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBPaymentWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBPaymentWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBPaymentWithdrawnIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBPaymentWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBPaymentWithdrawn struct { + Transmitter common.Address + Amount *big.Int + To common.Address + Payee common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterPaymentWithdrawn(opts *bind.FilterOpts, transmitter []common.Address, amount []*big.Int, to []common.Address) (*AutomationRegistryLogicBPaymentWithdrawnIterator, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "PaymentWithdrawn", transmitterRule, amountRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBPaymentWithdrawnIterator{contract: _AutomationRegistryLogicB.contract, event: "PaymentWithdrawn", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchPaymentWithdrawn(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBPaymentWithdrawn, transmitter []common.Address, amount []*big.Int, to []common.Address) (event.Subscription, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "PaymentWithdrawn", transmitterRule, amountRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBPaymentWithdrawn) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "PaymentWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParsePaymentWithdrawn(log types.Log) (*AutomationRegistryLogicBPaymentWithdrawn, error) { + event := new(AutomationRegistryLogicBPaymentWithdrawn) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "PaymentWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBReorgedUpkeepReportIterator struct { + Event *AutomationRegistryLogicBReorgedUpkeepReport + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBReorgedUpkeepReportIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBReorgedUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBReorgedUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBReorgedUpkeepReportIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBReorgedUpkeepReportIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBReorgedUpkeepReport struct { + Id *big.Int + Trigger []byte + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterReorgedUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBReorgedUpkeepReportIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "ReorgedUpkeepReport", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBReorgedUpkeepReportIterator{contract: _AutomationRegistryLogicB.contract, event: "ReorgedUpkeepReport", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchReorgedUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBReorgedUpkeepReport, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "ReorgedUpkeepReport", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBReorgedUpkeepReport) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "ReorgedUpkeepReport", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseReorgedUpkeepReport(log types.Log) (*AutomationRegistryLogicBReorgedUpkeepReport, error) { + event := new(AutomationRegistryLogicBReorgedUpkeepReport) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "ReorgedUpkeepReport", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBStaleUpkeepReportIterator struct { + Event *AutomationRegistryLogicBStaleUpkeepReport + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBStaleUpkeepReportIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBStaleUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBStaleUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBStaleUpkeepReportIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBStaleUpkeepReportIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBStaleUpkeepReport struct { + Id *big.Int + Trigger []byte + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterStaleUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBStaleUpkeepReportIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "StaleUpkeepReport", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBStaleUpkeepReportIterator{contract: _AutomationRegistryLogicB.contract, event: "StaleUpkeepReport", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchStaleUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBStaleUpkeepReport, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "StaleUpkeepReport", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBStaleUpkeepReport) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "StaleUpkeepReport", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseStaleUpkeepReport(log types.Log) (*AutomationRegistryLogicBStaleUpkeepReport, error) { + event := new(AutomationRegistryLogicBStaleUpkeepReport) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "StaleUpkeepReport", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBUnpausedIterator struct { + Event *AutomationRegistryLogicBUnpaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBUnpausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBUnpausedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBUnpaused struct { + Account common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterUnpaused(opts *bind.FilterOpts) (*AutomationRegistryLogicBUnpausedIterator, error) { + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBUnpausedIterator{contract: _AutomationRegistryLogicB.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUnpaused) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBUnpaused) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "Unpaused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseUnpaused(log types.Log) (*AutomationRegistryLogicBUnpaused, error) { + event := new(AutomationRegistryLogicBUnpaused) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBUpkeepAdminTransferRequestedIterator struct { + Event *AutomationRegistryLogicBUpkeepAdminTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBUpkeepAdminTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepAdminTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepAdminTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBUpkeepAdminTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBUpkeepAdminTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBUpkeepAdminTransferRequested struct { + Id *big.Int + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterUpkeepAdminTransferRequested(opts *bind.FilterOpts, id []*big.Int, from []common.Address, to []common.Address) (*AutomationRegistryLogicBUpkeepAdminTransferRequestedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "UpkeepAdminTransferRequested", idRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBUpkeepAdminTransferRequestedIterator{contract: _AutomationRegistryLogicB.contract, event: "UpkeepAdminTransferRequested", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchUpkeepAdminTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepAdminTransferRequested, id []*big.Int, from []common.Address, to []common.Address) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "UpkeepAdminTransferRequested", idRule, fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBUpkeepAdminTransferRequested) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepAdminTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseUpkeepAdminTransferRequested(log types.Log) (*AutomationRegistryLogicBUpkeepAdminTransferRequested, error) { + event := new(AutomationRegistryLogicBUpkeepAdminTransferRequested) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepAdminTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBUpkeepAdminTransferredIterator struct { + Event *AutomationRegistryLogicBUpkeepAdminTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBUpkeepAdminTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepAdminTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepAdminTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBUpkeepAdminTransferredIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBUpkeepAdminTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBUpkeepAdminTransferred struct { + Id *big.Int + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterUpkeepAdminTransferred(opts *bind.FilterOpts, id []*big.Int, from []common.Address, to []common.Address) (*AutomationRegistryLogicBUpkeepAdminTransferredIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "UpkeepAdminTransferred", idRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBUpkeepAdminTransferredIterator{contract: _AutomationRegistryLogicB.contract, event: "UpkeepAdminTransferred", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchUpkeepAdminTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepAdminTransferred, id []*big.Int, from []common.Address, to []common.Address) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "UpkeepAdminTransferred", idRule, fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBUpkeepAdminTransferred) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepAdminTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseUpkeepAdminTransferred(log types.Log) (*AutomationRegistryLogicBUpkeepAdminTransferred, error) { + event := new(AutomationRegistryLogicBUpkeepAdminTransferred) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepAdminTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBUpkeepCanceledIterator struct { + Event *AutomationRegistryLogicBUpkeepCanceled + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBUpkeepCanceledIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepCanceled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepCanceled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBUpkeepCanceledIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBUpkeepCanceledIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBUpkeepCanceled struct { + Id *big.Int + AtBlockHeight uint64 + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterUpkeepCanceled(opts *bind.FilterOpts, id []*big.Int, atBlockHeight []uint64) (*AutomationRegistryLogicBUpkeepCanceledIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var atBlockHeightRule []interface{} + for _, atBlockHeightItem := range atBlockHeight { + atBlockHeightRule = append(atBlockHeightRule, atBlockHeightItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "UpkeepCanceled", idRule, atBlockHeightRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBUpkeepCanceledIterator{contract: _AutomationRegistryLogicB.contract, event: "UpkeepCanceled", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchUpkeepCanceled(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepCanceled, id []*big.Int, atBlockHeight []uint64) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var atBlockHeightRule []interface{} + for _, atBlockHeightItem := range atBlockHeight { + atBlockHeightRule = append(atBlockHeightRule, atBlockHeightItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "UpkeepCanceled", idRule, atBlockHeightRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBUpkeepCanceled) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepCanceled", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseUpkeepCanceled(log types.Log) (*AutomationRegistryLogicBUpkeepCanceled, error) { + event := new(AutomationRegistryLogicBUpkeepCanceled) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepCanceled", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBUpkeepCheckDataSetIterator struct { + Event *AutomationRegistryLogicBUpkeepCheckDataSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBUpkeepCheckDataSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepCheckDataSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepCheckDataSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBUpkeepCheckDataSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBUpkeepCheckDataSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBUpkeepCheckDataSet struct { + Id *big.Int + NewCheckData []byte + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterUpkeepCheckDataSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBUpkeepCheckDataSetIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "UpkeepCheckDataSet", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBUpkeepCheckDataSetIterator{contract: _AutomationRegistryLogicB.contract, event: "UpkeepCheckDataSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchUpkeepCheckDataSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepCheckDataSet, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "UpkeepCheckDataSet", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBUpkeepCheckDataSet) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepCheckDataSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseUpkeepCheckDataSet(log types.Log) (*AutomationRegistryLogicBUpkeepCheckDataSet, error) { + event := new(AutomationRegistryLogicBUpkeepCheckDataSet) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepCheckDataSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBUpkeepGasLimitSetIterator struct { + Event *AutomationRegistryLogicBUpkeepGasLimitSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBUpkeepGasLimitSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepGasLimitSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepGasLimitSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBUpkeepGasLimitSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBUpkeepGasLimitSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBUpkeepGasLimitSet struct { + Id *big.Int + GasLimit *big.Int + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterUpkeepGasLimitSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBUpkeepGasLimitSetIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "UpkeepGasLimitSet", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBUpkeepGasLimitSetIterator{contract: _AutomationRegistryLogicB.contract, event: "UpkeepGasLimitSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchUpkeepGasLimitSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepGasLimitSet, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "UpkeepGasLimitSet", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBUpkeepGasLimitSet) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepGasLimitSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseUpkeepGasLimitSet(log types.Log) (*AutomationRegistryLogicBUpkeepGasLimitSet, error) { + event := new(AutomationRegistryLogicBUpkeepGasLimitSet) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepGasLimitSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBUpkeepMigratedIterator struct { + Event *AutomationRegistryLogicBUpkeepMigrated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBUpkeepMigratedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepMigrated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepMigrated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBUpkeepMigratedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBUpkeepMigratedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBUpkeepMigrated struct { + Id *big.Int + RemainingBalance *big.Int + Destination common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterUpkeepMigrated(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBUpkeepMigratedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "UpkeepMigrated", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBUpkeepMigratedIterator{contract: _AutomationRegistryLogicB.contract, event: "UpkeepMigrated", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchUpkeepMigrated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepMigrated, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "UpkeepMigrated", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBUpkeepMigrated) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepMigrated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseUpkeepMigrated(log types.Log) (*AutomationRegistryLogicBUpkeepMigrated, error) { + event := new(AutomationRegistryLogicBUpkeepMigrated) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepMigrated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBUpkeepOffchainConfigSetIterator struct { + Event *AutomationRegistryLogicBUpkeepOffchainConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBUpkeepOffchainConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepOffchainConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepOffchainConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBUpkeepOffchainConfigSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBUpkeepOffchainConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBUpkeepOffchainConfigSet struct { + Id *big.Int + OffchainConfig []byte + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterUpkeepOffchainConfigSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBUpkeepOffchainConfigSetIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "UpkeepOffchainConfigSet", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBUpkeepOffchainConfigSetIterator{contract: _AutomationRegistryLogicB.contract, event: "UpkeepOffchainConfigSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchUpkeepOffchainConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepOffchainConfigSet, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "UpkeepOffchainConfigSet", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBUpkeepOffchainConfigSet) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepOffchainConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseUpkeepOffchainConfigSet(log types.Log) (*AutomationRegistryLogicBUpkeepOffchainConfigSet, error) { + event := new(AutomationRegistryLogicBUpkeepOffchainConfigSet) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepOffchainConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBUpkeepPausedIterator struct { + Event *AutomationRegistryLogicBUpkeepPaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBUpkeepPausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBUpkeepPausedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBUpkeepPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBUpkeepPaused struct { + Id *big.Int + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterUpkeepPaused(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBUpkeepPausedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "UpkeepPaused", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBUpkeepPausedIterator{contract: _AutomationRegistryLogicB.contract, event: "UpkeepPaused", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchUpkeepPaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepPaused, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "UpkeepPaused", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBUpkeepPaused) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepPaused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseUpkeepPaused(log types.Log) (*AutomationRegistryLogicBUpkeepPaused, error) { + event := new(AutomationRegistryLogicBUpkeepPaused) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepPaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBUpkeepPerformedIterator struct { + Event *AutomationRegistryLogicBUpkeepPerformed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBUpkeepPerformedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepPerformed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepPerformed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBUpkeepPerformedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBUpkeepPerformedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBUpkeepPerformed struct { + Id *big.Int + Success bool + TotalPayment *big.Int + GasUsed *big.Int + GasOverhead *big.Int + Trigger []byte + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterUpkeepPerformed(opts *bind.FilterOpts, id []*big.Int, success []bool) (*AutomationRegistryLogicBUpkeepPerformedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var successRule []interface{} + for _, successItem := range success { + successRule = append(successRule, successItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "UpkeepPerformed", idRule, successRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBUpkeepPerformedIterator{contract: _AutomationRegistryLogicB.contract, event: "UpkeepPerformed", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchUpkeepPerformed(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepPerformed, id []*big.Int, success []bool) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var successRule []interface{} + for _, successItem := range success { + successRule = append(successRule, successItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "UpkeepPerformed", idRule, successRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBUpkeepPerformed) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepPerformed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseUpkeepPerformed(log types.Log) (*AutomationRegistryLogicBUpkeepPerformed, error) { + event := new(AutomationRegistryLogicBUpkeepPerformed) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepPerformed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBUpkeepPrivilegeConfigSetIterator struct { + Event *AutomationRegistryLogicBUpkeepPrivilegeConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBUpkeepPrivilegeConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepPrivilegeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepPrivilegeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBUpkeepPrivilegeConfigSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBUpkeepPrivilegeConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBUpkeepPrivilegeConfigSet struct { + Id *big.Int + PrivilegeConfig []byte + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterUpkeepPrivilegeConfigSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBUpkeepPrivilegeConfigSetIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "UpkeepPrivilegeConfigSet", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBUpkeepPrivilegeConfigSetIterator{contract: _AutomationRegistryLogicB.contract, event: "UpkeepPrivilegeConfigSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchUpkeepPrivilegeConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepPrivilegeConfigSet, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "UpkeepPrivilegeConfigSet", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBUpkeepPrivilegeConfigSet) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepPrivilegeConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseUpkeepPrivilegeConfigSet(log types.Log) (*AutomationRegistryLogicBUpkeepPrivilegeConfigSet, error) { + event := new(AutomationRegistryLogicBUpkeepPrivilegeConfigSet) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepPrivilegeConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBUpkeepReceivedIterator struct { + Event *AutomationRegistryLogicBUpkeepReceived + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBUpkeepReceivedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBUpkeepReceivedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBUpkeepReceivedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBUpkeepReceived struct { + Id *big.Int + StartingBalance *big.Int + ImportedFrom common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterUpkeepReceived(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBUpkeepReceivedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "UpkeepReceived", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBUpkeepReceivedIterator{contract: _AutomationRegistryLogicB.contract, event: "UpkeepReceived", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchUpkeepReceived(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepReceived, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "UpkeepReceived", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBUpkeepReceived) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepReceived", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseUpkeepReceived(log types.Log) (*AutomationRegistryLogicBUpkeepReceived, error) { + event := new(AutomationRegistryLogicBUpkeepReceived) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepReceived", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBUpkeepRegisteredIterator struct { + Event *AutomationRegistryLogicBUpkeepRegistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBUpkeepRegisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBUpkeepRegisteredIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBUpkeepRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBUpkeepRegistered struct { + Id *big.Int + PerformGas uint32 + Admin common.Address + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterUpkeepRegistered(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBUpkeepRegisteredIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "UpkeepRegistered", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBUpkeepRegisteredIterator{contract: _AutomationRegistryLogicB.contract, event: "UpkeepRegistered", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchUpkeepRegistered(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepRegistered, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "UpkeepRegistered", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBUpkeepRegistered) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseUpkeepRegistered(log types.Log) (*AutomationRegistryLogicBUpkeepRegistered, error) { + event := new(AutomationRegistryLogicBUpkeepRegistered) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBUpkeepTriggerConfigSetIterator struct { + Event *AutomationRegistryLogicBUpkeepTriggerConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBUpkeepTriggerConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepTriggerConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepTriggerConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBUpkeepTriggerConfigSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBUpkeepTriggerConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBUpkeepTriggerConfigSet struct { + Id *big.Int + TriggerConfig []byte + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterUpkeepTriggerConfigSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBUpkeepTriggerConfigSetIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "UpkeepTriggerConfigSet", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBUpkeepTriggerConfigSetIterator{contract: _AutomationRegistryLogicB.contract, event: "UpkeepTriggerConfigSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchUpkeepTriggerConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepTriggerConfigSet, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "UpkeepTriggerConfigSet", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBUpkeepTriggerConfigSet) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepTriggerConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseUpkeepTriggerConfigSet(log types.Log) (*AutomationRegistryLogicBUpkeepTriggerConfigSet, error) { + event := new(AutomationRegistryLogicBUpkeepTriggerConfigSet) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepTriggerConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryLogicBUpkeepUnpausedIterator struct { + Event *AutomationRegistryLogicBUpkeepUnpaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryLogicBUpkeepUnpausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryLogicBUpkeepUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryLogicBUpkeepUnpausedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryLogicBUpkeepUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryLogicBUpkeepUnpaused struct { + Id *big.Int + Raw types.Log +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) FilterUpkeepUnpaused(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBUpkeepUnpausedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.FilterLogs(opts, "UpkeepUnpaused", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryLogicBUpkeepUnpausedIterator{contract: _AutomationRegistryLogicB.contract, event: "UpkeepUnpaused", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) WatchUpkeepUnpaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepUnpaused, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistryLogicB.contract.WatchLogs(opts, "UpkeepUnpaused", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryLogicBUpkeepUnpaused) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepUnpaused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicBFilterer) ParseUpkeepUnpaused(log types.Log) (*AutomationRegistryLogicBUpkeepUnpaused, error) { + event := new(AutomationRegistryLogicBUpkeepUnpaused) + if err := _AutomationRegistryLogicB.contract.UnpackLog(event, "UpkeepUnpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetSignerInfo struct { + Active bool + Index uint8 +} +type GetState struct { + State AutomationRegistryBase23State + Config AutomationRegistryBase23OnchainConfigLegacy + Signers []common.Address + Transmitters []common.Address + F uint8 +} +type GetTransmitterInfo struct { + Active bool + Index uint8 + Balance *big.Int + LastCollected *big.Int + Payee common.Address +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicB) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _AutomationRegistryLogicB.abi.Events["AdminPrivilegeConfigSet"].ID: + return _AutomationRegistryLogicB.ParseAdminPrivilegeConfigSet(log) + case _AutomationRegistryLogicB.abi.Events["CancelledUpkeepReport"].ID: + return _AutomationRegistryLogicB.ParseCancelledUpkeepReport(log) + case _AutomationRegistryLogicB.abi.Events["ChainSpecificModuleUpdated"].ID: + return _AutomationRegistryLogicB.ParseChainSpecificModuleUpdated(log) + case _AutomationRegistryLogicB.abi.Events["DedupKeyAdded"].ID: + return _AutomationRegistryLogicB.ParseDedupKeyAdded(log) + case _AutomationRegistryLogicB.abi.Events["FundsAdded"].ID: + return _AutomationRegistryLogicB.ParseFundsAdded(log) + case _AutomationRegistryLogicB.abi.Events["FundsWithdrawn"].ID: + return _AutomationRegistryLogicB.ParseFundsWithdrawn(log) + case _AutomationRegistryLogicB.abi.Events["InsufficientFundsUpkeepReport"].ID: + return _AutomationRegistryLogicB.ParseInsufficientFundsUpkeepReport(log) + case _AutomationRegistryLogicB.abi.Events["OwnerFundsWithdrawn"].ID: + return _AutomationRegistryLogicB.ParseOwnerFundsWithdrawn(log) + case _AutomationRegistryLogicB.abi.Events["OwnershipTransferRequested"].ID: + return _AutomationRegistryLogicB.ParseOwnershipTransferRequested(log) + case _AutomationRegistryLogicB.abi.Events["OwnershipTransferred"].ID: + return _AutomationRegistryLogicB.ParseOwnershipTransferred(log) + case _AutomationRegistryLogicB.abi.Events["Paused"].ID: + return _AutomationRegistryLogicB.ParsePaused(log) + case _AutomationRegistryLogicB.abi.Events["PayeesUpdated"].ID: + return _AutomationRegistryLogicB.ParsePayeesUpdated(log) + case _AutomationRegistryLogicB.abi.Events["PayeeshipTransferRequested"].ID: + return _AutomationRegistryLogicB.ParsePayeeshipTransferRequested(log) + case _AutomationRegistryLogicB.abi.Events["PayeeshipTransferred"].ID: + return _AutomationRegistryLogicB.ParsePayeeshipTransferred(log) + case _AutomationRegistryLogicB.abi.Events["PaymentWithdrawn"].ID: + return _AutomationRegistryLogicB.ParsePaymentWithdrawn(log) + case _AutomationRegistryLogicB.abi.Events["ReorgedUpkeepReport"].ID: + return _AutomationRegistryLogicB.ParseReorgedUpkeepReport(log) + case _AutomationRegistryLogicB.abi.Events["StaleUpkeepReport"].ID: + return _AutomationRegistryLogicB.ParseStaleUpkeepReport(log) + case _AutomationRegistryLogicB.abi.Events["Unpaused"].ID: + return _AutomationRegistryLogicB.ParseUnpaused(log) + case _AutomationRegistryLogicB.abi.Events["UpkeepAdminTransferRequested"].ID: + return _AutomationRegistryLogicB.ParseUpkeepAdminTransferRequested(log) + case _AutomationRegistryLogicB.abi.Events["UpkeepAdminTransferred"].ID: + return _AutomationRegistryLogicB.ParseUpkeepAdminTransferred(log) + case _AutomationRegistryLogicB.abi.Events["UpkeepCanceled"].ID: + return _AutomationRegistryLogicB.ParseUpkeepCanceled(log) + case _AutomationRegistryLogicB.abi.Events["UpkeepCheckDataSet"].ID: + return _AutomationRegistryLogicB.ParseUpkeepCheckDataSet(log) + case _AutomationRegistryLogicB.abi.Events["UpkeepGasLimitSet"].ID: + return _AutomationRegistryLogicB.ParseUpkeepGasLimitSet(log) + case _AutomationRegistryLogicB.abi.Events["UpkeepMigrated"].ID: + return _AutomationRegistryLogicB.ParseUpkeepMigrated(log) + case _AutomationRegistryLogicB.abi.Events["UpkeepOffchainConfigSet"].ID: + return _AutomationRegistryLogicB.ParseUpkeepOffchainConfigSet(log) + case _AutomationRegistryLogicB.abi.Events["UpkeepPaused"].ID: + return _AutomationRegistryLogicB.ParseUpkeepPaused(log) + case _AutomationRegistryLogicB.abi.Events["UpkeepPerformed"].ID: + return _AutomationRegistryLogicB.ParseUpkeepPerformed(log) + case _AutomationRegistryLogicB.abi.Events["UpkeepPrivilegeConfigSet"].ID: + return _AutomationRegistryLogicB.ParseUpkeepPrivilegeConfigSet(log) + case _AutomationRegistryLogicB.abi.Events["UpkeepReceived"].ID: + return _AutomationRegistryLogicB.ParseUpkeepReceived(log) + case _AutomationRegistryLogicB.abi.Events["UpkeepRegistered"].ID: + return _AutomationRegistryLogicB.ParseUpkeepRegistered(log) + case _AutomationRegistryLogicB.abi.Events["UpkeepTriggerConfigSet"].ID: + return _AutomationRegistryLogicB.ParseUpkeepTriggerConfigSet(log) + case _AutomationRegistryLogicB.abi.Events["UpkeepUnpaused"].ID: + return _AutomationRegistryLogicB.ParseUpkeepUnpaused(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (AutomationRegistryLogicBAdminPrivilegeConfigSet) Topic() common.Hash { + return common.HexToHash("0x7c44b4eb59ee7873514e7e43e7718c269d872965938b288aa143befca62f99d2") +} + +func (AutomationRegistryLogicBCancelledUpkeepReport) Topic() common.Hash { + return common.HexToHash("0xc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636") +} + +func (AutomationRegistryLogicBChainSpecificModuleUpdated) Topic() common.Hash { + return common.HexToHash("0xdefc28b11a7980dbe0c49dbbd7055a1584bc8075097d1e8b3b57fb7283df2ad7") +} + +func (AutomationRegistryLogicBDedupKeyAdded) Topic() common.Hash { + return common.HexToHash("0xa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f2") +} + +func (AutomationRegistryLogicBFundsAdded) Topic() common.Hash { + return common.HexToHash("0xafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa734891506203") +} + +func (AutomationRegistryLogicBFundsWithdrawn) Topic() common.Hash { + return common.HexToHash("0xf3b5906e5672f3e524854103bcafbbdba80dbdfeca2c35e116127b1060a68318") +} + +func (AutomationRegistryLogicBInsufficientFundsUpkeepReport) Topic() common.Hash { + return common.HexToHash("0x377c8b0c126ae5248d27aca1c76fac4608aff85673ee3caf09747e1044549e02") +} + +func (AutomationRegistryLogicBOwnerFundsWithdrawn) Topic() common.Hash { + return common.HexToHash("0x1d07d0b0be43d3e5fee41a80b579af370affee03fa595bf56d5d4c19328162f1") +} + +func (AutomationRegistryLogicBOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (AutomationRegistryLogicBOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (AutomationRegistryLogicBPaused) Topic() common.Hash { + return common.HexToHash("0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258") +} + +func (AutomationRegistryLogicBPayeesUpdated) Topic() common.Hash { + return common.HexToHash("0xa46de38886467c59be07a0675f14781206a5477d871628af46c2443822fcb725") +} + +func (AutomationRegistryLogicBPayeeshipTransferRequested) Topic() common.Hash { + return common.HexToHash("0x84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e38367") +} + +func (AutomationRegistryLogicBPayeeshipTransferred) Topic() common.Hash { + return common.HexToHash("0x78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b3") +} + +func (AutomationRegistryLogicBPaymentWithdrawn) Topic() common.Hash { + return common.HexToHash("0x9819093176a1851202c7bcfa46845809b4e47c261866550e94ed3775d2f40698") +} + +func (AutomationRegistryLogicBReorgedUpkeepReport) Topic() common.Hash { + return common.HexToHash("0x6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301") +} + +func (AutomationRegistryLogicBStaleUpkeepReport) Topic() common.Hash { + return common.HexToHash("0x405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8") +} + +func (AutomationRegistryLogicBUnpaused) Topic() common.Hash { + return common.HexToHash("0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa") +} + +func (AutomationRegistryLogicBUpkeepAdminTransferRequested) Topic() common.Hash { + return common.HexToHash("0xb1cbb2c4b8480034c27e06da5f096b8233a8fd4497028593a41ff6df79726b35") +} + +func (AutomationRegistryLogicBUpkeepAdminTransferred) Topic() common.Hash { + return common.HexToHash("0x5cff4db96bef051785e999f44bfcd21c18823e034fb92dd376e3db4ce0feeb2c") +} + +func (AutomationRegistryLogicBUpkeepCanceled) Topic() common.Hash { + return common.HexToHash("0x91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f791181") +} + +func (AutomationRegistryLogicBUpkeepCheckDataSet) Topic() common.Hash { + return common.HexToHash("0xcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d") +} + +func (AutomationRegistryLogicBUpkeepGasLimitSet) Topic() common.Hash { + return common.HexToHash("0xc24c07e655ce79fba8a589778987d3c015bc6af1632bb20cf9182e02a65d972c") +} + +func (AutomationRegistryLogicBUpkeepMigrated) Topic() common.Hash { + return common.HexToHash("0xb38647142fbb1ea4c000fc4569b37a4e9a9f6313317b84ee3e5326c1a6cd06ff") +} + +func (AutomationRegistryLogicBUpkeepOffchainConfigSet) Topic() common.Hash { + return common.HexToHash("0x3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf4850") +} + +func (AutomationRegistryLogicBUpkeepPaused) Topic() common.Hash { + return common.HexToHash("0x8ab10247ce168c27748e656ecf852b951fcaac790c18106b19aa0ae57a8b741f") +} + +func (AutomationRegistryLogicBUpkeepPerformed) Topic() common.Hash { + return common.HexToHash("0xad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b") +} + +func (AutomationRegistryLogicBUpkeepPrivilegeConfigSet) Topic() common.Hash { + return common.HexToHash("0x2fd8d70753a007014349d4591843cc031c2dd7a260d7dd82eca8253686ae7769") +} + +func (AutomationRegistryLogicBUpkeepReceived) Topic() common.Hash { + return common.HexToHash("0x74931a144e43a50694897f241d973aecb5024c0e910f9bb80a163ea3c1cf5a71") +} + +func (AutomationRegistryLogicBUpkeepRegistered) Topic() common.Hash { + return common.HexToHash("0xbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d012") +} + +func (AutomationRegistryLogicBUpkeepTriggerConfigSet) Topic() common.Hash { + return common.HexToHash("0x2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d5664") +} + +func (AutomationRegistryLogicBUpkeepUnpaused) Topic() common.Hash { + return common.HexToHash("0x7bada562044eb163f6b4003c4553e4e62825344c0418eea087bed5ee05a47456") +} + +func (_AutomationRegistryLogicB *AutomationRegistryLogicB) Address() common.Address { + return _AutomationRegistryLogicB.address +} + +type AutomationRegistryLogicBInterface interface { + GetActiveUpkeepIDs(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) + + GetAdminPrivilegeConfig(opts *bind.CallOpts, admin common.Address) ([]byte, error) + + GetAllowedReadOnlyAddress(opts *bind.CallOpts) (common.Address, error) + + GetAutomationForwarderLogic(opts *bind.CallOpts) (common.Address, error) + + GetBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error) + + GetCancellationDelay(opts *bind.CallOpts) (*big.Int, error) + + GetChainModule(opts *bind.CallOpts) (common.Address, error) + + GetConditionalGasOverhead(opts *bind.CallOpts) (*big.Int, error) + + GetFastGasFeedAddress(opts *bind.CallOpts) (common.Address, error) + + GetForwarder(opts *bind.CallOpts, upkeepID *big.Int) (common.Address, error) + + GetLinkAddress(opts *bind.CallOpts) (common.Address, error) + + GetLinkNativeFeedAddress(opts *bind.CallOpts) (common.Address, error) + + GetLogGasOverhead(opts *bind.CallOpts) (*big.Int, error) + + GetMaxPaymentForGas(opts *bind.CallOpts, triggerType uint8, gasLimit uint32) (*big.Int, error) + + GetMinBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error) + + GetMinBalanceForUpkeep(opts *bind.CallOpts, id *big.Int) (*big.Int, error) + + GetPeerRegistryMigrationPermission(opts *bind.CallOpts, peer common.Address) (uint8, error) + + GetPerPerformByteGasOverhead(opts *bind.CallOpts) (*big.Int, error) + + GetPerSignerGasOverhead(opts *bind.CallOpts) (*big.Int, error) + + GetReorgProtectionEnabled(opts *bind.CallOpts) (bool, error) + + GetSignerInfo(opts *bind.CallOpts, query common.Address) (GetSignerInfo, + + error) + + GetState(opts *bind.CallOpts) (GetState, + + error) + + GetTransmitCalldataFixedBytesOverhead(opts *bind.CallOpts) (*big.Int, error) + + GetTransmitCalldataPerSignerBytesOverhead(opts *bind.CallOpts) (*big.Int, error) + + GetTransmitterInfo(opts *bind.CallOpts, query common.Address) (GetTransmitterInfo, + + error) + + GetTriggerType(opts *bind.CallOpts, upkeepId *big.Int) (uint8, error) + + GetUpkeep(opts *bind.CallOpts, id *big.Int) (AutomationRegistryBase23UpkeepInfo, error) + + GetUpkeepPrivilegeConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) + + GetUpkeepTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) + + HasDedupKey(opts *bind.CallOpts, dedupKey [32]byte) (bool, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + UpkeepTranscoderVersion(opts *bind.CallOpts) (uint8, error) + + UpkeepVersion(opts *bind.CallOpts) (uint8, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + AcceptPayeeship(opts *bind.TransactOpts, transmitter common.Address) (*types.Transaction, error) + + AcceptUpkeepAdmin(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) + + Pause(opts *bind.TransactOpts) (*types.Transaction, error) + + PauseUpkeep(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) + + RecoverFunds(opts *bind.TransactOpts) (*types.Transaction, error) + + SetAdminPrivilegeConfig(opts *bind.TransactOpts, admin common.Address, newPrivilegeConfig []byte) (*types.Transaction, error) + + SetPayees(opts *bind.TransactOpts, payees []common.Address) (*types.Transaction, error) + + SetPeerRegistryMigrationPermission(opts *bind.TransactOpts, peer common.Address, permission uint8) (*types.Transaction, error) + + SetUpkeepCheckData(opts *bind.TransactOpts, id *big.Int, newCheckData []byte) (*types.Transaction, error) + + SetUpkeepGasLimit(opts *bind.TransactOpts, id *big.Int, gasLimit uint32) (*types.Transaction, error) + + SetUpkeepOffchainConfig(opts *bind.TransactOpts, id *big.Int, config []byte) (*types.Transaction, error) + + SetUpkeepPrivilegeConfig(opts *bind.TransactOpts, upkeepId *big.Int, newPrivilegeConfig []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + TransferPayeeship(opts *bind.TransactOpts, transmitter common.Address, proposed common.Address) (*types.Transaction, error) + + TransferUpkeepAdmin(opts *bind.TransactOpts, id *big.Int, proposed common.Address) (*types.Transaction, error) + + Unpause(opts *bind.TransactOpts) (*types.Transaction, error) + + UnpauseUpkeep(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) + + WithdrawFunds(opts *bind.TransactOpts, id *big.Int, to common.Address) (*types.Transaction, error) + + WithdrawOwnerFunds(opts *bind.TransactOpts) (*types.Transaction, error) + + WithdrawPayment(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) + + FilterAdminPrivilegeConfigSet(opts *bind.FilterOpts, admin []common.Address) (*AutomationRegistryLogicBAdminPrivilegeConfigSetIterator, error) + + WatchAdminPrivilegeConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBAdminPrivilegeConfigSet, admin []common.Address) (event.Subscription, error) + + ParseAdminPrivilegeConfigSet(log types.Log) (*AutomationRegistryLogicBAdminPrivilegeConfigSet, error) + + FilterCancelledUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBCancelledUpkeepReportIterator, error) + + WatchCancelledUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBCancelledUpkeepReport, id []*big.Int) (event.Subscription, error) + + ParseCancelledUpkeepReport(log types.Log) (*AutomationRegistryLogicBCancelledUpkeepReport, error) + + FilterChainSpecificModuleUpdated(opts *bind.FilterOpts) (*AutomationRegistryLogicBChainSpecificModuleUpdatedIterator, error) + + WatchChainSpecificModuleUpdated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBChainSpecificModuleUpdated) (event.Subscription, error) + + ParseChainSpecificModuleUpdated(log types.Log) (*AutomationRegistryLogicBChainSpecificModuleUpdated, error) + + FilterDedupKeyAdded(opts *bind.FilterOpts, dedupKey [][32]byte) (*AutomationRegistryLogicBDedupKeyAddedIterator, error) + + WatchDedupKeyAdded(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBDedupKeyAdded, dedupKey [][32]byte) (event.Subscription, error) + + ParseDedupKeyAdded(log types.Log) (*AutomationRegistryLogicBDedupKeyAdded, error) + + FilterFundsAdded(opts *bind.FilterOpts, id []*big.Int, from []common.Address) (*AutomationRegistryLogicBFundsAddedIterator, error) + + WatchFundsAdded(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBFundsAdded, id []*big.Int, from []common.Address) (event.Subscription, error) + + ParseFundsAdded(log types.Log) (*AutomationRegistryLogicBFundsAdded, error) + + FilterFundsWithdrawn(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBFundsWithdrawnIterator, error) + + WatchFundsWithdrawn(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBFundsWithdrawn, id []*big.Int) (event.Subscription, error) + + ParseFundsWithdrawn(log types.Log) (*AutomationRegistryLogicBFundsWithdrawn, error) + + FilterInsufficientFundsUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBInsufficientFundsUpkeepReportIterator, error) + + WatchInsufficientFundsUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBInsufficientFundsUpkeepReport, id []*big.Int) (event.Subscription, error) + + ParseInsufficientFundsUpkeepReport(log types.Log) (*AutomationRegistryLogicBInsufficientFundsUpkeepReport, error) + + FilterOwnerFundsWithdrawn(opts *bind.FilterOpts) (*AutomationRegistryLogicBOwnerFundsWithdrawnIterator, error) + + WatchOwnerFundsWithdrawn(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBOwnerFundsWithdrawn) (event.Subscription, error) + + ParseOwnerFundsWithdrawn(log types.Log) (*AutomationRegistryLogicBOwnerFundsWithdrawn, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*AutomationRegistryLogicBOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*AutomationRegistryLogicBOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*AutomationRegistryLogicBOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*AutomationRegistryLogicBOwnershipTransferred, error) + + FilterPaused(opts *bind.FilterOpts) (*AutomationRegistryLogicBPausedIterator, error) + + WatchPaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBPaused) (event.Subscription, error) + + ParsePaused(log types.Log) (*AutomationRegistryLogicBPaused, error) + + FilterPayeesUpdated(opts *bind.FilterOpts) (*AutomationRegistryLogicBPayeesUpdatedIterator, error) + + WatchPayeesUpdated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBPayeesUpdated) (event.Subscription, error) + + ParsePayeesUpdated(log types.Log) (*AutomationRegistryLogicBPayeesUpdated, error) + + FilterPayeeshipTransferRequested(opts *bind.FilterOpts, transmitter []common.Address, from []common.Address, to []common.Address) (*AutomationRegistryLogicBPayeeshipTransferRequestedIterator, error) + + WatchPayeeshipTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBPayeeshipTransferRequested, transmitter []common.Address, from []common.Address, to []common.Address) (event.Subscription, error) + + ParsePayeeshipTransferRequested(log types.Log) (*AutomationRegistryLogicBPayeeshipTransferRequested, error) + + FilterPayeeshipTransferred(opts *bind.FilterOpts, transmitter []common.Address, from []common.Address, to []common.Address) (*AutomationRegistryLogicBPayeeshipTransferredIterator, error) + + WatchPayeeshipTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBPayeeshipTransferred, transmitter []common.Address, from []common.Address, to []common.Address) (event.Subscription, error) + + ParsePayeeshipTransferred(log types.Log) (*AutomationRegistryLogicBPayeeshipTransferred, error) + + FilterPaymentWithdrawn(opts *bind.FilterOpts, transmitter []common.Address, amount []*big.Int, to []common.Address) (*AutomationRegistryLogicBPaymentWithdrawnIterator, error) + + WatchPaymentWithdrawn(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBPaymentWithdrawn, transmitter []common.Address, amount []*big.Int, to []common.Address) (event.Subscription, error) + + ParsePaymentWithdrawn(log types.Log) (*AutomationRegistryLogicBPaymentWithdrawn, error) + + FilterReorgedUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBReorgedUpkeepReportIterator, error) + + WatchReorgedUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBReorgedUpkeepReport, id []*big.Int) (event.Subscription, error) + + ParseReorgedUpkeepReport(log types.Log) (*AutomationRegistryLogicBReorgedUpkeepReport, error) + + FilterStaleUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBStaleUpkeepReportIterator, error) + + WatchStaleUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBStaleUpkeepReport, id []*big.Int) (event.Subscription, error) + + ParseStaleUpkeepReport(log types.Log) (*AutomationRegistryLogicBStaleUpkeepReport, error) + + FilterUnpaused(opts *bind.FilterOpts) (*AutomationRegistryLogicBUnpausedIterator, error) + + WatchUnpaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUnpaused) (event.Subscription, error) + + ParseUnpaused(log types.Log) (*AutomationRegistryLogicBUnpaused, error) + + FilterUpkeepAdminTransferRequested(opts *bind.FilterOpts, id []*big.Int, from []common.Address, to []common.Address) (*AutomationRegistryLogicBUpkeepAdminTransferRequestedIterator, error) + + WatchUpkeepAdminTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepAdminTransferRequested, id []*big.Int, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseUpkeepAdminTransferRequested(log types.Log) (*AutomationRegistryLogicBUpkeepAdminTransferRequested, error) + + FilterUpkeepAdminTransferred(opts *bind.FilterOpts, id []*big.Int, from []common.Address, to []common.Address) (*AutomationRegistryLogicBUpkeepAdminTransferredIterator, error) + + WatchUpkeepAdminTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepAdminTransferred, id []*big.Int, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseUpkeepAdminTransferred(log types.Log) (*AutomationRegistryLogicBUpkeepAdminTransferred, error) + + FilterUpkeepCanceled(opts *bind.FilterOpts, id []*big.Int, atBlockHeight []uint64) (*AutomationRegistryLogicBUpkeepCanceledIterator, error) + + WatchUpkeepCanceled(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepCanceled, id []*big.Int, atBlockHeight []uint64) (event.Subscription, error) + + ParseUpkeepCanceled(log types.Log) (*AutomationRegistryLogicBUpkeepCanceled, error) + + FilterUpkeepCheckDataSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBUpkeepCheckDataSetIterator, error) + + WatchUpkeepCheckDataSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepCheckDataSet, id []*big.Int) (event.Subscription, error) + + ParseUpkeepCheckDataSet(log types.Log) (*AutomationRegistryLogicBUpkeepCheckDataSet, error) + + FilterUpkeepGasLimitSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBUpkeepGasLimitSetIterator, error) + + WatchUpkeepGasLimitSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepGasLimitSet, id []*big.Int) (event.Subscription, error) + + ParseUpkeepGasLimitSet(log types.Log) (*AutomationRegistryLogicBUpkeepGasLimitSet, error) + + FilterUpkeepMigrated(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBUpkeepMigratedIterator, error) + + WatchUpkeepMigrated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepMigrated, id []*big.Int) (event.Subscription, error) + + ParseUpkeepMigrated(log types.Log) (*AutomationRegistryLogicBUpkeepMigrated, error) + + FilterUpkeepOffchainConfigSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBUpkeepOffchainConfigSetIterator, error) + + WatchUpkeepOffchainConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepOffchainConfigSet, id []*big.Int) (event.Subscription, error) + + ParseUpkeepOffchainConfigSet(log types.Log) (*AutomationRegistryLogicBUpkeepOffchainConfigSet, error) + + FilterUpkeepPaused(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBUpkeepPausedIterator, error) + + WatchUpkeepPaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepPaused, id []*big.Int) (event.Subscription, error) + + ParseUpkeepPaused(log types.Log) (*AutomationRegistryLogicBUpkeepPaused, error) + + FilterUpkeepPerformed(opts *bind.FilterOpts, id []*big.Int, success []bool) (*AutomationRegistryLogicBUpkeepPerformedIterator, error) + + WatchUpkeepPerformed(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepPerformed, id []*big.Int, success []bool) (event.Subscription, error) + + ParseUpkeepPerformed(log types.Log) (*AutomationRegistryLogicBUpkeepPerformed, error) + + FilterUpkeepPrivilegeConfigSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBUpkeepPrivilegeConfigSetIterator, error) + + WatchUpkeepPrivilegeConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepPrivilegeConfigSet, id []*big.Int) (event.Subscription, error) + + ParseUpkeepPrivilegeConfigSet(log types.Log) (*AutomationRegistryLogicBUpkeepPrivilegeConfigSet, error) + + FilterUpkeepReceived(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBUpkeepReceivedIterator, error) + + WatchUpkeepReceived(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepReceived, id []*big.Int) (event.Subscription, error) + + ParseUpkeepReceived(log types.Log) (*AutomationRegistryLogicBUpkeepReceived, error) + + FilterUpkeepRegistered(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBUpkeepRegisteredIterator, error) + + WatchUpkeepRegistered(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepRegistered, id []*big.Int) (event.Subscription, error) + + ParseUpkeepRegistered(log types.Log) (*AutomationRegistryLogicBUpkeepRegistered, error) + + FilterUpkeepTriggerConfigSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBUpkeepTriggerConfigSetIterator, error) + + WatchUpkeepTriggerConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepTriggerConfigSet, id []*big.Int) (event.Subscription, error) + + ParseUpkeepTriggerConfigSet(log types.Log) (*AutomationRegistryLogicBUpkeepTriggerConfigSet, error) + + FilterUpkeepUnpaused(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryLogicBUpkeepUnpausedIterator, error) + + WatchUpkeepUnpaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryLogicBUpkeepUnpaused, id []*big.Int) (event.Subscription, error) + + ParseUpkeepUnpaused(log types.Log) (*AutomationRegistryLogicBUpkeepUnpaused, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/automation_registry_wrapper_2_3/automation_registry_wrapper_2_3.go b/core/gethwrappers/generated/automation_registry_wrapper_2_3/automation_registry_wrapper_2_3.go new file mode 100644 index 00000000000..950a6ccd986 --- /dev/null +++ b/core/gethwrappers/generated/automation_registry_wrapper_2_3/automation_registry_wrapper_2_3.go @@ -0,0 +1,5300 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package automation_registry_wrapper_2_3 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type AutomationRegistryBase23OnchainConfig struct { + PaymentPremiumPPB uint32 + FlatFeeMicroLink uint32 + CheckGasLimit uint32 + StalenessSeconds *big.Int + GasCeilingMultiplier uint16 + MinUpkeepSpend *big.Int + MaxPerformGas uint32 + MaxCheckDataSize uint32 + MaxPerformDataSize uint32 + MaxRevertDataSize uint32 + FallbackGasPrice *big.Int + FallbackLinkPrice *big.Int + Transcoder common.Address + Registrars []common.Address + UpkeepPrivilegeManager common.Address + ChainModule common.Address + ReorgProtectionEnabled bool +} + +var AutomationRegistryMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicB2_3\",\"name\":\"logicA\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"contractIChainModule\",\"name\":\"chainModule\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_3.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"simulatePerformUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101406040523480156200001257600080fd5b50604051620051bb380380620051bb8339810160408190526200003591620003b1565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b9190620003b1565b826001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001009190620003b1565b836001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001659190620003b1565b846001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca9190620003b1565b856001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f9190620003b1565b3380600081620002865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620002b957620002b981620002ed565b5050506001600160a01b0394851660805292841660a05290831660c052821660e052811661010052166101205250620003d8565b336001600160a01b03821603620003475760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200027d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b0381168114620003ae57600080fd5b50565b600060208284031215620003c457600080fd5b8151620003d18162000398565b9392505050565b60805160a05160c05160e0516101005161012051614d96620004256000396000818160d6015261016f01526000611b29015260005050600050506000505060006104330152614d966000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c8063aed2e92911610081578063e3d0e7121161005b578063e3d0e712146102e0578063f2fde38b146102f3578063f75f6b1114610306576100d4565b8063aed2e92914610262578063afcb95d71461028c578063b1dc65a4146102cd576100d4565b806381ff7048116100b257806381ff7048146101bc5780638da5cb5b14610231578063a4c0ed361461024f576100d4565b8063181f5a771461011b578063349e8cca1461016d57806379ba5097146101b4575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610114573d6000f35b3d6000fd5b005b6101576040518060400160405280601881526020017f4175746f6d6174696f6e526567697374727920322e332e30000000000000000081525081565b6040516101649190613a92565b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610164565b610119610319565b61020e60155460115463ffffffff780100000000000000000000000000000000000000000000000083048116937c01000000000000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610164565b60005473ffffffffffffffffffffffffffffffffffffffff1661018f565b61011961025d366004613b20565b61041b565b610275610270366004613b7c565b610637565b604080519215158352602083019190915201610164565b601154601254604080516000815260208101939093527401000000000000000000000000000000000000000090910463ffffffff1690820152606001610164565b6101196102db366004613c0d565b6107ad565b6101196102ee366004613ede565b610ae8565b610119610301366004613fab565b610b11565b6101196103143660046141af565b610b25565b60015473ffffffffffffffffffffffffffffffffffffffff16331461039f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461048a576040517fc8bad78d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081146104c4576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104d28284018461423e565b60008181526004602052604090205490915065010000000000900463ffffffff9081161461052c576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600460205260409020600101546105679085906c0100000000000000000000000090046bffffffffffffffffffffffff16614286565b600082815260046020526040902060010180546bffffffffffffffffffffffff929092166c01000000000000000000000000027fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff9092169190911790556019546105d29085906142ab565b6019556040516bffffffffffffffffffffffff8516815273ffffffffffffffffffffffffffffffffffffffff86169082907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a35050505050565b600080610642611b11565b6012547e01000000000000000000000000000000000000000000000000000000000000900460ff16156106a1576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260046020908152604091829020825160e081018452815460ff811615158252610100810463ffffffff908116838601819052650100000000008304821684880152690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff16606084018190526001909401546bffffffffffffffffffffffff80821660808601526c0100000000000000000000000082041660a0850152780100000000000000000000000000000000000000000000000090041660c08301528451601f890185900485028101850190955287855290936107a0938990899081908401838280828437600092019190915250611b8292505050565b9097909650945050505050565b60005a60408051610160810182526012546bffffffffffffffffffffffff8116825263ffffffff6c010000000000000000000000008204811660208401527001000000000000000000000000000000008204811693830193909352740100000000000000000000000000000000000000008104909216606082015262ffffff7801000000000000000000000000000000000000000000000000830416608082015261ffff7b0100000000000000000000000000000000000000000000000000000083041660a082015260ff7d0100000000000000000000000000000000000000000000000000000000008304811660c08301527e010000000000000000000000000000000000000000000000000000000000008304811615801560e08401527f01000000000000000000000000000000000000000000000000000000000000009093048116151561010080840191909152601354918216151561012084015273ffffffffffffffffffffffffffffffffffffffff910416610140820152919250610963576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff166109ac576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6011548a35146109e8576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c08101516109f89060016142ed565b60ff1686141580610a095750858414155b15610a40576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a508a8a8a8a8a8a8a8a611dab565b6000610a5c8a8a612014565b905060208b0135600881901c63ffffffff16610a798484876120cf565b836060015163ffffffff168163ffffffff161115610ad957601280547fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000063ffffffff8416021790555b50505050505050505050505050565b610b0986868686806020019051810190610b0291906143ac565b8686610b25565b505050505050565b610b19612a4e565b610b2281612acf565b50565b610b2d612a4e565b601f86511115610b69576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8360ff16600003610ba6576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518651141580610bc55750610bbd84600361452e565b60ff16865111155b15610bfc576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254600e546bffffffffffffffffffffffff9091169060005b816bffffffffffffffffffffffff16811015610c7e57610c6b600e8281548110610c4257610c426142be565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff168484612bc4565b5080610c768161454a565b915050610c16565b5060008060005b836bffffffffffffffffffffffff16811015610d8757600d8181548110610cae57610cae6142be565b600091825260209091200154600e805473ffffffffffffffffffffffffffffffffffffffff90921694509082908110610ce957610ce96142be565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff8681168452600c8352604080852080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559116808452600b90925290912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055915080610d7f8161454a565b915050610c85565b50610d94600d6000613971565b610da0600e6000613971565b604080516080810182526000808252602082018190529181018290526060810182905290805b8c5181101561120957600c60008e8381518110610de557610de56142be565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615610e50576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168d8281518110610e7a57610e7a6142be565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610ecf576040517f815e1d6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c60008f8481518110610f0057610f006142be565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909316929092171790558b518c9082908110610fa857610fa86142be565b60200260200101519150600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611018576040517f58a70a0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166000908152600b60209081526040918290208251608081018452905460ff80821615801584526101008304909116938301939093526bffffffffffffffffffffffff6201000082048116948301949094526e010000000000000000000000000000900490921660608301529093506110d3576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001835260ff80821660208086019182526bffffffffffffffffffffffff808b166060880190815273ffffffffffffffffffffffffffffffffffffffff87166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090951694909417179190911692909217919091179055806112018161454a565b915050610dc6565b50508a5161121f9150600d9060208d019061398f565b50885161123390600e9060208c019061398f565b50604051806101600160405280856bffffffffffffffffffffffff168152602001886000015163ffffffff168152602001886020015163ffffffff168152602001600063ffffffff168152602001886060015162ffffff168152602001886080015161ffff1681526020018960ff1681526020016012600001601e9054906101000a900460ff16151581526020016012600001601f9054906101000a900460ff161515815260200188610200015115158152602001886101e0015173ffffffffffffffffffffffffffffffffffffffff16815250601260008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160106101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060808201518160000160186101000a81548162ffffff021916908362ffffff16021790555060a082015181600001601b6101000a81548161ffff021916908361ffff16021790555060c082015181600001601d6101000a81548160ff021916908360ff16021790555060e082015181600001601e6101000a81548160ff02191690831515021790555061010082015181600001601f6101000a81548160ff0219169083151502179055506101208201518160010160006101000a81548160ff0219169083151502179055506101408201518160010160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050506040518061018001604052808860a001516bffffffffffffffffffffffff16815260200188610180015173ffffffffffffffffffffffffffffffffffffffff168152602001601460010160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001886040015163ffffffff1681526020018860c0015163ffffffff168152602001601460010160149054906101000a900463ffffffff1663ffffffff168152602001601460010160189054906101000a900463ffffffff1663ffffffff1681526020016014600101601c9054906101000a900463ffffffff1663ffffffff1681526020018860e0015163ffffffff16815260200188610100015163ffffffff16815260200188610120015163ffffffff168152602001886101c0015173ffffffffffffffffffffffffffffffffffffffff16815250601460008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550606082015181600101600c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160106101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548163ffffffff021916908363ffffffff1602179055506101208201518160020160046101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160086101000a81548163ffffffff021916908363ffffffff16021790555061016082015181600201600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505086610140015160178190555086610160015160188190555060006014600101601c9054906101000a900463ffffffff169050876101e0015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118f89190614582565b601580547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff9384160217808255600192601891611973918591780100000000000000000000000000000000000000000000000090041661459b565b92506101000a81548163ffffffff021916908363ffffffff1602179055506000886040516020016119a49190614609565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152919052601554909150611a0d90469030907801000000000000000000000000000000000000000000000000900463ffffffff168f8f8f878f8f612dcc565b60115560005b611a1d6009612e76565b811015611a4d57611a3a611a32600983612e80565b600990612e93565b5080611a458161454a565b915050611a13565b5060005b896101a0015151811015611aa457611a918a6101a001518281518110611a7957611a796142be565b60200260200101516009612eb590919063ffffffff16565b5080611a9c8161454a565b915050611a51565b507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0582601154601460010160189054906101000a900463ffffffff168f8f8f878f8f604051611afb999897969594939291906147ad565b60405180910390a1505050505050505050505050565b3273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611b80576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60125460009081907f0100000000000000000000000000000000000000000000000000000000000000900460ff1615611be7576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790556040517f4585e33b0000000000000000000000000000000000000000000000000000000090611c63908590602401613a92565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d1690611d369087908790600401614843565b60408051808303816000875af1158015611d54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d78919061485c565b601280547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16905590969095509350505050565b60008787604051611dbd92919061488a565b604051908190038120611dd4918b9060200161489a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b88811015611fab57600185878360208110611e4057611e406142be565b611e4d91901a601b6142ed565b8c8c85818110611e5f57611e5f6142be565b905060200201358b8b86818110611e7857611e786142be565b9050602002013560405160008152602001604052604051611eb5949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611ed7573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955093509050611f85576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b840193508080611fa39061454a565b915050611e23565b50827e01010101010101010101010101010101010101010101010101010101010101841614612006576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b61204d6040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b600061205b8385018561498b565b604081015151606082015151919250908114158061207e57508082608001515114155b8061208e5750808260a001515114155b156120c5576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5090505b92915050565b600082604001515167ffffffffffffffff8111156120ef576120ef613cc4565b6040519080825280602002602001820160405280156121ab57816020015b604080516101c081018252600060e08201818152610100830182905261012083018290526101408301829052610160830182905261018083018290526101a0830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161210d5790505b50905060006040518060800160405280600061ffff1681526020016000815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff168152509050600085610140015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612249573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061226d9190614582565b9050600086610140015173ffffffffffffffffffffffffffffffffffffffff166318b8f6136040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e59190614582565b905060005b866040015151811015612734576004600088604001518381518110612311576123116142be565b6020908102919091018101518252818101929092526040908101600020815160e081018352815460ff811615158252610100810463ffffffff90811695830195909552650100000000008104851693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c082015285518690839081106123f6576123f66142be565b60200260200101516000018190525061242b8760400151828151811061241e5761241e6142be565b6020026020010151612ed7565b85828151811061243d5761243d6142be565b602002602001015160600190600181111561245a5761245a614a78565b9081600181111561246d5761246d614a78565b815250506124d18760400151828151811061248a5761248a6142be565b602002602001015184896080015184815181106124a9576124a96142be565b60200260200101518885815181106124c3576124c36142be565b60200260200101518c612f82565b8683815181106124e3576124e36142be565b6020026020010151602001878481518110612500576125006142be565b602002602001015160c001828152508215151515815250505084818151811061252b5761252b6142be565b6020026020010151602001511561255b5760018460000181815161254f9190614aa7565b61ffff16905250612560565b612722565b6125c6858281518110612575576125756142be565b602002602001015160000151606001518860600151838151811061259b5761259b6142be565b60200260200101518960a0015184815181106125b9576125b96142be565b6020026020010151611b82565b8683815181106125d8576125d86142be565b60200260200101516040018784815181106125f5576125f56142be565b602090810291909101015160800191909152901515905260c088015161261c9060016142ed565b61262a9060ff166040614ac2565b6103a48860a001518381518110612643576126436142be565b60200260200101515161265691906142ab565b61266091906142ab565b858281518110612672576126726142be565b602002602001015160a0018181525050848181518110612694576126946142be565b602002602001015160a00151846020018181516126b191906142ab565b90525084518590829081106126c8576126c86142be565b602002602001015160800151866126df9190614ad9565b9550612722876040015182815181106126fa576126fa6142be565b602002602001015184878481518110612715576127156142be565b60200260200101516130a1565b8061272c8161454a565b9150506122ea565b50825161ffff1660000361274b5750505050505050565b6155f0612759366010614ac2565b5a6127649088614ad9565b61276e91906142ab565b61277891906142ab565b8351909550611b589061278f9061ffff1687614b1b565b61279991906142ab565b945060008060005b88604001515181101561297d578681815181106127c0576127c06142be565b6020026020010151602001511561296b576128598a8a6040015183815181106127eb576127eb6142be565b6020026020010151898481518110612805576128056142be565b6020026020010151608001518c600001518d602001518d8c602001518e8981518110612833576128336142be565b602002602001015160a001518c61284a9190614ac2565b6128549190614b1b565b6131a6565b6060880180519295509093508391612872908390614286565b6bffffffffffffffffffffffff16905250604086018051849190612897908390614286565b6bffffffffffffffffffffffff1690525086518790829081106128bc576128bc6142be565b6020026020010151604001511515896040015182815181106128e0576128e06142be565b60200260200101517fad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b84866129159190614286565b8a8581518110612927576129276142be565b6020026020010151608001518c8e60800151878151811061294a5761294a6142be565b60200260200101516040516129629493929190614b2f565b60405180910390a35b806129758161454a565b9150506127a1565b505050604083810151336000908152600b6020529190912080546002906129b99084906201000090046bffffffffffffffffffffffff16614286565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508260600151601260000160008282829054906101000a90046bffffffffffffffffffffffff16612a179190614286565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611b80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610396565b3373ffffffffffffffffffffffffffffffffffffffff821603612b4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610396565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e0100000000000000000000000000009004909116606082015290612dc0576000816060015185612c5c9190614b6c565b90506000612c6a8583614b91565b90508083604001818151612c7e9190614286565b6bffffffffffffffffffffffff16905250612c998582614bbc565b83606001818151612caa9190614286565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b6000808a8a8a8a8a8a8a8a8a604051602001612df099989796959493929190614bec565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b60006120c9825490565b6000612e8c8383613329565b9392505050565b6000612e8c8373ffffffffffffffffffffffffffffffffffffffff8416613353565b6000612e8c8373ffffffffffffffffffffffffffffffffffffffff841661344d565b6000818160045b600f811015612f64577fff000000000000000000000000000000000000000000000000000000000000008216838260208110612f1c57612f1c6142be565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612f5257506000949350505050565b80612f5c8161454a565b915050612ede565b5081600f1a6001811115612f7a57612f7a614a78565b949350505050565b600080808085606001516001811115612f9d57612f9d614a78565b03612fc357612faf888888888861349c565b612fbe57600092509050613097565b61303b565b600185606001516001811115612fdb57612fdb614a78565b03613009576000612fee89898988613627565b92509050806130035750600092509050613097565b5061303b565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516040015163ffffffff16871061309057877fc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd56368760405161307d9190613a92565b60405180910390a2600092509050613097565b6001925090505b9550959350505050565b6000816060015160018111156130b9576130b9614a78565b0361311d57600083815260046020526040902060010180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000063ffffffff851602179055505050565b60018160600151600181111561313557613135614a78565b036131a15760c08101805160009081526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055915191517fa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f29190a25b505050565b6000806131b9898886868a8a6001613835565b60008a8152600460205260408120600101549294509092506c010000000000000000000000009091046bffffffffffffffffffffffff16906131fb8385614286565b9050836bffffffffffffffffffffffff16826bffffffffffffffffffffffff16101561322f57509150600090508180613262565b806bffffffffffffffffffffffff16826bffffffffffffffffffffffff16101561326257508061325f8482614b6c565b92505b60008a81526004602052604090206001018054829190600c906132a49084906c0100000000000000000000000090046bffffffffffffffffffffffff16614b6c565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008c8152600460205260408120600101805485945090926132ed91859116614286565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505097509795505050505050565b6000826000018281548110613340576133406142be565b9060005260206000200154905092915050565b6000818152600183016020526040812054801561343c576000613377600183614ad9565b855490915060009061338b90600190614ad9565b90508181146133f05760008660000182815481106133ab576133ab6142be565b90600052602060002001549050808760000184815481106133ce576133ce6142be565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061340157613401614c81565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506120c9565b60009150506120c9565b5092915050565b6000818152600183016020526040812054613494575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556120c9565b5060006120c9565b600080848060200190518101906134b39190614cb0565b845160c00151815191925063ffffffff9081169116101561351057867f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8866040516134fe9190613a92565b60405180910390a2600091505061361e565b82610120015180156135d157506020810151158015906135d15750602081015161014084015182516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa1580156135aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135ce9190614582565b14155b806135e35750805163ffffffff168611155b1561361857867f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301866040516134fe9190613a92565b60019150505b95945050505050565b6000806000848060200190518101906136409190614d08565b90506000878260000151836020015184604001516040516020016136a294939291909384526020840192909252604083015260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016606082015260640190565b604051602081830303815290604052805190602001209050846101200151801561377e575060808201511580159061377e5750608082015161014086015160608401516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa158015613757573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061377b9190614582565b14155b80613793575086826060015163ffffffff1610155b156137dd57877f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301876040516137c89190613a92565b60405180910390a260009350915061382c9050565b60008181526008602052604090205460ff161561382457877f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8876040516137c89190613a92565b600193509150505b94509492505050565b60008060008960a0015161ffff168661384e9190614ac2565b905083801561385c5750803a105b1561386457503a5b600085886138728b8d6142ab565b61387c9085614ac2565b61388691906142ab565b61389890670de0b6b3a7640000614ac2565b6138a29190614b1b565b905060008b6040015163ffffffff1664e8d4a510006138c19190614ac2565b60208d0151889063ffffffff168b6138d98f88614ac2565b6138e391906142ab565b6138f190633b9aca00614ac2565b6138fb9190614ac2565b6139059190614b1b565b61390f91906142ab565b90506b033b2e3c9fd0803ce800000061392882846142ab565b1115613960576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909b909a5098505050505050505050565b5080546000825590600052602060002090810190610b229190613a19565b828054828255906000526020600020908101928215613a09579160200282015b82811115613a0957825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906139af565b50613a15929150613a19565b5090565b5b80821115613a155760008155600101613a1a565b6000815180845260005b81811015613a5457602081850181015186830182015201613a38565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000612e8c6020830184613a2e565b73ffffffffffffffffffffffffffffffffffffffff81168114610b2257600080fd5b8035613ad281613aa5565b919050565b60008083601f840112613ae957600080fd5b50813567ffffffffffffffff811115613b0157600080fd5b602083019150836020828501011115613b1957600080fd5b9250929050565b60008060008060608587031215613b3657600080fd5b8435613b4181613aa5565b935060208501359250604085013567ffffffffffffffff811115613b6457600080fd5b613b7087828801613ad7565b95989497509550505050565b600080600060408486031215613b9157600080fd5b83359250602084013567ffffffffffffffff811115613baf57600080fd5b613bbb86828701613ad7565b9497909650939450505050565b60008083601f840112613bda57600080fd5b50813567ffffffffffffffff811115613bf257600080fd5b6020830191508360208260051b8501011115613b1957600080fd5b60008060008060008060008060e0898b031215613c2957600080fd5b606089018a811115613c3a57600080fd5b8998503567ffffffffffffffff80821115613c5457600080fd5b613c608c838d01613ad7565b909950975060808b0135915080821115613c7957600080fd5b613c858c838d01613bc8565b909750955060a08b0135915080821115613c9e57600080fd5b50613cab8b828c01613bc8565b999c989b50969995989497949560c00135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610220810167ffffffffffffffff81118282101715613d1757613d17613cc4565b60405290565b60405160c0810167ffffffffffffffff81118282101715613d1757613d17613cc4565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613d8757613d87613cc4565b604052919050565b600067ffffffffffffffff821115613da957613da9613cc4565b5060051b60200190565b600082601f830112613dc457600080fd5b81356020613dd9613dd483613d8f565b613d40565b82815260059290921b84018101918181019086841115613df857600080fd5b8286015b84811015613e1c578035613e0f81613aa5565b8352918301918301613dfc565b509695505050505050565b803560ff81168114613ad257600080fd5b600082601f830112613e4957600080fd5b813567ffffffffffffffff811115613e6357613e63613cc4565b613e9460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613d40565b818152846020838601011115613ea957600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff81168114613ad257600080fd5b60008060008060008060c08789031215613ef757600080fd5b863567ffffffffffffffff80821115613f0f57600080fd5b613f1b8a838b01613db3565b97506020890135915080821115613f3157600080fd5b613f3d8a838b01613db3565b9650613f4b60408a01613e27565b95506060890135915080821115613f6157600080fd5b613f6d8a838b01613e38565b9450613f7b60808a01613ec6565b935060a0890135915080821115613f9157600080fd5b50613f9e89828a01613e38565b9150509295509295509295565b600060208284031215613fbd57600080fd5b8135612e8c81613aa5565b63ffffffff81168114610b2257600080fd5b8035613ad281613fc8565b62ffffff81168114610b2257600080fd5b8035613ad281613fe5565b61ffff81168114610b2257600080fd5b8035613ad281614001565b6bffffffffffffffffffffffff81168114610b2257600080fd5b8035613ad28161401c565b8015158114610b2257600080fd5b8035613ad281614041565b6000610220828403121561406d57600080fd5b614075613cf3565b905061408082613fda565b815261408e60208301613fda565b602082015261409f60408301613fda565b60408201526140b060608301613ff6565b60608201526140c160808301614011565b60808201526140d260a08301614036565b60a08201526140e360c08301613fda565b60c08201526140f460e08301613fda565b60e0820152610100614107818401613fda565b90820152610120614119838201613fda565b9082015261014082810135908201526101608083013590820152610180614141818401613ac7565b908201526101a08281013567ffffffffffffffff81111561416157600080fd5b61416d85828601613db3565b8284015250506101c0614181818401613ac7565b908201526101e0614193838201613ac7565b908201526102006141a583820161404f565b9082015292915050565b60008060008060008060c087890312156141c857600080fd5b863567ffffffffffffffff808211156141e057600080fd5b6141ec8a838b01613db3565b9750602089013591508082111561420257600080fd5b61420e8a838b01613db3565b965061421c60408a01613e27565b9550606089013591508082111561423257600080fd5b613f6d8a838b0161405a565b60006020828403121561425057600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff81811683821601908082111561344657613446614257565b808201808211156120c9576120c9614257565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60ff81811683821601908111156120c9576120c9614257565b8051613ad281613fc8565b8051613ad281613fe5565b8051613ad281614001565b8051613ad28161401c565b8051613ad281613aa5565b600082601f83011261434e57600080fd5b8151602061435e613dd483613d8f565b82815260059290921b8401810191818101908684111561437d57600080fd5b8286015b84811015613e1c57805161439481613aa5565b8352918301918301614381565b8051613ad281614041565b6000602082840312156143be57600080fd5b815167ffffffffffffffff808211156143d657600080fd5b9083019061022082860312156143eb57600080fd5b6143f3613cf3565b6143fc83614306565b815261440a60208401614306565b602082015261441b60408401614306565b604082015261442c60608401614311565b606082015261443d6080840161431c565b608082015261444e60a08401614327565b60a082015261445f60c08401614306565b60c082015261447060e08401614306565b60e0820152610100614483818501614306565b90820152610120614495848201614306565b90820152610140838101519082015261016080840151908201526101806144bd818501614332565b908201526101a083810151838111156144d557600080fd5b6144e18882870161433d565b8284015250506101c091506144f7828401614332565b828201526101e0915061450b828401614332565b82820152610200915061451f8284016143a1565b91810191909152949350505050565b60ff818116838216029081169081811461344657613446614257565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361457b5761457b614257565b5060010190565b60006020828403121561459457600080fd5b5051919050565b63ffffffff81811683821601908082111561344657613446614257565b600081518084526020808501945080840160005b838110156145fe57815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016145cc565b509495945050505050565b6020815261462060208201835163ffffffff169052565b60006020830151614639604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015162ffffff8116608084015250608083015161ffff811660a08401525060a08301516bffffffffffffffffffffffff811660c08401525060c083015163ffffffff811660e08401525060e08301516101006146b28185018363ffffffff169052565b84015190506101206146cb8482018363ffffffff169052565b84015190506101406146e48482018363ffffffff169052565b840151610160848101919091528401516101808085019190915284015190506101a06147278185018373ffffffffffffffffffffffffffffffffffffffff169052565b808501519150506102206101c081818601526147476102408601846145b8565b908601519092506101e06147728682018373ffffffffffffffffffffffffffffffffffffffff169052565b860151905061020061479b8682018373ffffffffffffffffffffffffffffffffffffffff169052565b90950151151593019290925250919050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526147dd8184018a6145b8565b905082810360808401526147f181896145b8565b905060ff871660a084015282810360c084015261480e8187613a2e565b905067ffffffffffffffff851660e08401528281036101008401526148338185613a2e565b9c9b505050505050505050505050565b828152604060208201526000612f7a6040830184613a2e565b6000806040838503121561486f57600080fd5b825161487a81614041565b6020939093015192949293505050565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f8301126148c157600080fd5b813560206148d1613dd483613d8f565b82815260059290921b840181019181810190868411156148f057600080fd5b8286015b84811015613e1c57803583529183019183016148f4565b600082601f83011261491c57600080fd5b8135602061492c613dd483613d8f565b82815260059290921b8401810191818101908684111561494b57600080fd5b8286015b84811015613e1c57803567ffffffffffffffff81111561496f5760008081fd5b61497d8986838b0101613e38565b84525091830191830161494f565b60006020828403121561499d57600080fd5b813567ffffffffffffffff808211156149b557600080fd5b9083019060c082860312156149c957600080fd5b6149d1613d1d565b82358152602083013560208201526040830135828111156149f157600080fd5b6149fd878286016148b0565b604083015250606083013582811115614a1557600080fd5b614a21878286016148b0565b606083015250608083013582811115614a3957600080fd5b614a458782860161490b565b60808301525060a083013582811115614a5d57600080fd5b614a698782860161490b565b60a08301525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b61ffff81811683821601908082111561344657613446614257565b80820281158282048414176120c9576120c9614257565b818103818111156120c9576120c9614257565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614b2a57614b2a614aec565b500490565b6bffffffffffffffffffffffff85168152836020820152826040820152608060608201526000614b626080830184613a2e565b9695505050505050565b6bffffffffffffffffffffffff82811682821603908082111561344657613446614257565b60006bffffffffffffffffffffffff80841680614bb057614bb0614aec565b92169190910492915050565b6bffffffffffffffffffffffff818116838216028082169190828114614be457614be4614257565b505092915050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614c338285018b6145b8565b91508382036080850152614c47828a6145b8565b915060ff881660a085015283820360c0850152614c648288613a2e565b90861660e085015283810361010085015290506148338185613a2e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600060408284031215614cc257600080fd5b6040516040810181811067ffffffffffffffff82111715614ce557614ce5613cc4565b6040528251614cf381613fc8565b81526020928301519281019290925250919050565b600060a08284031215614d1a57600080fd5b60405160a0810181811067ffffffffffffffff82111715614d3d57614d3d613cc4565b806040525082518152602083015160208201526040830151614d5e81613fc8565b60408201526060830151614d7181613fc8565b6060820152608092830151928101929092525091905056fea164736f6c6343000813000a", +} + +var AutomationRegistryABI = AutomationRegistryMetaData.ABI + +var AutomationRegistryBin = AutomationRegistryMetaData.Bin + +func DeployAutomationRegistry(auth *bind.TransactOpts, backend bind.ContractBackend, logicA common.Address) (common.Address, *types.Transaction, *AutomationRegistry, error) { + parsed, err := AutomationRegistryMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(AutomationRegistryBin), backend, logicA) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &AutomationRegistry{address: address, abi: *parsed, AutomationRegistryCaller: AutomationRegistryCaller{contract: contract}, AutomationRegistryTransactor: AutomationRegistryTransactor{contract: contract}, AutomationRegistryFilterer: AutomationRegistryFilterer{contract: contract}}, nil +} + +type AutomationRegistry struct { + address common.Address + abi abi.ABI + AutomationRegistryCaller + AutomationRegistryTransactor + AutomationRegistryFilterer +} + +type AutomationRegistryCaller struct { + contract *bind.BoundContract +} + +type AutomationRegistryTransactor struct { + contract *bind.BoundContract +} + +type AutomationRegistryFilterer struct { + contract *bind.BoundContract +} + +type AutomationRegistrySession struct { + Contract *AutomationRegistry + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type AutomationRegistryCallerSession struct { + Contract *AutomationRegistryCaller + CallOpts bind.CallOpts +} + +type AutomationRegistryTransactorSession struct { + Contract *AutomationRegistryTransactor + TransactOpts bind.TransactOpts +} + +type AutomationRegistryRaw struct { + Contract *AutomationRegistry +} + +type AutomationRegistryCallerRaw struct { + Contract *AutomationRegistryCaller +} + +type AutomationRegistryTransactorRaw struct { + Contract *AutomationRegistryTransactor +} + +func NewAutomationRegistry(address common.Address, backend bind.ContractBackend) (*AutomationRegistry, error) { + abi, err := abi.JSON(strings.NewReader(AutomationRegistryABI)) + if err != nil { + return nil, err + } + contract, err := bindAutomationRegistry(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AutomationRegistry{address: address, abi: abi, AutomationRegistryCaller: AutomationRegistryCaller{contract: contract}, AutomationRegistryTransactor: AutomationRegistryTransactor{contract: contract}, AutomationRegistryFilterer: AutomationRegistryFilterer{contract: contract}}, nil +} + +func NewAutomationRegistryCaller(address common.Address, caller bind.ContractCaller) (*AutomationRegistryCaller, error) { + contract, err := bindAutomationRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AutomationRegistryCaller{contract: contract}, nil +} + +func NewAutomationRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*AutomationRegistryTransactor, error) { + contract, err := bindAutomationRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AutomationRegistryTransactor{contract: contract}, nil +} + +func NewAutomationRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*AutomationRegistryFilterer, error) { + contract, err := bindAutomationRegistry(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AutomationRegistryFilterer{contract: contract}, nil +} + +func bindAutomationRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := AutomationRegistryMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_AutomationRegistry *AutomationRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AutomationRegistry.Contract.AutomationRegistryCaller.contract.Call(opts, result, method, params...) +} + +func (_AutomationRegistry *AutomationRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationRegistry.Contract.AutomationRegistryTransactor.contract.Transfer(opts) +} + +func (_AutomationRegistry *AutomationRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AutomationRegistry.Contract.AutomationRegistryTransactor.contract.Transact(opts, method, params...) +} + +func (_AutomationRegistry *AutomationRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AutomationRegistry.Contract.contract.Call(opts, result, method, params...) +} + +func (_AutomationRegistry *AutomationRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationRegistry.Contract.contract.Transfer(opts) +} + +func (_AutomationRegistry *AutomationRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AutomationRegistry.Contract.contract.Transact(opts, method, params...) +} + +func (_AutomationRegistry *AutomationRegistryCaller) FallbackTo(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AutomationRegistry.contract.Call(opts, &out, "fallbackTo") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_AutomationRegistry *AutomationRegistrySession) FallbackTo() (common.Address, error) { + return _AutomationRegistry.Contract.FallbackTo(&_AutomationRegistry.CallOpts) +} + +func (_AutomationRegistry *AutomationRegistryCallerSession) FallbackTo() (common.Address, error) { + return _AutomationRegistry.Contract.FallbackTo(&_AutomationRegistry.CallOpts) +} + +func (_AutomationRegistry *AutomationRegistryCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) { + var out []interface{} + err := _AutomationRegistry.contract.Call(opts, &out, "latestConfigDetails") + + outstruct := new(LatestConfigDetails) + if err != nil { + return *outstruct, err + } + + outstruct.ConfigCount = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.ConfigDigest = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + + return *outstruct, err + +} + +func (_AutomationRegistry *AutomationRegistrySession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _AutomationRegistry.Contract.LatestConfigDetails(&_AutomationRegistry.CallOpts) +} + +func (_AutomationRegistry *AutomationRegistryCallerSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _AutomationRegistry.Contract.LatestConfigDetails(&_AutomationRegistry.CallOpts) +} + +func (_AutomationRegistry *AutomationRegistryCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) { + var out []interface{} + err := _AutomationRegistry.contract.Call(opts, &out, "latestConfigDigestAndEpoch") + + outstruct := new(LatestConfigDigestAndEpoch) + if err != nil { + return *outstruct, err + } + + outstruct.ScanLogs = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.ConfigDigest = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + outstruct.Epoch = *abi.ConvertType(out[2], new(uint32)).(*uint32) + + return *outstruct, err + +} + +func (_AutomationRegistry *AutomationRegistrySession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _AutomationRegistry.Contract.LatestConfigDigestAndEpoch(&_AutomationRegistry.CallOpts) +} + +func (_AutomationRegistry *AutomationRegistryCallerSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _AutomationRegistry.Contract.LatestConfigDigestAndEpoch(&_AutomationRegistry.CallOpts) +} + +func (_AutomationRegistry *AutomationRegistryCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _AutomationRegistry.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_AutomationRegistry *AutomationRegistrySession) Owner() (common.Address, error) { + return _AutomationRegistry.Contract.Owner(&_AutomationRegistry.CallOpts) +} + +func (_AutomationRegistry *AutomationRegistryCallerSession) Owner() (common.Address, error) { + return _AutomationRegistry.Contract.Owner(&_AutomationRegistry.CallOpts) +} + +func (_AutomationRegistry *AutomationRegistryCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _AutomationRegistry.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_AutomationRegistry *AutomationRegistrySession) TypeAndVersion() (string, error) { + return _AutomationRegistry.Contract.TypeAndVersion(&_AutomationRegistry.CallOpts) +} + +func (_AutomationRegistry *AutomationRegistryCallerSession) TypeAndVersion() (string, error) { + return _AutomationRegistry.Contract.TypeAndVersion(&_AutomationRegistry.CallOpts) +} + +func (_AutomationRegistry *AutomationRegistryTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationRegistry.contract.Transact(opts, "acceptOwnership") +} + +func (_AutomationRegistry *AutomationRegistrySession) AcceptOwnership() (*types.Transaction, error) { + return _AutomationRegistry.Contract.AcceptOwnership(&_AutomationRegistry.TransactOpts) +} + +func (_AutomationRegistry *AutomationRegistryTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _AutomationRegistry.Contract.AcceptOwnership(&_AutomationRegistry.TransactOpts) +} + +func (_AutomationRegistry *AutomationRegistryTransactor) OnTokenTransfer(opts *bind.TransactOpts, sender common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _AutomationRegistry.contract.Transact(opts, "onTokenTransfer", sender, amount, data) +} + +func (_AutomationRegistry *AutomationRegistrySession) OnTokenTransfer(sender common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _AutomationRegistry.Contract.OnTokenTransfer(&_AutomationRegistry.TransactOpts, sender, amount, data) +} + +func (_AutomationRegistry *AutomationRegistryTransactorSession) OnTokenTransfer(sender common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _AutomationRegistry.Contract.OnTokenTransfer(&_AutomationRegistry.TransactOpts, sender, amount, data) +} + +func (_AutomationRegistry *AutomationRegistryTransactor) SetConfig(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _AutomationRegistry.contract.Transact(opts, "setConfig", signers, transmitters, f, onchainConfigBytes, offchainConfigVersion, offchainConfig) +} + +func (_AutomationRegistry *AutomationRegistrySession) SetConfig(signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _AutomationRegistry.Contract.SetConfig(&_AutomationRegistry.TransactOpts, signers, transmitters, f, onchainConfigBytes, offchainConfigVersion, offchainConfig) +} + +func (_AutomationRegistry *AutomationRegistryTransactorSession) SetConfig(signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _AutomationRegistry.Contract.SetConfig(&_AutomationRegistry.TransactOpts, signers, transmitters, f, onchainConfigBytes, offchainConfigVersion, offchainConfig) +} + +func (_AutomationRegistry *AutomationRegistryTransactor) SetConfigTypeSafe(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig AutomationRegistryBase23OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _AutomationRegistry.contract.Transact(opts, "setConfigTypeSafe", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_AutomationRegistry *AutomationRegistrySession) SetConfigTypeSafe(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig AutomationRegistryBase23OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _AutomationRegistry.Contract.SetConfigTypeSafe(&_AutomationRegistry.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_AutomationRegistry *AutomationRegistryTransactorSession) SetConfigTypeSafe(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig AutomationRegistryBase23OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _AutomationRegistry.Contract.SetConfigTypeSafe(&_AutomationRegistry.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_AutomationRegistry *AutomationRegistryTransactor) SimulatePerformUpkeep(opts *bind.TransactOpts, id *big.Int, performData []byte) (*types.Transaction, error) { + return _AutomationRegistry.contract.Transact(opts, "simulatePerformUpkeep", id, performData) +} + +func (_AutomationRegistry *AutomationRegistrySession) SimulatePerformUpkeep(id *big.Int, performData []byte) (*types.Transaction, error) { + return _AutomationRegistry.Contract.SimulatePerformUpkeep(&_AutomationRegistry.TransactOpts, id, performData) +} + +func (_AutomationRegistry *AutomationRegistryTransactorSession) SimulatePerformUpkeep(id *big.Int, performData []byte) (*types.Transaction, error) { + return _AutomationRegistry.Contract.SimulatePerformUpkeep(&_AutomationRegistry.TransactOpts, id, performData) +} + +func (_AutomationRegistry *AutomationRegistryTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _AutomationRegistry.contract.Transact(opts, "transferOwnership", to) +} + +func (_AutomationRegistry *AutomationRegistrySession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _AutomationRegistry.Contract.TransferOwnership(&_AutomationRegistry.TransactOpts, to) +} + +func (_AutomationRegistry *AutomationRegistryTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _AutomationRegistry.Contract.TransferOwnership(&_AutomationRegistry.TransactOpts, to) +} + +func (_AutomationRegistry *AutomationRegistryTransactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, rawReport []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _AutomationRegistry.contract.Transact(opts, "transmit", reportContext, rawReport, rs, ss, rawVs) +} + +func (_AutomationRegistry *AutomationRegistrySession) Transmit(reportContext [3][32]byte, rawReport []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _AutomationRegistry.Contract.Transmit(&_AutomationRegistry.TransactOpts, reportContext, rawReport, rs, ss, rawVs) +} + +func (_AutomationRegistry *AutomationRegistryTransactorSession) Transmit(reportContext [3][32]byte, rawReport []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _AutomationRegistry.Contract.Transmit(&_AutomationRegistry.TransactOpts, reportContext, rawReport, rs, ss, rawVs) +} + +func (_AutomationRegistry *AutomationRegistryTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _AutomationRegistry.contract.RawTransact(opts, calldata) +} + +func (_AutomationRegistry *AutomationRegistrySession) Fallback(calldata []byte) (*types.Transaction, error) { + return _AutomationRegistry.Contract.Fallback(&_AutomationRegistry.TransactOpts, calldata) +} + +func (_AutomationRegistry *AutomationRegistryTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _AutomationRegistry.Contract.Fallback(&_AutomationRegistry.TransactOpts, calldata) +} + +type AutomationRegistryAdminPrivilegeConfigSetIterator struct { + Event *AutomationRegistryAdminPrivilegeConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryAdminPrivilegeConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryAdminPrivilegeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryAdminPrivilegeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryAdminPrivilegeConfigSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryAdminPrivilegeConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryAdminPrivilegeConfigSet struct { + Admin common.Address + PrivilegeConfig []byte + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterAdminPrivilegeConfigSet(opts *bind.FilterOpts, admin []common.Address) (*AutomationRegistryAdminPrivilegeConfigSetIterator, error) { + + var adminRule []interface{} + for _, adminItem := range admin { + adminRule = append(adminRule, adminItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "AdminPrivilegeConfigSet", adminRule) + if err != nil { + return nil, err + } + return &AutomationRegistryAdminPrivilegeConfigSetIterator{contract: _AutomationRegistry.contract, event: "AdminPrivilegeConfigSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchAdminPrivilegeConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryAdminPrivilegeConfigSet, admin []common.Address) (event.Subscription, error) { + + var adminRule []interface{} + for _, adminItem := range admin { + adminRule = append(adminRule, adminItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "AdminPrivilegeConfigSet", adminRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryAdminPrivilegeConfigSet) + if err := _AutomationRegistry.contract.UnpackLog(event, "AdminPrivilegeConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseAdminPrivilegeConfigSet(log types.Log) (*AutomationRegistryAdminPrivilegeConfigSet, error) { + event := new(AutomationRegistryAdminPrivilegeConfigSet) + if err := _AutomationRegistry.contract.UnpackLog(event, "AdminPrivilegeConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryCancelledUpkeepReportIterator struct { + Event *AutomationRegistryCancelledUpkeepReport + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryCancelledUpkeepReportIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryCancelledUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryCancelledUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryCancelledUpkeepReportIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryCancelledUpkeepReportIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryCancelledUpkeepReport struct { + Id *big.Int + Trigger []byte + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterCancelledUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryCancelledUpkeepReportIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "CancelledUpkeepReport", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryCancelledUpkeepReportIterator{contract: _AutomationRegistry.contract, event: "CancelledUpkeepReport", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchCancelledUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryCancelledUpkeepReport, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "CancelledUpkeepReport", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryCancelledUpkeepReport) + if err := _AutomationRegistry.contract.UnpackLog(event, "CancelledUpkeepReport", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseCancelledUpkeepReport(log types.Log) (*AutomationRegistryCancelledUpkeepReport, error) { + event := new(AutomationRegistryCancelledUpkeepReport) + if err := _AutomationRegistry.contract.UnpackLog(event, "CancelledUpkeepReport", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryChainSpecificModuleUpdatedIterator struct { + Event *AutomationRegistryChainSpecificModuleUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryChainSpecificModuleUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryChainSpecificModuleUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryChainSpecificModuleUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryChainSpecificModuleUpdatedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryChainSpecificModuleUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryChainSpecificModuleUpdated struct { + NewModule common.Address + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterChainSpecificModuleUpdated(opts *bind.FilterOpts) (*AutomationRegistryChainSpecificModuleUpdatedIterator, error) { + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "ChainSpecificModuleUpdated") + if err != nil { + return nil, err + } + return &AutomationRegistryChainSpecificModuleUpdatedIterator{contract: _AutomationRegistry.contract, event: "ChainSpecificModuleUpdated", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchChainSpecificModuleUpdated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryChainSpecificModuleUpdated) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "ChainSpecificModuleUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryChainSpecificModuleUpdated) + if err := _AutomationRegistry.contract.UnpackLog(event, "ChainSpecificModuleUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseChainSpecificModuleUpdated(log types.Log) (*AutomationRegistryChainSpecificModuleUpdated, error) { + event := new(AutomationRegistryChainSpecificModuleUpdated) + if err := _AutomationRegistry.contract.UnpackLog(event, "ChainSpecificModuleUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryConfigSetIterator struct { + Event *AutomationRegistryConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryConfigSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryConfigSet struct { + PreviousConfigBlockNumber uint32 + ConfigDigest [32]byte + ConfigCount uint64 + Signers []common.Address + Transmitters []common.Address + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterConfigSet(opts *bind.FilterOpts) (*AutomationRegistryConfigSetIterator, error) { + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &AutomationRegistryConfigSetIterator{contract: _AutomationRegistry.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryConfigSet) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryConfigSet) + if err := _AutomationRegistry.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseConfigSet(log types.Log) (*AutomationRegistryConfigSet, error) { + event := new(AutomationRegistryConfigSet) + if err := _AutomationRegistry.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryDedupKeyAddedIterator struct { + Event *AutomationRegistryDedupKeyAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryDedupKeyAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryDedupKeyAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryDedupKeyAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryDedupKeyAddedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryDedupKeyAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryDedupKeyAdded struct { + DedupKey [32]byte + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterDedupKeyAdded(opts *bind.FilterOpts, dedupKey [][32]byte) (*AutomationRegistryDedupKeyAddedIterator, error) { + + var dedupKeyRule []interface{} + for _, dedupKeyItem := range dedupKey { + dedupKeyRule = append(dedupKeyRule, dedupKeyItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "DedupKeyAdded", dedupKeyRule) + if err != nil { + return nil, err + } + return &AutomationRegistryDedupKeyAddedIterator{contract: _AutomationRegistry.contract, event: "DedupKeyAdded", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchDedupKeyAdded(opts *bind.WatchOpts, sink chan<- *AutomationRegistryDedupKeyAdded, dedupKey [][32]byte) (event.Subscription, error) { + + var dedupKeyRule []interface{} + for _, dedupKeyItem := range dedupKey { + dedupKeyRule = append(dedupKeyRule, dedupKeyItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "DedupKeyAdded", dedupKeyRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryDedupKeyAdded) + if err := _AutomationRegistry.contract.UnpackLog(event, "DedupKeyAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseDedupKeyAdded(log types.Log) (*AutomationRegistryDedupKeyAdded, error) { + event := new(AutomationRegistryDedupKeyAdded) + if err := _AutomationRegistry.contract.UnpackLog(event, "DedupKeyAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryFundsAddedIterator struct { + Event *AutomationRegistryFundsAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryFundsAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryFundsAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryFundsAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryFundsAddedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryFundsAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryFundsAdded struct { + Id *big.Int + From common.Address + Amount *big.Int + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterFundsAdded(opts *bind.FilterOpts, id []*big.Int, from []common.Address) (*AutomationRegistryFundsAddedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "FundsAdded", idRule, fromRule) + if err != nil { + return nil, err + } + return &AutomationRegistryFundsAddedIterator{contract: _AutomationRegistry.contract, event: "FundsAdded", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchFundsAdded(opts *bind.WatchOpts, sink chan<- *AutomationRegistryFundsAdded, id []*big.Int, from []common.Address) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "FundsAdded", idRule, fromRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryFundsAdded) + if err := _AutomationRegistry.contract.UnpackLog(event, "FundsAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseFundsAdded(log types.Log) (*AutomationRegistryFundsAdded, error) { + event := new(AutomationRegistryFundsAdded) + if err := _AutomationRegistry.contract.UnpackLog(event, "FundsAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryFundsWithdrawnIterator struct { + Event *AutomationRegistryFundsWithdrawn + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryFundsWithdrawnIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryFundsWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryFundsWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryFundsWithdrawnIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryFundsWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryFundsWithdrawn struct { + Id *big.Int + Amount *big.Int + To common.Address + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterFundsWithdrawn(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryFundsWithdrawnIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "FundsWithdrawn", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryFundsWithdrawnIterator{contract: _AutomationRegistry.contract, event: "FundsWithdrawn", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchFundsWithdrawn(opts *bind.WatchOpts, sink chan<- *AutomationRegistryFundsWithdrawn, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "FundsWithdrawn", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryFundsWithdrawn) + if err := _AutomationRegistry.contract.UnpackLog(event, "FundsWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseFundsWithdrawn(log types.Log) (*AutomationRegistryFundsWithdrawn, error) { + event := new(AutomationRegistryFundsWithdrawn) + if err := _AutomationRegistry.contract.UnpackLog(event, "FundsWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryInsufficientFundsUpkeepReportIterator struct { + Event *AutomationRegistryInsufficientFundsUpkeepReport + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryInsufficientFundsUpkeepReportIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryInsufficientFundsUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryInsufficientFundsUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryInsufficientFundsUpkeepReportIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryInsufficientFundsUpkeepReportIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryInsufficientFundsUpkeepReport struct { + Id *big.Int + Trigger []byte + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterInsufficientFundsUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryInsufficientFundsUpkeepReportIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "InsufficientFundsUpkeepReport", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryInsufficientFundsUpkeepReportIterator{contract: _AutomationRegistry.contract, event: "InsufficientFundsUpkeepReport", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchInsufficientFundsUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryInsufficientFundsUpkeepReport, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "InsufficientFundsUpkeepReport", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryInsufficientFundsUpkeepReport) + if err := _AutomationRegistry.contract.UnpackLog(event, "InsufficientFundsUpkeepReport", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseInsufficientFundsUpkeepReport(log types.Log) (*AutomationRegistryInsufficientFundsUpkeepReport, error) { + event := new(AutomationRegistryInsufficientFundsUpkeepReport) + if err := _AutomationRegistry.contract.UnpackLog(event, "InsufficientFundsUpkeepReport", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryOwnerFundsWithdrawnIterator struct { + Event *AutomationRegistryOwnerFundsWithdrawn + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryOwnerFundsWithdrawnIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryOwnerFundsWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryOwnerFundsWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryOwnerFundsWithdrawnIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryOwnerFundsWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryOwnerFundsWithdrawn struct { + Amount *big.Int + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterOwnerFundsWithdrawn(opts *bind.FilterOpts) (*AutomationRegistryOwnerFundsWithdrawnIterator, error) { + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "OwnerFundsWithdrawn") + if err != nil { + return nil, err + } + return &AutomationRegistryOwnerFundsWithdrawnIterator{contract: _AutomationRegistry.contract, event: "OwnerFundsWithdrawn", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchOwnerFundsWithdrawn(opts *bind.WatchOpts, sink chan<- *AutomationRegistryOwnerFundsWithdrawn) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "OwnerFundsWithdrawn") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryOwnerFundsWithdrawn) + if err := _AutomationRegistry.contract.UnpackLog(event, "OwnerFundsWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseOwnerFundsWithdrawn(log types.Log) (*AutomationRegistryOwnerFundsWithdrawn, error) { + event := new(AutomationRegistryOwnerFundsWithdrawn) + if err := _AutomationRegistry.contract.UnpackLog(event, "OwnerFundsWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryOwnershipTransferRequestedIterator struct { + Event *AutomationRegistryOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*AutomationRegistryOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryOwnershipTransferRequestedIterator{contract: _AutomationRegistry.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryOwnershipTransferRequested) + if err := _AutomationRegistry.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseOwnershipTransferRequested(log types.Log) (*AutomationRegistryOwnershipTransferRequested, error) { + event := new(AutomationRegistryOwnershipTransferRequested) + if err := _AutomationRegistry.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryOwnershipTransferredIterator struct { + Event *AutomationRegistryOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*AutomationRegistryOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryOwnershipTransferredIterator{contract: _AutomationRegistry.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistryOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryOwnershipTransferred) + if err := _AutomationRegistry.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseOwnershipTransferred(log types.Log) (*AutomationRegistryOwnershipTransferred, error) { + event := new(AutomationRegistryOwnershipTransferred) + if err := _AutomationRegistry.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryPausedIterator struct { + Event *AutomationRegistryPaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryPausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryPausedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryPaused struct { + Account common.Address + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterPaused(opts *bind.FilterOpts) (*AutomationRegistryPausedIterator, error) { + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &AutomationRegistryPausedIterator{contract: _AutomationRegistry.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryPaused) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "Paused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryPaused) + if err := _AutomationRegistry.contract.UnpackLog(event, "Paused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParsePaused(log types.Log) (*AutomationRegistryPaused, error) { + event := new(AutomationRegistryPaused) + if err := _AutomationRegistry.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryPayeesUpdatedIterator struct { + Event *AutomationRegistryPayeesUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryPayeesUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryPayeesUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryPayeesUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryPayeesUpdatedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryPayeesUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryPayeesUpdated struct { + Transmitters []common.Address + Payees []common.Address + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterPayeesUpdated(opts *bind.FilterOpts) (*AutomationRegistryPayeesUpdatedIterator, error) { + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "PayeesUpdated") + if err != nil { + return nil, err + } + return &AutomationRegistryPayeesUpdatedIterator{contract: _AutomationRegistry.contract, event: "PayeesUpdated", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchPayeesUpdated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryPayeesUpdated) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "PayeesUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryPayeesUpdated) + if err := _AutomationRegistry.contract.UnpackLog(event, "PayeesUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParsePayeesUpdated(log types.Log) (*AutomationRegistryPayeesUpdated, error) { + event := new(AutomationRegistryPayeesUpdated) + if err := _AutomationRegistry.contract.UnpackLog(event, "PayeesUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryPayeeshipTransferRequestedIterator struct { + Event *AutomationRegistryPayeeshipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryPayeeshipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryPayeeshipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryPayeeshipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryPayeeshipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryPayeeshipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryPayeeshipTransferRequested struct { + Transmitter common.Address + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterPayeeshipTransferRequested(opts *bind.FilterOpts, transmitter []common.Address, from []common.Address, to []common.Address) (*AutomationRegistryPayeeshipTransferRequestedIterator, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "PayeeshipTransferRequested", transmitterRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryPayeeshipTransferRequestedIterator{contract: _AutomationRegistry.contract, event: "PayeeshipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchPayeeshipTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistryPayeeshipTransferRequested, transmitter []common.Address, from []common.Address, to []common.Address) (event.Subscription, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "PayeeshipTransferRequested", transmitterRule, fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryPayeeshipTransferRequested) + if err := _AutomationRegistry.contract.UnpackLog(event, "PayeeshipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParsePayeeshipTransferRequested(log types.Log) (*AutomationRegistryPayeeshipTransferRequested, error) { + event := new(AutomationRegistryPayeeshipTransferRequested) + if err := _AutomationRegistry.contract.UnpackLog(event, "PayeeshipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryPayeeshipTransferredIterator struct { + Event *AutomationRegistryPayeeshipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryPayeeshipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryPayeeshipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryPayeeshipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryPayeeshipTransferredIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryPayeeshipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryPayeeshipTransferred struct { + Transmitter common.Address + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterPayeeshipTransferred(opts *bind.FilterOpts, transmitter []common.Address, from []common.Address, to []common.Address) (*AutomationRegistryPayeeshipTransferredIterator, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "PayeeshipTransferred", transmitterRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryPayeeshipTransferredIterator{contract: _AutomationRegistry.contract, event: "PayeeshipTransferred", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchPayeeshipTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistryPayeeshipTransferred, transmitter []common.Address, from []common.Address, to []common.Address) (event.Subscription, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "PayeeshipTransferred", transmitterRule, fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryPayeeshipTransferred) + if err := _AutomationRegistry.contract.UnpackLog(event, "PayeeshipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParsePayeeshipTransferred(log types.Log) (*AutomationRegistryPayeeshipTransferred, error) { + event := new(AutomationRegistryPayeeshipTransferred) + if err := _AutomationRegistry.contract.UnpackLog(event, "PayeeshipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryPaymentWithdrawnIterator struct { + Event *AutomationRegistryPaymentWithdrawn + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryPaymentWithdrawnIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryPaymentWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryPaymentWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryPaymentWithdrawnIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryPaymentWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryPaymentWithdrawn struct { + Transmitter common.Address + Amount *big.Int + To common.Address + Payee common.Address + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterPaymentWithdrawn(opts *bind.FilterOpts, transmitter []common.Address, amount []*big.Int, to []common.Address) (*AutomationRegistryPaymentWithdrawnIterator, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "PaymentWithdrawn", transmitterRule, amountRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryPaymentWithdrawnIterator{contract: _AutomationRegistry.contract, event: "PaymentWithdrawn", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchPaymentWithdrawn(opts *bind.WatchOpts, sink chan<- *AutomationRegistryPaymentWithdrawn, transmitter []common.Address, amount []*big.Int, to []common.Address) (event.Subscription, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "PaymentWithdrawn", transmitterRule, amountRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryPaymentWithdrawn) + if err := _AutomationRegistry.contract.UnpackLog(event, "PaymentWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParsePaymentWithdrawn(log types.Log) (*AutomationRegistryPaymentWithdrawn, error) { + event := new(AutomationRegistryPaymentWithdrawn) + if err := _AutomationRegistry.contract.UnpackLog(event, "PaymentWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryReorgedUpkeepReportIterator struct { + Event *AutomationRegistryReorgedUpkeepReport + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryReorgedUpkeepReportIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryReorgedUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryReorgedUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryReorgedUpkeepReportIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryReorgedUpkeepReportIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryReorgedUpkeepReport struct { + Id *big.Int + Trigger []byte + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterReorgedUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryReorgedUpkeepReportIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "ReorgedUpkeepReport", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryReorgedUpkeepReportIterator{contract: _AutomationRegistry.contract, event: "ReorgedUpkeepReport", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchReorgedUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryReorgedUpkeepReport, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "ReorgedUpkeepReport", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryReorgedUpkeepReport) + if err := _AutomationRegistry.contract.UnpackLog(event, "ReorgedUpkeepReport", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseReorgedUpkeepReport(log types.Log) (*AutomationRegistryReorgedUpkeepReport, error) { + event := new(AutomationRegistryReorgedUpkeepReport) + if err := _AutomationRegistry.contract.UnpackLog(event, "ReorgedUpkeepReport", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryStaleUpkeepReportIterator struct { + Event *AutomationRegistryStaleUpkeepReport + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryStaleUpkeepReportIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryStaleUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryStaleUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryStaleUpkeepReportIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryStaleUpkeepReportIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryStaleUpkeepReport struct { + Id *big.Int + Trigger []byte + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterStaleUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryStaleUpkeepReportIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "StaleUpkeepReport", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryStaleUpkeepReportIterator{contract: _AutomationRegistry.contract, event: "StaleUpkeepReport", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchStaleUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryStaleUpkeepReport, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "StaleUpkeepReport", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryStaleUpkeepReport) + if err := _AutomationRegistry.contract.UnpackLog(event, "StaleUpkeepReport", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseStaleUpkeepReport(log types.Log) (*AutomationRegistryStaleUpkeepReport, error) { + event := new(AutomationRegistryStaleUpkeepReport) + if err := _AutomationRegistry.contract.UnpackLog(event, "StaleUpkeepReport", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryTransmittedIterator struct { + Event *AutomationRegistryTransmitted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryTransmittedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryTransmittedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryTransmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryTransmitted struct { + ConfigDigest [32]byte + Epoch uint32 + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterTransmitted(opts *bind.FilterOpts) (*AutomationRegistryTransmittedIterator, error) { + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return &AutomationRegistryTransmittedIterator{contract: _AutomationRegistry.contract, event: "Transmitted", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *AutomationRegistryTransmitted) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryTransmitted) + if err := _AutomationRegistry.contract.UnpackLog(event, "Transmitted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseTransmitted(log types.Log) (*AutomationRegistryTransmitted, error) { + event := new(AutomationRegistryTransmitted) + if err := _AutomationRegistry.contract.UnpackLog(event, "Transmitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryUnpausedIterator struct { + Event *AutomationRegistryUnpaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryUnpausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryUnpausedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryUnpaused struct { + Account common.Address + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterUnpaused(opts *bind.FilterOpts) (*AutomationRegistryUnpausedIterator, error) { + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &AutomationRegistryUnpausedIterator{contract: _AutomationRegistry.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUnpaused) (event.Subscription, error) { + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryUnpaused) + if err := _AutomationRegistry.contract.UnpackLog(event, "Unpaused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseUnpaused(log types.Log) (*AutomationRegistryUnpaused, error) { + event := new(AutomationRegistryUnpaused) + if err := _AutomationRegistry.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryUpkeepAdminTransferRequestedIterator struct { + Event *AutomationRegistryUpkeepAdminTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryUpkeepAdminTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepAdminTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepAdminTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryUpkeepAdminTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryUpkeepAdminTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryUpkeepAdminTransferRequested struct { + Id *big.Int + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterUpkeepAdminTransferRequested(opts *bind.FilterOpts, id []*big.Int, from []common.Address, to []common.Address) (*AutomationRegistryUpkeepAdminTransferRequestedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "UpkeepAdminTransferRequested", idRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryUpkeepAdminTransferRequestedIterator{contract: _AutomationRegistry.contract, event: "UpkeepAdminTransferRequested", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchUpkeepAdminTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepAdminTransferRequested, id []*big.Int, from []common.Address, to []common.Address) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "UpkeepAdminTransferRequested", idRule, fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryUpkeepAdminTransferRequested) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepAdminTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseUpkeepAdminTransferRequested(log types.Log) (*AutomationRegistryUpkeepAdminTransferRequested, error) { + event := new(AutomationRegistryUpkeepAdminTransferRequested) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepAdminTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryUpkeepAdminTransferredIterator struct { + Event *AutomationRegistryUpkeepAdminTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryUpkeepAdminTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepAdminTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepAdminTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryUpkeepAdminTransferredIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryUpkeepAdminTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryUpkeepAdminTransferred struct { + Id *big.Int + From common.Address + To common.Address + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterUpkeepAdminTransferred(opts *bind.FilterOpts, id []*big.Int, from []common.Address, to []common.Address) (*AutomationRegistryUpkeepAdminTransferredIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "UpkeepAdminTransferred", idRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &AutomationRegistryUpkeepAdminTransferredIterator{contract: _AutomationRegistry.contract, event: "UpkeepAdminTransferred", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchUpkeepAdminTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepAdminTransferred, id []*big.Int, from []common.Address, to []common.Address) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "UpkeepAdminTransferred", idRule, fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryUpkeepAdminTransferred) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepAdminTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseUpkeepAdminTransferred(log types.Log) (*AutomationRegistryUpkeepAdminTransferred, error) { + event := new(AutomationRegistryUpkeepAdminTransferred) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepAdminTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryUpkeepCanceledIterator struct { + Event *AutomationRegistryUpkeepCanceled + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryUpkeepCanceledIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepCanceled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepCanceled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryUpkeepCanceledIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryUpkeepCanceledIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryUpkeepCanceled struct { + Id *big.Int + AtBlockHeight uint64 + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterUpkeepCanceled(opts *bind.FilterOpts, id []*big.Int, atBlockHeight []uint64) (*AutomationRegistryUpkeepCanceledIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var atBlockHeightRule []interface{} + for _, atBlockHeightItem := range atBlockHeight { + atBlockHeightRule = append(atBlockHeightRule, atBlockHeightItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "UpkeepCanceled", idRule, atBlockHeightRule) + if err != nil { + return nil, err + } + return &AutomationRegistryUpkeepCanceledIterator{contract: _AutomationRegistry.contract, event: "UpkeepCanceled", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchUpkeepCanceled(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepCanceled, id []*big.Int, atBlockHeight []uint64) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var atBlockHeightRule []interface{} + for _, atBlockHeightItem := range atBlockHeight { + atBlockHeightRule = append(atBlockHeightRule, atBlockHeightItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "UpkeepCanceled", idRule, atBlockHeightRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryUpkeepCanceled) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepCanceled", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseUpkeepCanceled(log types.Log) (*AutomationRegistryUpkeepCanceled, error) { + event := new(AutomationRegistryUpkeepCanceled) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepCanceled", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryUpkeepCheckDataSetIterator struct { + Event *AutomationRegistryUpkeepCheckDataSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryUpkeepCheckDataSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepCheckDataSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepCheckDataSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryUpkeepCheckDataSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryUpkeepCheckDataSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryUpkeepCheckDataSet struct { + Id *big.Int + NewCheckData []byte + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterUpkeepCheckDataSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryUpkeepCheckDataSetIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "UpkeepCheckDataSet", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryUpkeepCheckDataSetIterator{contract: _AutomationRegistry.contract, event: "UpkeepCheckDataSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchUpkeepCheckDataSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepCheckDataSet, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "UpkeepCheckDataSet", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryUpkeepCheckDataSet) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepCheckDataSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseUpkeepCheckDataSet(log types.Log) (*AutomationRegistryUpkeepCheckDataSet, error) { + event := new(AutomationRegistryUpkeepCheckDataSet) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepCheckDataSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryUpkeepGasLimitSetIterator struct { + Event *AutomationRegistryUpkeepGasLimitSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryUpkeepGasLimitSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepGasLimitSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepGasLimitSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryUpkeepGasLimitSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryUpkeepGasLimitSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryUpkeepGasLimitSet struct { + Id *big.Int + GasLimit *big.Int + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterUpkeepGasLimitSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryUpkeepGasLimitSetIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "UpkeepGasLimitSet", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryUpkeepGasLimitSetIterator{contract: _AutomationRegistry.contract, event: "UpkeepGasLimitSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchUpkeepGasLimitSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepGasLimitSet, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "UpkeepGasLimitSet", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryUpkeepGasLimitSet) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepGasLimitSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseUpkeepGasLimitSet(log types.Log) (*AutomationRegistryUpkeepGasLimitSet, error) { + event := new(AutomationRegistryUpkeepGasLimitSet) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepGasLimitSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryUpkeepMigratedIterator struct { + Event *AutomationRegistryUpkeepMigrated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryUpkeepMigratedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepMigrated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepMigrated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryUpkeepMigratedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryUpkeepMigratedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryUpkeepMigrated struct { + Id *big.Int + RemainingBalance *big.Int + Destination common.Address + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterUpkeepMigrated(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryUpkeepMigratedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "UpkeepMigrated", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryUpkeepMigratedIterator{contract: _AutomationRegistry.contract, event: "UpkeepMigrated", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchUpkeepMigrated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepMigrated, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "UpkeepMigrated", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryUpkeepMigrated) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepMigrated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseUpkeepMigrated(log types.Log) (*AutomationRegistryUpkeepMigrated, error) { + event := new(AutomationRegistryUpkeepMigrated) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepMigrated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryUpkeepOffchainConfigSetIterator struct { + Event *AutomationRegistryUpkeepOffchainConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryUpkeepOffchainConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepOffchainConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepOffchainConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryUpkeepOffchainConfigSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryUpkeepOffchainConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryUpkeepOffchainConfigSet struct { + Id *big.Int + OffchainConfig []byte + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterUpkeepOffchainConfigSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryUpkeepOffchainConfigSetIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "UpkeepOffchainConfigSet", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryUpkeepOffchainConfigSetIterator{contract: _AutomationRegistry.contract, event: "UpkeepOffchainConfigSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchUpkeepOffchainConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepOffchainConfigSet, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "UpkeepOffchainConfigSet", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryUpkeepOffchainConfigSet) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepOffchainConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseUpkeepOffchainConfigSet(log types.Log) (*AutomationRegistryUpkeepOffchainConfigSet, error) { + event := new(AutomationRegistryUpkeepOffchainConfigSet) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepOffchainConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryUpkeepPausedIterator struct { + Event *AutomationRegistryUpkeepPaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryUpkeepPausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryUpkeepPausedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryUpkeepPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryUpkeepPaused struct { + Id *big.Int + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterUpkeepPaused(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryUpkeepPausedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "UpkeepPaused", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryUpkeepPausedIterator{contract: _AutomationRegistry.contract, event: "UpkeepPaused", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchUpkeepPaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepPaused, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "UpkeepPaused", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryUpkeepPaused) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepPaused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseUpkeepPaused(log types.Log) (*AutomationRegistryUpkeepPaused, error) { + event := new(AutomationRegistryUpkeepPaused) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepPaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryUpkeepPerformedIterator struct { + Event *AutomationRegistryUpkeepPerformed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryUpkeepPerformedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepPerformed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepPerformed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryUpkeepPerformedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryUpkeepPerformedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryUpkeepPerformed struct { + Id *big.Int + Success bool + TotalPayment *big.Int + GasUsed *big.Int + GasOverhead *big.Int + Trigger []byte + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterUpkeepPerformed(opts *bind.FilterOpts, id []*big.Int, success []bool) (*AutomationRegistryUpkeepPerformedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var successRule []interface{} + for _, successItem := range success { + successRule = append(successRule, successItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "UpkeepPerformed", idRule, successRule) + if err != nil { + return nil, err + } + return &AutomationRegistryUpkeepPerformedIterator{contract: _AutomationRegistry.contract, event: "UpkeepPerformed", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchUpkeepPerformed(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepPerformed, id []*big.Int, success []bool) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var successRule []interface{} + for _, successItem := range success { + successRule = append(successRule, successItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "UpkeepPerformed", idRule, successRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryUpkeepPerformed) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepPerformed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseUpkeepPerformed(log types.Log) (*AutomationRegistryUpkeepPerformed, error) { + event := new(AutomationRegistryUpkeepPerformed) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepPerformed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryUpkeepPrivilegeConfigSetIterator struct { + Event *AutomationRegistryUpkeepPrivilegeConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryUpkeepPrivilegeConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepPrivilegeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepPrivilegeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryUpkeepPrivilegeConfigSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryUpkeepPrivilegeConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryUpkeepPrivilegeConfigSet struct { + Id *big.Int + PrivilegeConfig []byte + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterUpkeepPrivilegeConfigSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryUpkeepPrivilegeConfigSetIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "UpkeepPrivilegeConfigSet", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryUpkeepPrivilegeConfigSetIterator{contract: _AutomationRegistry.contract, event: "UpkeepPrivilegeConfigSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchUpkeepPrivilegeConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepPrivilegeConfigSet, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "UpkeepPrivilegeConfigSet", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryUpkeepPrivilegeConfigSet) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepPrivilegeConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseUpkeepPrivilegeConfigSet(log types.Log) (*AutomationRegistryUpkeepPrivilegeConfigSet, error) { + event := new(AutomationRegistryUpkeepPrivilegeConfigSet) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepPrivilegeConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryUpkeepReceivedIterator struct { + Event *AutomationRegistryUpkeepReceived + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryUpkeepReceivedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryUpkeepReceivedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryUpkeepReceivedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryUpkeepReceived struct { + Id *big.Int + StartingBalance *big.Int + ImportedFrom common.Address + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterUpkeepReceived(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryUpkeepReceivedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "UpkeepReceived", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryUpkeepReceivedIterator{contract: _AutomationRegistry.contract, event: "UpkeepReceived", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchUpkeepReceived(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepReceived, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "UpkeepReceived", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryUpkeepReceived) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepReceived", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseUpkeepReceived(log types.Log) (*AutomationRegistryUpkeepReceived, error) { + event := new(AutomationRegistryUpkeepReceived) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepReceived", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryUpkeepRegisteredIterator struct { + Event *AutomationRegistryUpkeepRegistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryUpkeepRegisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryUpkeepRegisteredIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryUpkeepRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryUpkeepRegistered struct { + Id *big.Int + PerformGas uint32 + Admin common.Address + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterUpkeepRegistered(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryUpkeepRegisteredIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "UpkeepRegistered", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryUpkeepRegisteredIterator{contract: _AutomationRegistry.contract, event: "UpkeepRegistered", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchUpkeepRegistered(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepRegistered, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "UpkeepRegistered", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryUpkeepRegistered) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseUpkeepRegistered(log types.Log) (*AutomationRegistryUpkeepRegistered, error) { + event := new(AutomationRegistryUpkeepRegistered) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryUpkeepTriggerConfigSetIterator struct { + Event *AutomationRegistryUpkeepTriggerConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryUpkeepTriggerConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepTriggerConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepTriggerConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryUpkeepTriggerConfigSetIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryUpkeepTriggerConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryUpkeepTriggerConfigSet struct { + Id *big.Int + TriggerConfig []byte + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterUpkeepTriggerConfigSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryUpkeepTriggerConfigSetIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "UpkeepTriggerConfigSet", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryUpkeepTriggerConfigSetIterator{contract: _AutomationRegistry.contract, event: "UpkeepTriggerConfigSet", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchUpkeepTriggerConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepTriggerConfigSet, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "UpkeepTriggerConfigSet", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryUpkeepTriggerConfigSet) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepTriggerConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseUpkeepTriggerConfigSet(log types.Log) (*AutomationRegistryUpkeepTriggerConfigSet, error) { + event := new(AutomationRegistryUpkeepTriggerConfigSet) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepTriggerConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type AutomationRegistryUpkeepUnpausedIterator struct { + Event *AutomationRegistryUpkeepUnpaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *AutomationRegistryUpkeepUnpausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(AutomationRegistryUpkeepUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *AutomationRegistryUpkeepUnpausedIterator) Error() error { + return it.fail +} + +func (it *AutomationRegistryUpkeepUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type AutomationRegistryUpkeepUnpaused struct { + Id *big.Int + Raw types.Log +} + +func (_AutomationRegistry *AutomationRegistryFilterer) FilterUpkeepUnpaused(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryUpkeepUnpausedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.FilterLogs(opts, "UpkeepUnpaused", idRule) + if err != nil { + return nil, err + } + return &AutomationRegistryUpkeepUnpausedIterator{contract: _AutomationRegistry.contract, event: "UpkeepUnpaused", logs: logs, sub: sub}, nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) WatchUpkeepUnpaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepUnpaused, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _AutomationRegistry.contract.WatchLogs(opts, "UpkeepUnpaused", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(AutomationRegistryUpkeepUnpaused) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepUnpaused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_AutomationRegistry *AutomationRegistryFilterer) ParseUpkeepUnpaused(log types.Log) (*AutomationRegistryUpkeepUnpaused, error) { + event := new(AutomationRegistryUpkeepUnpaused) + if err := _AutomationRegistry.contract.UnpackLog(event, "UpkeepUnpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LatestConfigDetails struct { + ConfigCount uint32 + BlockNumber uint32 + ConfigDigest [32]byte +} +type LatestConfigDigestAndEpoch struct { + ScanLogs bool + ConfigDigest [32]byte + Epoch uint32 +} + +func (_AutomationRegistry *AutomationRegistry) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _AutomationRegistry.abi.Events["AdminPrivilegeConfigSet"].ID: + return _AutomationRegistry.ParseAdminPrivilegeConfigSet(log) + case _AutomationRegistry.abi.Events["CancelledUpkeepReport"].ID: + return _AutomationRegistry.ParseCancelledUpkeepReport(log) + case _AutomationRegistry.abi.Events["ChainSpecificModuleUpdated"].ID: + return _AutomationRegistry.ParseChainSpecificModuleUpdated(log) + case _AutomationRegistry.abi.Events["ConfigSet"].ID: + return _AutomationRegistry.ParseConfigSet(log) + case _AutomationRegistry.abi.Events["DedupKeyAdded"].ID: + return _AutomationRegistry.ParseDedupKeyAdded(log) + case _AutomationRegistry.abi.Events["FundsAdded"].ID: + return _AutomationRegistry.ParseFundsAdded(log) + case _AutomationRegistry.abi.Events["FundsWithdrawn"].ID: + return _AutomationRegistry.ParseFundsWithdrawn(log) + case _AutomationRegistry.abi.Events["InsufficientFundsUpkeepReport"].ID: + return _AutomationRegistry.ParseInsufficientFundsUpkeepReport(log) + case _AutomationRegistry.abi.Events["OwnerFundsWithdrawn"].ID: + return _AutomationRegistry.ParseOwnerFundsWithdrawn(log) + case _AutomationRegistry.abi.Events["OwnershipTransferRequested"].ID: + return _AutomationRegistry.ParseOwnershipTransferRequested(log) + case _AutomationRegistry.abi.Events["OwnershipTransferred"].ID: + return _AutomationRegistry.ParseOwnershipTransferred(log) + case _AutomationRegistry.abi.Events["Paused"].ID: + return _AutomationRegistry.ParsePaused(log) + case _AutomationRegistry.abi.Events["PayeesUpdated"].ID: + return _AutomationRegistry.ParsePayeesUpdated(log) + case _AutomationRegistry.abi.Events["PayeeshipTransferRequested"].ID: + return _AutomationRegistry.ParsePayeeshipTransferRequested(log) + case _AutomationRegistry.abi.Events["PayeeshipTransferred"].ID: + return _AutomationRegistry.ParsePayeeshipTransferred(log) + case _AutomationRegistry.abi.Events["PaymentWithdrawn"].ID: + return _AutomationRegistry.ParsePaymentWithdrawn(log) + case _AutomationRegistry.abi.Events["ReorgedUpkeepReport"].ID: + return _AutomationRegistry.ParseReorgedUpkeepReport(log) + case _AutomationRegistry.abi.Events["StaleUpkeepReport"].ID: + return _AutomationRegistry.ParseStaleUpkeepReport(log) + case _AutomationRegistry.abi.Events["Transmitted"].ID: + return _AutomationRegistry.ParseTransmitted(log) + case _AutomationRegistry.abi.Events["Unpaused"].ID: + return _AutomationRegistry.ParseUnpaused(log) + case _AutomationRegistry.abi.Events["UpkeepAdminTransferRequested"].ID: + return _AutomationRegistry.ParseUpkeepAdminTransferRequested(log) + case _AutomationRegistry.abi.Events["UpkeepAdminTransferred"].ID: + return _AutomationRegistry.ParseUpkeepAdminTransferred(log) + case _AutomationRegistry.abi.Events["UpkeepCanceled"].ID: + return _AutomationRegistry.ParseUpkeepCanceled(log) + case _AutomationRegistry.abi.Events["UpkeepCheckDataSet"].ID: + return _AutomationRegistry.ParseUpkeepCheckDataSet(log) + case _AutomationRegistry.abi.Events["UpkeepGasLimitSet"].ID: + return _AutomationRegistry.ParseUpkeepGasLimitSet(log) + case _AutomationRegistry.abi.Events["UpkeepMigrated"].ID: + return _AutomationRegistry.ParseUpkeepMigrated(log) + case _AutomationRegistry.abi.Events["UpkeepOffchainConfigSet"].ID: + return _AutomationRegistry.ParseUpkeepOffchainConfigSet(log) + case _AutomationRegistry.abi.Events["UpkeepPaused"].ID: + return _AutomationRegistry.ParseUpkeepPaused(log) + case _AutomationRegistry.abi.Events["UpkeepPerformed"].ID: + return _AutomationRegistry.ParseUpkeepPerformed(log) + case _AutomationRegistry.abi.Events["UpkeepPrivilegeConfigSet"].ID: + return _AutomationRegistry.ParseUpkeepPrivilegeConfigSet(log) + case _AutomationRegistry.abi.Events["UpkeepReceived"].ID: + return _AutomationRegistry.ParseUpkeepReceived(log) + case _AutomationRegistry.abi.Events["UpkeepRegistered"].ID: + return _AutomationRegistry.ParseUpkeepRegistered(log) + case _AutomationRegistry.abi.Events["UpkeepTriggerConfigSet"].ID: + return _AutomationRegistry.ParseUpkeepTriggerConfigSet(log) + case _AutomationRegistry.abi.Events["UpkeepUnpaused"].ID: + return _AutomationRegistry.ParseUpkeepUnpaused(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (AutomationRegistryAdminPrivilegeConfigSet) Topic() common.Hash { + return common.HexToHash("0x7c44b4eb59ee7873514e7e43e7718c269d872965938b288aa143befca62f99d2") +} + +func (AutomationRegistryCancelledUpkeepReport) Topic() common.Hash { + return common.HexToHash("0xc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636") +} + +func (AutomationRegistryChainSpecificModuleUpdated) Topic() common.Hash { + return common.HexToHash("0xdefc28b11a7980dbe0c49dbbd7055a1584bc8075097d1e8b3b57fb7283df2ad7") +} + +func (AutomationRegistryConfigSet) Topic() common.Hash { + return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") +} + +func (AutomationRegistryDedupKeyAdded) Topic() common.Hash { + return common.HexToHash("0xa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f2") +} + +func (AutomationRegistryFundsAdded) Topic() common.Hash { + return common.HexToHash("0xafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa734891506203") +} + +func (AutomationRegistryFundsWithdrawn) Topic() common.Hash { + return common.HexToHash("0xf3b5906e5672f3e524854103bcafbbdba80dbdfeca2c35e116127b1060a68318") +} + +func (AutomationRegistryInsufficientFundsUpkeepReport) Topic() common.Hash { + return common.HexToHash("0x377c8b0c126ae5248d27aca1c76fac4608aff85673ee3caf09747e1044549e02") +} + +func (AutomationRegistryOwnerFundsWithdrawn) Topic() common.Hash { + return common.HexToHash("0x1d07d0b0be43d3e5fee41a80b579af370affee03fa595bf56d5d4c19328162f1") +} + +func (AutomationRegistryOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (AutomationRegistryOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (AutomationRegistryPaused) Topic() common.Hash { + return common.HexToHash("0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258") +} + +func (AutomationRegistryPayeesUpdated) Topic() common.Hash { + return common.HexToHash("0xa46de38886467c59be07a0675f14781206a5477d871628af46c2443822fcb725") +} + +func (AutomationRegistryPayeeshipTransferRequested) Topic() common.Hash { + return common.HexToHash("0x84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e38367") +} + +func (AutomationRegistryPayeeshipTransferred) Topic() common.Hash { + return common.HexToHash("0x78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b3") +} + +func (AutomationRegistryPaymentWithdrawn) Topic() common.Hash { + return common.HexToHash("0x9819093176a1851202c7bcfa46845809b4e47c261866550e94ed3775d2f40698") +} + +func (AutomationRegistryReorgedUpkeepReport) Topic() common.Hash { + return common.HexToHash("0x6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301") +} + +func (AutomationRegistryStaleUpkeepReport) Topic() common.Hash { + return common.HexToHash("0x405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8") +} + +func (AutomationRegistryTransmitted) Topic() common.Hash { + return common.HexToHash("0xb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62") +} + +func (AutomationRegistryUnpaused) Topic() common.Hash { + return common.HexToHash("0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa") +} + +func (AutomationRegistryUpkeepAdminTransferRequested) Topic() common.Hash { + return common.HexToHash("0xb1cbb2c4b8480034c27e06da5f096b8233a8fd4497028593a41ff6df79726b35") +} + +func (AutomationRegistryUpkeepAdminTransferred) Topic() common.Hash { + return common.HexToHash("0x5cff4db96bef051785e999f44bfcd21c18823e034fb92dd376e3db4ce0feeb2c") +} + +func (AutomationRegistryUpkeepCanceled) Topic() common.Hash { + return common.HexToHash("0x91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f791181") +} + +func (AutomationRegistryUpkeepCheckDataSet) Topic() common.Hash { + return common.HexToHash("0xcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d") +} + +func (AutomationRegistryUpkeepGasLimitSet) Topic() common.Hash { + return common.HexToHash("0xc24c07e655ce79fba8a589778987d3c015bc6af1632bb20cf9182e02a65d972c") +} + +func (AutomationRegistryUpkeepMigrated) Topic() common.Hash { + return common.HexToHash("0xb38647142fbb1ea4c000fc4569b37a4e9a9f6313317b84ee3e5326c1a6cd06ff") +} + +func (AutomationRegistryUpkeepOffchainConfigSet) Topic() common.Hash { + return common.HexToHash("0x3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf4850") +} + +func (AutomationRegistryUpkeepPaused) Topic() common.Hash { + return common.HexToHash("0x8ab10247ce168c27748e656ecf852b951fcaac790c18106b19aa0ae57a8b741f") +} + +func (AutomationRegistryUpkeepPerformed) Topic() common.Hash { + return common.HexToHash("0xad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b") +} + +func (AutomationRegistryUpkeepPrivilegeConfigSet) Topic() common.Hash { + return common.HexToHash("0x2fd8d70753a007014349d4591843cc031c2dd7a260d7dd82eca8253686ae7769") +} + +func (AutomationRegistryUpkeepReceived) Topic() common.Hash { + return common.HexToHash("0x74931a144e43a50694897f241d973aecb5024c0e910f9bb80a163ea3c1cf5a71") +} + +func (AutomationRegistryUpkeepRegistered) Topic() common.Hash { + return common.HexToHash("0xbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d012") +} + +func (AutomationRegistryUpkeepTriggerConfigSet) Topic() common.Hash { + return common.HexToHash("0x2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d5664") +} + +func (AutomationRegistryUpkeepUnpaused) Topic() common.Hash { + return common.HexToHash("0x7bada562044eb163f6b4003c4553e4e62825344c0418eea087bed5ee05a47456") +} + +func (_AutomationRegistry *AutomationRegistry) Address() common.Address { + return _AutomationRegistry.address +} + +type AutomationRegistryInterface interface { + FallbackTo(opts *bind.CallOpts) (common.Address, error) + + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) + + LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + OnTokenTransfer(opts *bind.TransactOpts, sender common.Address, amount *big.Int, data []byte) (*types.Transaction, error) + + SetConfig(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + + SetConfigTypeSafe(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig AutomationRegistryBase23OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + + SimulatePerformUpkeep(opts *bind.TransactOpts, id *big.Int, performData []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, rawReport []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) + + Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) + + FilterAdminPrivilegeConfigSet(opts *bind.FilterOpts, admin []common.Address) (*AutomationRegistryAdminPrivilegeConfigSetIterator, error) + + WatchAdminPrivilegeConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryAdminPrivilegeConfigSet, admin []common.Address) (event.Subscription, error) + + ParseAdminPrivilegeConfigSet(log types.Log) (*AutomationRegistryAdminPrivilegeConfigSet, error) + + FilterCancelledUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryCancelledUpkeepReportIterator, error) + + WatchCancelledUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryCancelledUpkeepReport, id []*big.Int) (event.Subscription, error) + + ParseCancelledUpkeepReport(log types.Log) (*AutomationRegistryCancelledUpkeepReport, error) + + FilterChainSpecificModuleUpdated(opts *bind.FilterOpts) (*AutomationRegistryChainSpecificModuleUpdatedIterator, error) + + WatchChainSpecificModuleUpdated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryChainSpecificModuleUpdated) (event.Subscription, error) + + ParseChainSpecificModuleUpdated(log types.Log) (*AutomationRegistryChainSpecificModuleUpdated, error) + + FilterConfigSet(opts *bind.FilterOpts) (*AutomationRegistryConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*AutomationRegistryConfigSet, error) + + FilterDedupKeyAdded(opts *bind.FilterOpts, dedupKey [][32]byte) (*AutomationRegistryDedupKeyAddedIterator, error) + + WatchDedupKeyAdded(opts *bind.WatchOpts, sink chan<- *AutomationRegistryDedupKeyAdded, dedupKey [][32]byte) (event.Subscription, error) + + ParseDedupKeyAdded(log types.Log) (*AutomationRegistryDedupKeyAdded, error) + + FilterFundsAdded(opts *bind.FilterOpts, id []*big.Int, from []common.Address) (*AutomationRegistryFundsAddedIterator, error) + + WatchFundsAdded(opts *bind.WatchOpts, sink chan<- *AutomationRegistryFundsAdded, id []*big.Int, from []common.Address) (event.Subscription, error) + + ParseFundsAdded(log types.Log) (*AutomationRegistryFundsAdded, error) + + FilterFundsWithdrawn(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryFundsWithdrawnIterator, error) + + WatchFundsWithdrawn(opts *bind.WatchOpts, sink chan<- *AutomationRegistryFundsWithdrawn, id []*big.Int) (event.Subscription, error) + + ParseFundsWithdrawn(log types.Log) (*AutomationRegistryFundsWithdrawn, error) + + FilterInsufficientFundsUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryInsufficientFundsUpkeepReportIterator, error) + + WatchInsufficientFundsUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryInsufficientFundsUpkeepReport, id []*big.Int) (event.Subscription, error) + + ParseInsufficientFundsUpkeepReport(log types.Log) (*AutomationRegistryInsufficientFundsUpkeepReport, error) + + FilterOwnerFundsWithdrawn(opts *bind.FilterOpts) (*AutomationRegistryOwnerFundsWithdrawnIterator, error) + + WatchOwnerFundsWithdrawn(opts *bind.WatchOpts, sink chan<- *AutomationRegistryOwnerFundsWithdrawn) (event.Subscription, error) + + ParseOwnerFundsWithdrawn(log types.Log) (*AutomationRegistryOwnerFundsWithdrawn, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*AutomationRegistryOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*AutomationRegistryOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*AutomationRegistryOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistryOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*AutomationRegistryOwnershipTransferred, error) + + FilterPaused(opts *bind.FilterOpts) (*AutomationRegistryPausedIterator, error) + + WatchPaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryPaused) (event.Subscription, error) + + ParsePaused(log types.Log) (*AutomationRegistryPaused, error) + + FilterPayeesUpdated(opts *bind.FilterOpts) (*AutomationRegistryPayeesUpdatedIterator, error) + + WatchPayeesUpdated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryPayeesUpdated) (event.Subscription, error) + + ParsePayeesUpdated(log types.Log) (*AutomationRegistryPayeesUpdated, error) + + FilterPayeeshipTransferRequested(opts *bind.FilterOpts, transmitter []common.Address, from []common.Address, to []common.Address) (*AutomationRegistryPayeeshipTransferRequestedIterator, error) + + WatchPayeeshipTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistryPayeeshipTransferRequested, transmitter []common.Address, from []common.Address, to []common.Address) (event.Subscription, error) + + ParsePayeeshipTransferRequested(log types.Log) (*AutomationRegistryPayeeshipTransferRequested, error) + + FilterPayeeshipTransferred(opts *bind.FilterOpts, transmitter []common.Address, from []common.Address, to []common.Address) (*AutomationRegistryPayeeshipTransferredIterator, error) + + WatchPayeeshipTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistryPayeeshipTransferred, transmitter []common.Address, from []common.Address, to []common.Address) (event.Subscription, error) + + ParsePayeeshipTransferred(log types.Log) (*AutomationRegistryPayeeshipTransferred, error) + + FilterPaymentWithdrawn(opts *bind.FilterOpts, transmitter []common.Address, amount []*big.Int, to []common.Address) (*AutomationRegistryPaymentWithdrawnIterator, error) + + WatchPaymentWithdrawn(opts *bind.WatchOpts, sink chan<- *AutomationRegistryPaymentWithdrawn, transmitter []common.Address, amount []*big.Int, to []common.Address) (event.Subscription, error) + + ParsePaymentWithdrawn(log types.Log) (*AutomationRegistryPaymentWithdrawn, error) + + FilterReorgedUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryReorgedUpkeepReportIterator, error) + + WatchReorgedUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryReorgedUpkeepReport, id []*big.Int) (event.Subscription, error) + + ParseReorgedUpkeepReport(log types.Log) (*AutomationRegistryReorgedUpkeepReport, error) + + FilterStaleUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryStaleUpkeepReportIterator, error) + + WatchStaleUpkeepReport(opts *bind.WatchOpts, sink chan<- *AutomationRegistryStaleUpkeepReport, id []*big.Int) (event.Subscription, error) + + ParseStaleUpkeepReport(log types.Log) (*AutomationRegistryStaleUpkeepReport, error) + + FilterTransmitted(opts *bind.FilterOpts) (*AutomationRegistryTransmittedIterator, error) + + WatchTransmitted(opts *bind.WatchOpts, sink chan<- *AutomationRegistryTransmitted) (event.Subscription, error) + + ParseTransmitted(log types.Log) (*AutomationRegistryTransmitted, error) + + FilterUnpaused(opts *bind.FilterOpts) (*AutomationRegistryUnpausedIterator, error) + + WatchUnpaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUnpaused) (event.Subscription, error) + + ParseUnpaused(log types.Log) (*AutomationRegistryUnpaused, error) + + FilterUpkeepAdminTransferRequested(opts *bind.FilterOpts, id []*big.Int, from []common.Address, to []common.Address) (*AutomationRegistryUpkeepAdminTransferRequestedIterator, error) + + WatchUpkeepAdminTransferRequested(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepAdminTransferRequested, id []*big.Int, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseUpkeepAdminTransferRequested(log types.Log) (*AutomationRegistryUpkeepAdminTransferRequested, error) + + FilterUpkeepAdminTransferred(opts *bind.FilterOpts, id []*big.Int, from []common.Address, to []common.Address) (*AutomationRegistryUpkeepAdminTransferredIterator, error) + + WatchUpkeepAdminTransferred(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepAdminTransferred, id []*big.Int, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseUpkeepAdminTransferred(log types.Log) (*AutomationRegistryUpkeepAdminTransferred, error) + + FilterUpkeepCanceled(opts *bind.FilterOpts, id []*big.Int, atBlockHeight []uint64) (*AutomationRegistryUpkeepCanceledIterator, error) + + WatchUpkeepCanceled(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepCanceled, id []*big.Int, atBlockHeight []uint64) (event.Subscription, error) + + ParseUpkeepCanceled(log types.Log) (*AutomationRegistryUpkeepCanceled, error) + + FilterUpkeepCheckDataSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryUpkeepCheckDataSetIterator, error) + + WatchUpkeepCheckDataSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepCheckDataSet, id []*big.Int) (event.Subscription, error) + + ParseUpkeepCheckDataSet(log types.Log) (*AutomationRegistryUpkeepCheckDataSet, error) + + FilterUpkeepGasLimitSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryUpkeepGasLimitSetIterator, error) + + WatchUpkeepGasLimitSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepGasLimitSet, id []*big.Int) (event.Subscription, error) + + ParseUpkeepGasLimitSet(log types.Log) (*AutomationRegistryUpkeepGasLimitSet, error) + + FilterUpkeepMigrated(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryUpkeepMigratedIterator, error) + + WatchUpkeepMigrated(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepMigrated, id []*big.Int) (event.Subscription, error) + + ParseUpkeepMigrated(log types.Log) (*AutomationRegistryUpkeepMigrated, error) + + FilterUpkeepOffchainConfigSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryUpkeepOffchainConfigSetIterator, error) + + WatchUpkeepOffchainConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepOffchainConfigSet, id []*big.Int) (event.Subscription, error) + + ParseUpkeepOffchainConfigSet(log types.Log) (*AutomationRegistryUpkeepOffchainConfigSet, error) + + FilterUpkeepPaused(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryUpkeepPausedIterator, error) + + WatchUpkeepPaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepPaused, id []*big.Int) (event.Subscription, error) + + ParseUpkeepPaused(log types.Log) (*AutomationRegistryUpkeepPaused, error) + + FilterUpkeepPerformed(opts *bind.FilterOpts, id []*big.Int, success []bool) (*AutomationRegistryUpkeepPerformedIterator, error) + + WatchUpkeepPerformed(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepPerformed, id []*big.Int, success []bool) (event.Subscription, error) + + ParseUpkeepPerformed(log types.Log) (*AutomationRegistryUpkeepPerformed, error) + + FilterUpkeepPrivilegeConfigSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryUpkeepPrivilegeConfigSetIterator, error) + + WatchUpkeepPrivilegeConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepPrivilegeConfigSet, id []*big.Int) (event.Subscription, error) + + ParseUpkeepPrivilegeConfigSet(log types.Log) (*AutomationRegistryUpkeepPrivilegeConfigSet, error) + + FilterUpkeepReceived(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryUpkeepReceivedIterator, error) + + WatchUpkeepReceived(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepReceived, id []*big.Int) (event.Subscription, error) + + ParseUpkeepReceived(log types.Log) (*AutomationRegistryUpkeepReceived, error) + + FilterUpkeepRegistered(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryUpkeepRegisteredIterator, error) + + WatchUpkeepRegistered(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepRegistered, id []*big.Int) (event.Subscription, error) + + ParseUpkeepRegistered(log types.Log) (*AutomationRegistryUpkeepRegistered, error) + + FilterUpkeepTriggerConfigSet(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryUpkeepTriggerConfigSetIterator, error) + + WatchUpkeepTriggerConfigSet(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepTriggerConfigSet, id []*big.Int) (event.Subscription, error) + + ParseUpkeepTriggerConfigSet(log types.Log) (*AutomationRegistryUpkeepTriggerConfigSet, error) + + FilterUpkeepUnpaused(opts *bind.FilterOpts, id []*big.Int) (*AutomationRegistryUpkeepUnpausedIterator, error) + + WatchUpkeepUnpaused(opts *bind.WatchOpts, sink chan<- *AutomationRegistryUpkeepUnpaused, id []*big.Int) (event.Subscription, error) + + ParseUpkeepUnpaused(log types.Log) (*AutomationRegistryUpkeepUnpaused, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/automation_utils_2_3/automation_utils_2_3.go b/core/gethwrappers/generated/automation_utils_2_3/automation_utils_2_3.go new file mode 100644 index 00000000000..65cb0e4c04c --- /dev/null +++ b/core/gethwrappers/generated/automation_utils_2_3/automation_utils_2_3.go @@ -0,0 +1,324 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package automation_utils_2_3 + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type AutomationRegistryBase23ConditionalTrigger struct { + BlockNum uint32 + BlockHash [32]byte +} + +type AutomationRegistryBase23LogTrigger struct { + LogBlockHash [32]byte + TxHash [32]byte + LogIndex uint32 + BlockNum uint32 + BlockHash [32]byte +} + +type AutomationRegistryBase23OnchainConfig struct { + PaymentPremiumPPB uint32 + FlatFeeMicroLink uint32 + CheckGasLimit uint32 + StalenessSeconds *big.Int + GasCeilingMultiplier uint16 + MinUpkeepSpend *big.Int + MaxPerformGas uint32 + MaxCheckDataSize uint32 + MaxPerformDataSize uint32 + MaxRevertDataSize uint32 + FallbackGasPrice *big.Int + FallbackLinkPrice *big.Int + Transcoder common.Address + Registrars []common.Address + UpkeepPrivilegeManager common.Address + ChainModule common.Address + ReorgProtectionEnabled bool +} + +type AutomationRegistryBase23Report struct { + FastGasWei *big.Int + LinkNative *big.Int + UpkeepIds []*big.Int + GasLimits []*big.Int + Triggers [][]byte + PerformDatas [][]byte +} + +type Log struct { + Index *big.Int + Timestamp *big.Int + TxHash [32]byte + BlockNumber *big.Int + BlockHash [32]byte + Source common.Address + Topics [][32]byte + Data []byte +} + +type LogTriggerConfig struct { + ContractAddress common.Address + FilterSelector uint8 + Topic0 [32]byte + Topic1 [32]byte + Topic2 [32]byte + Topic3 [32]byte +} + +var AutomationUtilsMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"blockNum\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"internalType\":\"structAutomationRegistryBase2_3.ConditionalTrigger\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_conditionalTrigger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_log\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"logBlockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNum\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"internalType\":\"structAutomationRegistryBase2_3.LogTrigger\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_logTrigger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"filterSelector\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"topic0\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic1\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic2\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic3\",\"type\":\"bytes32\"}],\"internalType\":\"structLogTriggerConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_logTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"contractIChainModule\",\"name\":\"chainModule\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_3.OnchainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_onChainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"gasLimits\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"triggers\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes[]\",\"name\":\"performDatas\",\"type\":\"bytes[]\"}],\"internalType\":\"structAutomationRegistryBase2_3.Report\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b506108f1806100206000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063a4860f2311610050578063a4860f23146100a6578063e65d6546146100b4578063e9720a49146100c257600080fd5b806321f373d7146100775780634b6df2941461008a578063776f306114610098575b600080fd5b6100886100853660046101f1565b50565b005b610088610085366004610279565b6100886100853660046102d0565b610088610085366004610437565b610088610085366004610722565b61008861008536600461080f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715610122576101226100d0565b60405290565b604051610220810167ffffffffffffffff81118282101715610122576101226100d0565b604051610100810167ffffffffffffffff81118282101715610122576101226100d0565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156101b7576101b76100d0565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461008557600080fd5b80356101ec816101bf565b919050565b600060c0828403121561020357600080fd5b61020b6100ff565b8235610216816101bf565b8152602083013560ff8116811461022c57600080fd5b8060208301525060408301356040820152606083013560608201526080830135608082015260a083013560a08201528091505092915050565b803563ffffffff811681146101ec57600080fd5b60006040828403121561028b57600080fd5b6040516040810181811067ffffffffffffffff821117156102ae576102ae6100d0565b6040526102ba83610265565b8152602083013560208201528091505092915050565b600060a082840312156102e257600080fd5b60405160a0810181811067ffffffffffffffff82111715610305576103056100d0565b8060405250823581526020830135602082015261032460408401610265565b604082015261033560608401610265565b6060820152608083013560808201528091505092915050565b803562ffffff811681146101ec57600080fd5b803561ffff811681146101ec57600080fd5b80356bffffffffffffffffffffffff811681146101ec57600080fd5b600067ffffffffffffffff8211156103a9576103a96100d0565b5060051b60200190565b600082601f8301126103c457600080fd5b813560206103d96103d48361038f565b610170565b82815260059290921b840181019181810190868411156103f857600080fd5b8286015b8481101561041c57803561040f816101bf565b83529183019183016103fc565b509695505050505050565b803580151581146101ec57600080fd5b60006020828403121561044957600080fd5b813567ffffffffffffffff8082111561046157600080fd5b90830190610220828603121561047657600080fd5b61047e610128565b61048783610265565b815261049560208401610265565b60208201526104a660408401610265565b60408201526104b76060840161034e565b60608201526104c860808401610361565b60808201526104d960a08401610373565b60a08201526104ea60c08401610265565b60c08201526104fb60e08401610265565b60e082015261010061050e818501610265565b90820152610120610520848201610265565b90820152610140838101359082015261016080840135908201526101806105488185016101e1565b908201526101a0838101358381111561056057600080fd5b61056c888287016103b3565b8284015250506101c091506105828284016101e1565b828201526101e091506105968284016101e1565b8282015261020091506105aa828401610427565b91810191909152949350505050565b600082601f8301126105ca57600080fd5b813560206105da6103d48361038f565b82815260059290921b840181019181810190868411156105f957600080fd5b8286015b8481101561041c57803583529183019183016105fd565b600082601f83011261062557600080fd5b813567ffffffffffffffff81111561063f5761063f6100d0565b61067060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610170565b81815284602083860101111561068557600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f8301126106b357600080fd5b813560206106c36103d48361038f565b82815260059290921b840181019181810190868411156106e257600080fd5b8286015b8481101561041c57803567ffffffffffffffff8111156107065760008081fd5b6107148986838b0101610614565b8452509183019183016106e6565b60006020828403121561073457600080fd5b813567ffffffffffffffff8082111561074c57600080fd5b9083019060c0828603121561076057600080fd5b6107686100ff565b823581526020830135602082015260408301358281111561078857600080fd5b610794878286016105b9565b6040830152506060830135828111156107ac57600080fd5b6107b8878286016105b9565b6060830152506080830135828111156107d057600080fd5b6107dc878286016106a2565b60808301525060a0830135828111156107f457600080fd5b610800878286016106a2565b60a08301525095945050505050565b60006020828403121561082157600080fd5b813567ffffffffffffffff8082111561083957600080fd5b90830190610100828603121561084e57600080fd5b61085661014c565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015261088e60a084016101e1565b60a082015260c0830135828111156108a557600080fd5b6108b1878286016105b9565b60c08301525060e0830135828111156108c957600080fd5b6108d587828601610614565b60e0830152509594505050505056fea164736f6c6343000813000a", +} + +var AutomationUtilsABI = AutomationUtilsMetaData.ABI + +var AutomationUtilsBin = AutomationUtilsMetaData.Bin + +func DeployAutomationUtils(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *AutomationUtils, error) { + parsed, err := AutomationUtilsMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(AutomationUtilsBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &AutomationUtils{address: address, abi: *parsed, AutomationUtilsCaller: AutomationUtilsCaller{contract: contract}, AutomationUtilsTransactor: AutomationUtilsTransactor{contract: contract}, AutomationUtilsFilterer: AutomationUtilsFilterer{contract: contract}}, nil +} + +type AutomationUtils struct { + address common.Address + abi abi.ABI + AutomationUtilsCaller + AutomationUtilsTransactor + AutomationUtilsFilterer +} + +type AutomationUtilsCaller struct { + contract *bind.BoundContract +} + +type AutomationUtilsTransactor struct { + contract *bind.BoundContract +} + +type AutomationUtilsFilterer struct { + contract *bind.BoundContract +} + +type AutomationUtilsSession struct { + Contract *AutomationUtils + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type AutomationUtilsCallerSession struct { + Contract *AutomationUtilsCaller + CallOpts bind.CallOpts +} + +type AutomationUtilsTransactorSession struct { + Contract *AutomationUtilsTransactor + TransactOpts bind.TransactOpts +} + +type AutomationUtilsRaw struct { + Contract *AutomationUtils +} + +type AutomationUtilsCallerRaw struct { + Contract *AutomationUtilsCaller +} + +type AutomationUtilsTransactorRaw struct { + Contract *AutomationUtilsTransactor +} + +func NewAutomationUtils(address common.Address, backend bind.ContractBackend) (*AutomationUtils, error) { + abi, err := abi.JSON(strings.NewReader(AutomationUtilsABI)) + if err != nil { + return nil, err + } + contract, err := bindAutomationUtils(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AutomationUtils{address: address, abi: abi, AutomationUtilsCaller: AutomationUtilsCaller{contract: contract}, AutomationUtilsTransactor: AutomationUtilsTransactor{contract: contract}, AutomationUtilsFilterer: AutomationUtilsFilterer{contract: contract}}, nil +} + +func NewAutomationUtilsCaller(address common.Address, caller bind.ContractCaller) (*AutomationUtilsCaller, error) { + contract, err := bindAutomationUtils(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AutomationUtilsCaller{contract: contract}, nil +} + +func NewAutomationUtilsTransactor(address common.Address, transactor bind.ContractTransactor) (*AutomationUtilsTransactor, error) { + contract, err := bindAutomationUtils(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AutomationUtilsTransactor{contract: contract}, nil +} + +func NewAutomationUtilsFilterer(address common.Address, filterer bind.ContractFilterer) (*AutomationUtilsFilterer, error) { + contract, err := bindAutomationUtils(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AutomationUtilsFilterer{contract: contract}, nil +} + +func bindAutomationUtils(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := AutomationUtilsMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_AutomationUtils *AutomationUtilsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AutomationUtils.Contract.AutomationUtilsCaller.contract.Call(opts, result, method, params...) +} + +func (_AutomationUtils *AutomationUtilsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationUtils.Contract.AutomationUtilsTransactor.contract.Transfer(opts) +} + +func (_AutomationUtils *AutomationUtilsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AutomationUtils.Contract.AutomationUtilsTransactor.contract.Transact(opts, method, params...) +} + +func (_AutomationUtils *AutomationUtilsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AutomationUtils.Contract.contract.Call(opts, result, method, params...) +} + +func (_AutomationUtils *AutomationUtilsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AutomationUtils.Contract.contract.Transfer(opts) +} + +func (_AutomationUtils *AutomationUtilsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AutomationUtils.Contract.contract.Transact(opts, method, params...) +} + +func (_AutomationUtils *AutomationUtilsTransactor) ConditionalTrigger(opts *bind.TransactOpts, arg0 AutomationRegistryBase23ConditionalTrigger) (*types.Transaction, error) { + return _AutomationUtils.contract.Transact(opts, "_conditionalTrigger", arg0) +} + +func (_AutomationUtils *AutomationUtilsSession) ConditionalTrigger(arg0 AutomationRegistryBase23ConditionalTrigger) (*types.Transaction, error) { + return _AutomationUtils.Contract.ConditionalTrigger(&_AutomationUtils.TransactOpts, arg0) +} + +func (_AutomationUtils *AutomationUtilsTransactorSession) ConditionalTrigger(arg0 AutomationRegistryBase23ConditionalTrigger) (*types.Transaction, error) { + return _AutomationUtils.Contract.ConditionalTrigger(&_AutomationUtils.TransactOpts, arg0) +} + +func (_AutomationUtils *AutomationUtilsTransactor) Log(opts *bind.TransactOpts, arg0 Log) (*types.Transaction, error) { + return _AutomationUtils.contract.Transact(opts, "_log", arg0) +} + +func (_AutomationUtils *AutomationUtilsSession) Log(arg0 Log) (*types.Transaction, error) { + return _AutomationUtils.Contract.Log(&_AutomationUtils.TransactOpts, arg0) +} + +func (_AutomationUtils *AutomationUtilsTransactorSession) Log(arg0 Log) (*types.Transaction, error) { + return _AutomationUtils.Contract.Log(&_AutomationUtils.TransactOpts, arg0) +} + +func (_AutomationUtils *AutomationUtilsTransactor) LogTrigger(opts *bind.TransactOpts, arg0 AutomationRegistryBase23LogTrigger) (*types.Transaction, error) { + return _AutomationUtils.contract.Transact(opts, "_logTrigger", arg0) +} + +func (_AutomationUtils *AutomationUtilsSession) LogTrigger(arg0 AutomationRegistryBase23LogTrigger) (*types.Transaction, error) { + return _AutomationUtils.Contract.LogTrigger(&_AutomationUtils.TransactOpts, arg0) +} + +func (_AutomationUtils *AutomationUtilsTransactorSession) LogTrigger(arg0 AutomationRegistryBase23LogTrigger) (*types.Transaction, error) { + return _AutomationUtils.Contract.LogTrigger(&_AutomationUtils.TransactOpts, arg0) +} + +func (_AutomationUtils *AutomationUtilsTransactor) LogTriggerConfig(opts *bind.TransactOpts, arg0 LogTriggerConfig) (*types.Transaction, error) { + return _AutomationUtils.contract.Transact(opts, "_logTriggerConfig", arg0) +} + +func (_AutomationUtils *AutomationUtilsSession) LogTriggerConfig(arg0 LogTriggerConfig) (*types.Transaction, error) { + return _AutomationUtils.Contract.LogTriggerConfig(&_AutomationUtils.TransactOpts, arg0) +} + +func (_AutomationUtils *AutomationUtilsTransactorSession) LogTriggerConfig(arg0 LogTriggerConfig) (*types.Transaction, error) { + return _AutomationUtils.Contract.LogTriggerConfig(&_AutomationUtils.TransactOpts, arg0) +} + +func (_AutomationUtils *AutomationUtilsTransactor) OnChainConfig(opts *bind.TransactOpts, arg0 AutomationRegistryBase23OnchainConfig) (*types.Transaction, error) { + return _AutomationUtils.contract.Transact(opts, "_onChainConfig", arg0) +} + +func (_AutomationUtils *AutomationUtilsSession) OnChainConfig(arg0 AutomationRegistryBase23OnchainConfig) (*types.Transaction, error) { + return _AutomationUtils.Contract.OnChainConfig(&_AutomationUtils.TransactOpts, arg0) +} + +func (_AutomationUtils *AutomationUtilsTransactorSession) OnChainConfig(arg0 AutomationRegistryBase23OnchainConfig) (*types.Transaction, error) { + return _AutomationUtils.Contract.OnChainConfig(&_AutomationUtils.TransactOpts, arg0) +} + +func (_AutomationUtils *AutomationUtilsTransactor) Report(opts *bind.TransactOpts, arg0 AutomationRegistryBase23Report) (*types.Transaction, error) { + return _AutomationUtils.contract.Transact(opts, "_report", arg0) +} + +func (_AutomationUtils *AutomationUtilsSession) Report(arg0 AutomationRegistryBase23Report) (*types.Transaction, error) { + return _AutomationUtils.Contract.Report(&_AutomationUtils.TransactOpts, arg0) +} + +func (_AutomationUtils *AutomationUtilsTransactorSession) Report(arg0 AutomationRegistryBase23Report) (*types.Transaction, error) { + return _AutomationUtils.Contract.Report(&_AutomationUtils.TransactOpts, arg0) +} + +func (_AutomationUtils *AutomationUtils) Address() common.Address { + return _AutomationUtils.address +} + +type AutomationUtilsInterface interface { + ConditionalTrigger(opts *bind.TransactOpts, arg0 AutomationRegistryBase23ConditionalTrigger) (*types.Transaction, error) + + Log(opts *bind.TransactOpts, arg0 Log) (*types.Transaction, error) + + LogTrigger(opts *bind.TransactOpts, arg0 AutomationRegistryBase23LogTrigger) (*types.Transaction, error) + + LogTriggerConfig(opts *bind.TransactOpts, arg0 LogTriggerConfig) (*types.Transaction, error) + + OnChainConfig(opts *bind.TransactOpts, arg0 AutomationRegistryBase23OnchainConfig) (*types.Transaction, error) + + Report(opts *bind.TransactOpts, arg0 AutomationRegistryBase23Report) (*types.Transaction, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3/i_automation_registry_master_wrapper_2_3.go b/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3/i_automation_registry_master_wrapper_2_3.go new file mode 100644 index 00000000000..0d4ca0b5cc2 --- /dev/null +++ b/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3/i_automation_registry_master_wrapper_2_3.go @@ -0,0 +1,6687 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package i_automation_registry_master_wrapper_2_3 + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type AutomationRegistryBase23OnchainConfig struct { + PaymentPremiumPPB uint32 + FlatFeeMicroLink uint32 + CheckGasLimit uint32 + StalenessSeconds *big.Int + GasCeilingMultiplier uint16 + MinUpkeepSpend *big.Int + MaxPerformGas uint32 + MaxCheckDataSize uint32 + MaxPerformDataSize uint32 + MaxRevertDataSize uint32 + FallbackGasPrice *big.Int + FallbackLinkPrice *big.Int + Transcoder common.Address + Registrars []common.Address + UpkeepPrivilegeManager common.Address + ChainModule common.Address + ReorgProtectionEnabled bool +} + +type AutomationRegistryBase23OnchainConfigLegacy struct { + PaymentPremiumPPB uint32 + FlatFeeMicroLink uint32 + CheckGasLimit uint32 + StalenessSeconds *big.Int + GasCeilingMultiplier uint16 + MinUpkeepSpend *big.Int + MaxPerformGas uint32 + MaxCheckDataSize uint32 + MaxPerformDataSize uint32 + MaxRevertDataSize uint32 + FallbackGasPrice *big.Int + FallbackLinkPrice *big.Int + Transcoder common.Address + Registrars []common.Address + UpkeepPrivilegeManager common.Address +} + +type AutomationRegistryBase23State struct { + Nonce uint32 + OwnerLinkBalance *big.Int + ExpectedLinkBalance *big.Int + TotalPremium *big.Int + NumUpkeeps *big.Int + ConfigCount uint32 + LatestConfigBlockNumber uint32 + LatestConfigDigest [32]byte + LatestEpoch uint32 + Paused bool +} + +type AutomationRegistryBase23UpkeepInfo struct { + Target common.Address + PerformGas uint32 + CheckData []byte + Balance *big.Int + Admin common.Address + MaxValidBlocknumber uint64 + LastPerformedBlockNumber uint32 + AmountSpent *big.Int + Paused bool + OffchainConfig []byte +} + +var IAutomationRegistryMasterMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"acceptPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"acceptUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"executeCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"getAdminPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedReadOnlyAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAutomationForwarderLogic\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCancellationDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainModule\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConditionalGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFastGasFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getForwarder\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkNativeFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLogGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"getMaxPaymentForGas\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"maxPayment\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"minBalance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"}],\"name\":\"getPeerRegistryMigrationPermission\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerPerformByteGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerSignerGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getReorgProtectionEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getSignerInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"ownerLinkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"expectedLinkBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"totalPremium\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"numUpkeeps\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"latestConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"latestConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"latestEpoch\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_3.State\",\"name\":\"state\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.OnchainConfigLegacy\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitCalldataFixedBytesOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitCalldataPerSignerBytesOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getTransmitterInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"lastCollected\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTriggerType\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getUpkeep\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"maxValidBlocknumber\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"lastPerformedBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"amountSpent\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structAutomationRegistryBase2_3.UpkeepInfo\",\"name\":\"upkeepInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"hasDedupKey\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"migrateUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"pauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedUpkeeps\",\"type\":\"bytes\"}],\"name\":\"receiveUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setAdminPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"internalType\":\"structAutomationRegistryBase2_3.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"setPayees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"permission\",\"type\":\"uint8\"}],\"name\":\"setPeerRegistryMigrationPermission\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"setUpkeepCheckData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"setUpkeepOffchainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"simulatePerformUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"unpauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTranscoderVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawOwnerFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +} + +var IAutomationRegistryMasterABI = IAutomationRegistryMasterMetaData.ABI + +type IAutomationRegistryMaster struct { + address common.Address + abi abi.ABI + IAutomationRegistryMasterCaller + IAutomationRegistryMasterTransactor + IAutomationRegistryMasterFilterer +} + +type IAutomationRegistryMasterCaller struct { + contract *bind.BoundContract +} + +type IAutomationRegistryMasterTransactor struct { + contract *bind.BoundContract +} + +type IAutomationRegistryMasterFilterer struct { + contract *bind.BoundContract +} + +type IAutomationRegistryMasterSession struct { + Contract *IAutomationRegistryMaster + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type IAutomationRegistryMasterCallerSession struct { + Contract *IAutomationRegistryMasterCaller + CallOpts bind.CallOpts +} + +type IAutomationRegistryMasterTransactorSession struct { + Contract *IAutomationRegistryMasterTransactor + TransactOpts bind.TransactOpts +} + +type IAutomationRegistryMasterRaw struct { + Contract *IAutomationRegistryMaster +} + +type IAutomationRegistryMasterCallerRaw struct { + Contract *IAutomationRegistryMasterCaller +} + +type IAutomationRegistryMasterTransactorRaw struct { + Contract *IAutomationRegistryMasterTransactor +} + +func NewIAutomationRegistryMaster(address common.Address, backend bind.ContractBackend) (*IAutomationRegistryMaster, error) { + abi, err := abi.JSON(strings.NewReader(IAutomationRegistryMasterABI)) + if err != nil { + return nil, err + } + contract, err := bindIAutomationRegistryMaster(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &IAutomationRegistryMaster{address: address, abi: abi, IAutomationRegistryMasterCaller: IAutomationRegistryMasterCaller{contract: contract}, IAutomationRegistryMasterTransactor: IAutomationRegistryMasterTransactor{contract: contract}, IAutomationRegistryMasterFilterer: IAutomationRegistryMasterFilterer{contract: contract}}, nil +} + +func NewIAutomationRegistryMasterCaller(address common.Address, caller bind.ContractCaller) (*IAutomationRegistryMasterCaller, error) { + contract, err := bindIAutomationRegistryMaster(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterCaller{contract: contract}, nil +} + +func NewIAutomationRegistryMasterTransactor(address common.Address, transactor bind.ContractTransactor) (*IAutomationRegistryMasterTransactor, error) { + contract, err := bindIAutomationRegistryMaster(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterTransactor{contract: contract}, nil +} + +func NewIAutomationRegistryMasterFilterer(address common.Address, filterer bind.ContractFilterer) (*IAutomationRegistryMasterFilterer, error) { + contract, err := bindIAutomationRegistryMaster(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterFilterer{contract: contract}, nil +} + +func bindIAutomationRegistryMaster(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := IAutomationRegistryMasterMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IAutomationRegistryMaster.Contract.IAutomationRegistryMasterCaller.contract.Call(opts, result, method, params...) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.IAutomationRegistryMasterTransactor.contract.Transfer(opts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.IAutomationRegistryMasterTransactor.contract.Transact(opts, method, params...) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IAutomationRegistryMaster.Contract.contract.Call(opts, result, method, params...) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.contract.Transfer(opts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.contract.Transact(opts, method, params...) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) CheckCallback(opts *bind.CallOpts, id *big.Int, values [][]byte, extraData []byte) (CheckCallback, + + error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "checkCallback", id, values, extraData) + + outstruct := new(CheckCallback) + if err != nil { + return *outstruct, err + } + + outstruct.UpkeepNeeded = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.PerformData = *abi.ConvertType(out[1], new([]byte)).(*[]byte) + outstruct.UpkeepFailureReason = *abi.ConvertType(out[2], new(uint8)).(*uint8) + outstruct.GasUsed = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) CheckCallback(id *big.Int, values [][]byte, extraData []byte) (CheckCallback, + + error) { + return _IAutomationRegistryMaster.Contract.CheckCallback(&_IAutomationRegistryMaster.CallOpts, id, values, extraData) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) CheckCallback(id *big.Int, values [][]byte, extraData []byte) (CheckCallback, + + error) { + return _IAutomationRegistryMaster.Contract.CheckCallback(&_IAutomationRegistryMaster.CallOpts, id, values, extraData) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) CheckUpkeep(opts *bind.CallOpts, id *big.Int, triggerData []byte) (CheckUpkeep, + + error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "checkUpkeep", id, triggerData) + + outstruct := new(CheckUpkeep) + if err != nil { + return *outstruct, err + } + + outstruct.UpkeepNeeded = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.PerformData = *abi.ConvertType(out[1], new([]byte)).(*[]byte) + outstruct.UpkeepFailureReason = *abi.ConvertType(out[2], new(uint8)).(*uint8) + outstruct.GasUsed = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.GasLimit = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + outstruct.FastGasWei = *abi.ConvertType(out[5], new(*big.Int)).(**big.Int) + outstruct.LinkNative = *abi.ConvertType(out[6], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) CheckUpkeep(id *big.Int, triggerData []byte) (CheckUpkeep, + + error) { + return _IAutomationRegistryMaster.Contract.CheckUpkeep(&_IAutomationRegistryMaster.CallOpts, id, triggerData) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) CheckUpkeep(id *big.Int, triggerData []byte) (CheckUpkeep, + + error) { + return _IAutomationRegistryMaster.Contract.CheckUpkeep(&_IAutomationRegistryMaster.CallOpts, id, triggerData) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) CheckUpkeep0(opts *bind.CallOpts, id *big.Int) (CheckUpkeep0, + + error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "checkUpkeep0", id) + + outstruct := new(CheckUpkeep0) + if err != nil { + return *outstruct, err + } + + outstruct.UpkeepNeeded = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.PerformData = *abi.ConvertType(out[1], new([]byte)).(*[]byte) + outstruct.UpkeepFailureReason = *abi.ConvertType(out[2], new(uint8)).(*uint8) + outstruct.GasUsed = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.GasLimit = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + outstruct.FastGasWei = *abi.ConvertType(out[5], new(*big.Int)).(**big.Int) + outstruct.LinkNative = *abi.ConvertType(out[6], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) CheckUpkeep0(id *big.Int) (CheckUpkeep0, + + error) { + return _IAutomationRegistryMaster.Contract.CheckUpkeep0(&_IAutomationRegistryMaster.CallOpts, id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) CheckUpkeep0(id *big.Int) (CheckUpkeep0, + + error) { + return _IAutomationRegistryMaster.Contract.CheckUpkeep0(&_IAutomationRegistryMaster.CallOpts, id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) FallbackTo(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "fallbackTo") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) FallbackTo() (common.Address, error) { + return _IAutomationRegistryMaster.Contract.FallbackTo(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) FallbackTo() (common.Address, error) { + return _IAutomationRegistryMaster.Contract.FallbackTo(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetActiveUpkeepIDs(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getActiveUpkeepIDs", startIndex, maxCount) + + if err != nil { + return *new([]*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetActiveUpkeepIDs(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetActiveUpkeepIDs(&_IAutomationRegistryMaster.CallOpts, startIndex, maxCount) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetActiveUpkeepIDs(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetActiveUpkeepIDs(&_IAutomationRegistryMaster.CallOpts, startIndex, maxCount) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetAdminPrivilegeConfig(opts *bind.CallOpts, admin common.Address) ([]byte, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getAdminPrivilegeConfig", admin) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetAdminPrivilegeConfig(admin common.Address) ([]byte, error) { + return _IAutomationRegistryMaster.Contract.GetAdminPrivilegeConfig(&_IAutomationRegistryMaster.CallOpts, admin) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetAdminPrivilegeConfig(admin common.Address) ([]byte, error) { + return _IAutomationRegistryMaster.Contract.GetAdminPrivilegeConfig(&_IAutomationRegistryMaster.CallOpts, admin) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetAllowedReadOnlyAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getAllowedReadOnlyAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetAllowedReadOnlyAddress() (common.Address, error) { + return _IAutomationRegistryMaster.Contract.GetAllowedReadOnlyAddress(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetAllowedReadOnlyAddress() (common.Address, error) { + return _IAutomationRegistryMaster.Contract.GetAllowedReadOnlyAddress(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetAutomationForwarderLogic(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getAutomationForwarderLogic") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetAutomationForwarderLogic() (common.Address, error) { + return _IAutomationRegistryMaster.Contract.GetAutomationForwarderLogic(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetAutomationForwarderLogic() (common.Address, error) { + return _IAutomationRegistryMaster.Contract.GetAutomationForwarderLogic(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getBalance", id) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetBalance(id *big.Int) (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetBalance(&_IAutomationRegistryMaster.CallOpts, id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetBalance(id *big.Int) (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetBalance(&_IAutomationRegistryMaster.CallOpts, id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetCancellationDelay(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getCancellationDelay") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetCancellationDelay() (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetCancellationDelay(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetCancellationDelay() (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetCancellationDelay(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetChainModule(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getChainModule") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetChainModule() (common.Address, error) { + return _IAutomationRegistryMaster.Contract.GetChainModule(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetChainModule() (common.Address, error) { + return _IAutomationRegistryMaster.Contract.GetChainModule(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetConditionalGasOverhead(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getConditionalGasOverhead") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetConditionalGasOverhead() (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetConditionalGasOverhead(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetConditionalGasOverhead() (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetConditionalGasOverhead(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetFastGasFeedAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getFastGasFeedAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetFastGasFeedAddress() (common.Address, error) { + return _IAutomationRegistryMaster.Contract.GetFastGasFeedAddress(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetFastGasFeedAddress() (common.Address, error) { + return _IAutomationRegistryMaster.Contract.GetFastGasFeedAddress(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetForwarder(opts *bind.CallOpts, upkeepID *big.Int) (common.Address, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getForwarder", upkeepID) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetForwarder(upkeepID *big.Int) (common.Address, error) { + return _IAutomationRegistryMaster.Contract.GetForwarder(&_IAutomationRegistryMaster.CallOpts, upkeepID) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetForwarder(upkeepID *big.Int) (common.Address, error) { + return _IAutomationRegistryMaster.Contract.GetForwarder(&_IAutomationRegistryMaster.CallOpts, upkeepID) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetLinkAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getLinkAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetLinkAddress() (common.Address, error) { + return _IAutomationRegistryMaster.Contract.GetLinkAddress(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetLinkAddress() (common.Address, error) { + return _IAutomationRegistryMaster.Contract.GetLinkAddress(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetLinkNativeFeedAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getLinkNativeFeedAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetLinkNativeFeedAddress() (common.Address, error) { + return _IAutomationRegistryMaster.Contract.GetLinkNativeFeedAddress(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetLinkNativeFeedAddress() (common.Address, error) { + return _IAutomationRegistryMaster.Contract.GetLinkNativeFeedAddress(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetLogGasOverhead(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getLogGasOverhead") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetLogGasOverhead() (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetLogGasOverhead(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetLogGasOverhead() (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetLogGasOverhead(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetMaxPaymentForGas(opts *bind.CallOpts, triggerType uint8, gasLimit uint32) (*big.Int, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getMaxPaymentForGas", triggerType, gasLimit) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetMaxPaymentForGas(triggerType uint8, gasLimit uint32) (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetMaxPaymentForGas(&_IAutomationRegistryMaster.CallOpts, triggerType, gasLimit) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetMaxPaymentForGas(triggerType uint8, gasLimit uint32) (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetMaxPaymentForGas(&_IAutomationRegistryMaster.CallOpts, triggerType, gasLimit) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetMinBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getMinBalance", id) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetMinBalance(id *big.Int) (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetMinBalance(&_IAutomationRegistryMaster.CallOpts, id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetMinBalance(id *big.Int) (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetMinBalance(&_IAutomationRegistryMaster.CallOpts, id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetMinBalanceForUpkeep(opts *bind.CallOpts, id *big.Int) (*big.Int, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getMinBalanceForUpkeep", id) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetMinBalanceForUpkeep(id *big.Int) (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetMinBalanceForUpkeep(&_IAutomationRegistryMaster.CallOpts, id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetMinBalanceForUpkeep(id *big.Int) (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetMinBalanceForUpkeep(&_IAutomationRegistryMaster.CallOpts, id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetPeerRegistryMigrationPermission(opts *bind.CallOpts, peer common.Address) (uint8, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getPeerRegistryMigrationPermission", peer) + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetPeerRegistryMigrationPermission(peer common.Address) (uint8, error) { + return _IAutomationRegistryMaster.Contract.GetPeerRegistryMigrationPermission(&_IAutomationRegistryMaster.CallOpts, peer) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetPeerRegistryMigrationPermission(peer common.Address) (uint8, error) { + return _IAutomationRegistryMaster.Contract.GetPeerRegistryMigrationPermission(&_IAutomationRegistryMaster.CallOpts, peer) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetPerPerformByteGasOverhead(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getPerPerformByteGasOverhead") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetPerPerformByteGasOverhead() (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetPerPerformByteGasOverhead(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetPerPerformByteGasOverhead() (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetPerPerformByteGasOverhead(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetPerSignerGasOverhead(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getPerSignerGasOverhead") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetPerSignerGasOverhead() (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetPerSignerGasOverhead(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetPerSignerGasOverhead() (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetPerSignerGasOverhead(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetReorgProtectionEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getReorgProtectionEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetReorgProtectionEnabled() (bool, error) { + return _IAutomationRegistryMaster.Contract.GetReorgProtectionEnabled(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetReorgProtectionEnabled() (bool, error) { + return _IAutomationRegistryMaster.Contract.GetReorgProtectionEnabled(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetSignerInfo(opts *bind.CallOpts, query common.Address) (GetSignerInfo, + + error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getSignerInfo", query) + + outstruct := new(GetSignerInfo) + if err != nil { + return *outstruct, err + } + + outstruct.Active = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.Index = *abi.ConvertType(out[1], new(uint8)).(*uint8) + + return *outstruct, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetSignerInfo(query common.Address) (GetSignerInfo, + + error) { + return _IAutomationRegistryMaster.Contract.GetSignerInfo(&_IAutomationRegistryMaster.CallOpts, query) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetSignerInfo(query common.Address) (GetSignerInfo, + + error) { + return _IAutomationRegistryMaster.Contract.GetSignerInfo(&_IAutomationRegistryMaster.CallOpts, query) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetState(opts *bind.CallOpts) (GetState, + + error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getState") + + outstruct := new(GetState) + if err != nil { + return *outstruct, err + } + + outstruct.State = *abi.ConvertType(out[0], new(AutomationRegistryBase23State)).(*AutomationRegistryBase23State) + outstruct.Config = *abi.ConvertType(out[1], new(AutomationRegistryBase23OnchainConfigLegacy)).(*AutomationRegistryBase23OnchainConfigLegacy) + outstruct.Signers = *abi.ConvertType(out[2], new([]common.Address)).(*[]common.Address) + outstruct.Transmitters = *abi.ConvertType(out[3], new([]common.Address)).(*[]common.Address) + outstruct.F = *abi.ConvertType(out[4], new(uint8)).(*uint8) + + return *outstruct, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetState() (GetState, + + error) { + return _IAutomationRegistryMaster.Contract.GetState(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetState() (GetState, + + error) { + return _IAutomationRegistryMaster.Contract.GetState(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetTransmitCalldataFixedBytesOverhead(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getTransmitCalldataFixedBytesOverhead") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetTransmitCalldataFixedBytesOverhead() (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetTransmitCalldataFixedBytesOverhead(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetTransmitCalldataFixedBytesOverhead() (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetTransmitCalldataFixedBytesOverhead(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetTransmitCalldataPerSignerBytesOverhead(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getTransmitCalldataPerSignerBytesOverhead") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetTransmitCalldataPerSignerBytesOverhead() (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetTransmitCalldataPerSignerBytesOverhead(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetTransmitCalldataPerSignerBytesOverhead() (*big.Int, error) { + return _IAutomationRegistryMaster.Contract.GetTransmitCalldataPerSignerBytesOverhead(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetTransmitterInfo(opts *bind.CallOpts, query common.Address) (GetTransmitterInfo, + + error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getTransmitterInfo", query) + + outstruct := new(GetTransmitterInfo) + if err != nil { + return *outstruct, err + } + + outstruct.Active = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.Index = *abi.ConvertType(out[1], new(uint8)).(*uint8) + outstruct.Balance = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + outstruct.LastCollected = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.Payee = *abi.ConvertType(out[4], new(common.Address)).(*common.Address) + + return *outstruct, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetTransmitterInfo(query common.Address) (GetTransmitterInfo, + + error) { + return _IAutomationRegistryMaster.Contract.GetTransmitterInfo(&_IAutomationRegistryMaster.CallOpts, query) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetTransmitterInfo(query common.Address) (GetTransmitterInfo, + + error) { + return _IAutomationRegistryMaster.Contract.GetTransmitterInfo(&_IAutomationRegistryMaster.CallOpts, query) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetTriggerType(opts *bind.CallOpts, upkeepId *big.Int) (uint8, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getTriggerType", upkeepId) + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetTriggerType(upkeepId *big.Int) (uint8, error) { + return _IAutomationRegistryMaster.Contract.GetTriggerType(&_IAutomationRegistryMaster.CallOpts, upkeepId) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetTriggerType(upkeepId *big.Int) (uint8, error) { + return _IAutomationRegistryMaster.Contract.GetTriggerType(&_IAutomationRegistryMaster.CallOpts, upkeepId) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetUpkeep(opts *bind.CallOpts, id *big.Int) (AutomationRegistryBase23UpkeepInfo, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getUpkeep", id) + + if err != nil { + return *new(AutomationRegistryBase23UpkeepInfo), err + } + + out0 := *abi.ConvertType(out[0], new(AutomationRegistryBase23UpkeepInfo)).(*AutomationRegistryBase23UpkeepInfo) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetUpkeep(id *big.Int) (AutomationRegistryBase23UpkeepInfo, error) { + return _IAutomationRegistryMaster.Contract.GetUpkeep(&_IAutomationRegistryMaster.CallOpts, id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetUpkeep(id *big.Int) (AutomationRegistryBase23UpkeepInfo, error) { + return _IAutomationRegistryMaster.Contract.GetUpkeep(&_IAutomationRegistryMaster.CallOpts, id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetUpkeepPrivilegeConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getUpkeepPrivilegeConfig", upkeepId) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetUpkeepPrivilegeConfig(upkeepId *big.Int) ([]byte, error) { + return _IAutomationRegistryMaster.Contract.GetUpkeepPrivilegeConfig(&_IAutomationRegistryMaster.CallOpts, upkeepId) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetUpkeepPrivilegeConfig(upkeepId *big.Int) ([]byte, error) { + return _IAutomationRegistryMaster.Contract.GetUpkeepPrivilegeConfig(&_IAutomationRegistryMaster.CallOpts, upkeepId) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) GetUpkeepTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "getUpkeepTriggerConfig", upkeepId) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) GetUpkeepTriggerConfig(upkeepId *big.Int) ([]byte, error) { + return _IAutomationRegistryMaster.Contract.GetUpkeepTriggerConfig(&_IAutomationRegistryMaster.CallOpts, upkeepId) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) GetUpkeepTriggerConfig(upkeepId *big.Int) ([]byte, error) { + return _IAutomationRegistryMaster.Contract.GetUpkeepTriggerConfig(&_IAutomationRegistryMaster.CallOpts, upkeepId) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) HasDedupKey(opts *bind.CallOpts, dedupKey [32]byte) (bool, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "hasDedupKey", dedupKey) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) HasDedupKey(dedupKey [32]byte) (bool, error) { + return _IAutomationRegistryMaster.Contract.HasDedupKey(&_IAutomationRegistryMaster.CallOpts, dedupKey) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) HasDedupKey(dedupKey [32]byte) (bool, error) { + return _IAutomationRegistryMaster.Contract.HasDedupKey(&_IAutomationRegistryMaster.CallOpts, dedupKey) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "latestConfigDetails") + + outstruct := new(LatestConfigDetails) + if err != nil { + return *outstruct, err + } + + outstruct.ConfigCount = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.ConfigDigest = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + + return *outstruct, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _IAutomationRegistryMaster.Contract.LatestConfigDetails(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _IAutomationRegistryMaster.Contract.LatestConfigDetails(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "latestConfigDigestAndEpoch") + + outstruct := new(LatestConfigDigestAndEpoch) + if err != nil { + return *outstruct, err + } + + outstruct.ScanLogs = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.ConfigDigest = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + outstruct.Epoch = *abi.ConvertType(out[2], new(uint32)).(*uint32) + + return *outstruct, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _IAutomationRegistryMaster.Contract.LatestConfigDigestAndEpoch(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _IAutomationRegistryMaster.Contract.LatestConfigDigestAndEpoch(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) Owner() (common.Address, error) { + return _IAutomationRegistryMaster.Contract.Owner(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) Owner() (common.Address, error) { + return _IAutomationRegistryMaster.Contract.Owner(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) SimulatePerformUpkeep(opts *bind.CallOpts, id *big.Int, performData []byte) (SimulatePerformUpkeep, + + error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "simulatePerformUpkeep", id, performData) + + outstruct := new(SimulatePerformUpkeep) + if err != nil { + return *outstruct, err + } + + outstruct.Success = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.GasUsed = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) SimulatePerformUpkeep(id *big.Int, performData []byte) (SimulatePerformUpkeep, + + error) { + return _IAutomationRegistryMaster.Contract.SimulatePerformUpkeep(&_IAutomationRegistryMaster.CallOpts, id, performData) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) SimulatePerformUpkeep(id *big.Int, performData []byte) (SimulatePerformUpkeep, + + error) { + return _IAutomationRegistryMaster.Contract.SimulatePerformUpkeep(&_IAutomationRegistryMaster.CallOpts, id, performData) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) TypeAndVersion() (string, error) { + return _IAutomationRegistryMaster.Contract.TypeAndVersion(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) TypeAndVersion() (string, error) { + return _IAutomationRegistryMaster.Contract.TypeAndVersion(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) UpkeepTranscoderVersion(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "upkeepTranscoderVersion") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) UpkeepTranscoderVersion() (uint8, error) { + return _IAutomationRegistryMaster.Contract.UpkeepTranscoderVersion(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) UpkeepTranscoderVersion() (uint8, error) { + return _IAutomationRegistryMaster.Contract.UpkeepTranscoderVersion(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCaller) UpkeepVersion(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _IAutomationRegistryMaster.contract.Call(opts, &out, "upkeepVersion") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) UpkeepVersion() (uint8, error) { + return _IAutomationRegistryMaster.Contract.UpkeepVersion(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterCallerSession) UpkeepVersion() (uint8, error) { + return _IAutomationRegistryMaster.Contract.UpkeepVersion(&_IAutomationRegistryMaster.CallOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "acceptOwnership") +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) AcceptOwnership() (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.AcceptOwnership(&_IAutomationRegistryMaster.TransactOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.AcceptOwnership(&_IAutomationRegistryMaster.TransactOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) AcceptPayeeship(opts *bind.TransactOpts, transmitter common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "acceptPayeeship", transmitter) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) AcceptPayeeship(transmitter common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.AcceptPayeeship(&_IAutomationRegistryMaster.TransactOpts, transmitter) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) AcceptPayeeship(transmitter common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.AcceptPayeeship(&_IAutomationRegistryMaster.TransactOpts, transmitter) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) AcceptUpkeepAdmin(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "acceptUpkeepAdmin", id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) AcceptUpkeepAdmin(id *big.Int) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.AcceptUpkeepAdmin(&_IAutomationRegistryMaster.TransactOpts, id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) AcceptUpkeepAdmin(id *big.Int) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.AcceptUpkeepAdmin(&_IAutomationRegistryMaster.TransactOpts, id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) AddFunds(opts *bind.TransactOpts, id *big.Int, amount *big.Int) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "addFunds", id, amount) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) AddFunds(id *big.Int, amount *big.Int) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.AddFunds(&_IAutomationRegistryMaster.TransactOpts, id, amount) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) AddFunds(id *big.Int, amount *big.Int) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.AddFunds(&_IAutomationRegistryMaster.TransactOpts, id, amount) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) CancelUpkeep(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "cancelUpkeep", id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) CancelUpkeep(id *big.Int) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.CancelUpkeep(&_IAutomationRegistryMaster.TransactOpts, id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) CancelUpkeep(id *big.Int) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.CancelUpkeep(&_IAutomationRegistryMaster.TransactOpts, id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) ExecuteCallback(opts *bind.TransactOpts, id *big.Int, payload []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "executeCallback", id, payload) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) ExecuteCallback(id *big.Int, payload []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.ExecuteCallback(&_IAutomationRegistryMaster.TransactOpts, id, payload) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) ExecuteCallback(id *big.Int, payload []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.ExecuteCallback(&_IAutomationRegistryMaster.TransactOpts, id, payload) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) MigrateUpkeeps(opts *bind.TransactOpts, ids []*big.Int, destination common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "migrateUpkeeps", ids, destination) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) MigrateUpkeeps(ids []*big.Int, destination common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.MigrateUpkeeps(&_IAutomationRegistryMaster.TransactOpts, ids, destination) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) MigrateUpkeeps(ids []*big.Int, destination common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.MigrateUpkeeps(&_IAutomationRegistryMaster.TransactOpts, ids, destination) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) OnTokenTransfer(opts *bind.TransactOpts, sender common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "onTokenTransfer", sender, amount, data) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) OnTokenTransfer(sender common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.OnTokenTransfer(&_IAutomationRegistryMaster.TransactOpts, sender, amount, data) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) OnTokenTransfer(sender common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.OnTokenTransfer(&_IAutomationRegistryMaster.TransactOpts, sender, amount, data) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "pause") +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) Pause() (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.Pause(&_IAutomationRegistryMaster.TransactOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) Pause() (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.Pause(&_IAutomationRegistryMaster.TransactOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) PauseUpkeep(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "pauseUpkeep", id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) PauseUpkeep(id *big.Int) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.PauseUpkeep(&_IAutomationRegistryMaster.TransactOpts, id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) PauseUpkeep(id *big.Int) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.PauseUpkeep(&_IAutomationRegistryMaster.TransactOpts, id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) ReceiveUpkeeps(opts *bind.TransactOpts, encodedUpkeeps []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "receiveUpkeeps", encodedUpkeeps) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) ReceiveUpkeeps(encodedUpkeeps []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.ReceiveUpkeeps(&_IAutomationRegistryMaster.TransactOpts, encodedUpkeeps) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) ReceiveUpkeeps(encodedUpkeeps []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.ReceiveUpkeeps(&_IAutomationRegistryMaster.TransactOpts, encodedUpkeeps) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) RecoverFunds(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "recoverFunds") +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) RecoverFunds() (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.RecoverFunds(&_IAutomationRegistryMaster.TransactOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) RecoverFunds() (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.RecoverFunds(&_IAutomationRegistryMaster.TransactOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) RegisterUpkeep(opts *bind.TransactOpts, target common.Address, gasLimit uint32, admin common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "registerUpkeep", target, gasLimit, admin, triggerType, checkData, triggerConfig, offchainConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) RegisterUpkeep(target common.Address, gasLimit uint32, admin common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.RegisterUpkeep(&_IAutomationRegistryMaster.TransactOpts, target, gasLimit, admin, triggerType, checkData, triggerConfig, offchainConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) RegisterUpkeep(target common.Address, gasLimit uint32, admin common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.RegisterUpkeep(&_IAutomationRegistryMaster.TransactOpts, target, gasLimit, admin, triggerType, checkData, triggerConfig, offchainConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) RegisterUpkeep0(opts *bind.TransactOpts, target common.Address, gasLimit uint32, admin common.Address, checkData []byte, offchainConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "registerUpkeep0", target, gasLimit, admin, checkData, offchainConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) RegisterUpkeep0(target common.Address, gasLimit uint32, admin common.Address, checkData []byte, offchainConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.RegisterUpkeep0(&_IAutomationRegistryMaster.TransactOpts, target, gasLimit, admin, checkData, offchainConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) RegisterUpkeep0(target common.Address, gasLimit uint32, admin common.Address, checkData []byte, offchainConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.RegisterUpkeep0(&_IAutomationRegistryMaster.TransactOpts, target, gasLimit, admin, checkData, offchainConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) SetAdminPrivilegeConfig(opts *bind.TransactOpts, admin common.Address, newPrivilegeConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "setAdminPrivilegeConfig", admin, newPrivilegeConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) SetAdminPrivilegeConfig(admin common.Address, newPrivilegeConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetAdminPrivilegeConfig(&_IAutomationRegistryMaster.TransactOpts, admin, newPrivilegeConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) SetAdminPrivilegeConfig(admin common.Address, newPrivilegeConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetAdminPrivilegeConfig(&_IAutomationRegistryMaster.TransactOpts, admin, newPrivilegeConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) SetConfig(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "setConfig", signers, transmitters, f, onchainConfigBytes, offchainConfigVersion, offchainConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) SetConfig(signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetConfig(&_IAutomationRegistryMaster.TransactOpts, signers, transmitters, f, onchainConfigBytes, offchainConfigVersion, offchainConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) SetConfig(signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetConfig(&_IAutomationRegistryMaster.TransactOpts, signers, transmitters, f, onchainConfigBytes, offchainConfigVersion, offchainConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) SetConfigTypeSafe(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig AutomationRegistryBase23OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "setConfigTypeSafe", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) SetConfigTypeSafe(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig AutomationRegistryBase23OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetConfigTypeSafe(&_IAutomationRegistryMaster.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) SetConfigTypeSafe(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig AutomationRegistryBase23OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetConfigTypeSafe(&_IAutomationRegistryMaster.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) SetPayees(opts *bind.TransactOpts, payees []common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "setPayees", payees) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) SetPayees(payees []common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetPayees(&_IAutomationRegistryMaster.TransactOpts, payees) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) SetPayees(payees []common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetPayees(&_IAutomationRegistryMaster.TransactOpts, payees) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) SetPeerRegistryMigrationPermission(opts *bind.TransactOpts, peer common.Address, permission uint8) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "setPeerRegistryMigrationPermission", peer, permission) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) SetPeerRegistryMigrationPermission(peer common.Address, permission uint8) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetPeerRegistryMigrationPermission(&_IAutomationRegistryMaster.TransactOpts, peer, permission) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) SetPeerRegistryMigrationPermission(peer common.Address, permission uint8) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetPeerRegistryMigrationPermission(&_IAutomationRegistryMaster.TransactOpts, peer, permission) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) SetUpkeepCheckData(opts *bind.TransactOpts, id *big.Int, newCheckData []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "setUpkeepCheckData", id, newCheckData) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) SetUpkeepCheckData(id *big.Int, newCheckData []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetUpkeepCheckData(&_IAutomationRegistryMaster.TransactOpts, id, newCheckData) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) SetUpkeepCheckData(id *big.Int, newCheckData []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetUpkeepCheckData(&_IAutomationRegistryMaster.TransactOpts, id, newCheckData) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) SetUpkeepGasLimit(opts *bind.TransactOpts, id *big.Int, gasLimit uint32) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "setUpkeepGasLimit", id, gasLimit) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) SetUpkeepGasLimit(id *big.Int, gasLimit uint32) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetUpkeepGasLimit(&_IAutomationRegistryMaster.TransactOpts, id, gasLimit) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) SetUpkeepGasLimit(id *big.Int, gasLimit uint32) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetUpkeepGasLimit(&_IAutomationRegistryMaster.TransactOpts, id, gasLimit) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) SetUpkeepOffchainConfig(opts *bind.TransactOpts, id *big.Int, config []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "setUpkeepOffchainConfig", id, config) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) SetUpkeepOffchainConfig(id *big.Int, config []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetUpkeepOffchainConfig(&_IAutomationRegistryMaster.TransactOpts, id, config) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) SetUpkeepOffchainConfig(id *big.Int, config []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetUpkeepOffchainConfig(&_IAutomationRegistryMaster.TransactOpts, id, config) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) SetUpkeepPrivilegeConfig(opts *bind.TransactOpts, upkeepId *big.Int, newPrivilegeConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "setUpkeepPrivilegeConfig", upkeepId, newPrivilegeConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) SetUpkeepPrivilegeConfig(upkeepId *big.Int, newPrivilegeConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetUpkeepPrivilegeConfig(&_IAutomationRegistryMaster.TransactOpts, upkeepId, newPrivilegeConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) SetUpkeepPrivilegeConfig(upkeepId *big.Int, newPrivilegeConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetUpkeepPrivilegeConfig(&_IAutomationRegistryMaster.TransactOpts, upkeepId, newPrivilegeConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) SetUpkeepTriggerConfig(opts *bind.TransactOpts, id *big.Int, triggerConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "setUpkeepTriggerConfig", id, triggerConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) SetUpkeepTriggerConfig(id *big.Int, triggerConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetUpkeepTriggerConfig(&_IAutomationRegistryMaster.TransactOpts, id, triggerConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) SetUpkeepTriggerConfig(id *big.Int, triggerConfig []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.SetUpkeepTriggerConfig(&_IAutomationRegistryMaster.TransactOpts, id, triggerConfig) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "transferOwnership", to) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.TransferOwnership(&_IAutomationRegistryMaster.TransactOpts, to) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.TransferOwnership(&_IAutomationRegistryMaster.TransactOpts, to) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) TransferPayeeship(opts *bind.TransactOpts, transmitter common.Address, proposed common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "transferPayeeship", transmitter, proposed) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) TransferPayeeship(transmitter common.Address, proposed common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.TransferPayeeship(&_IAutomationRegistryMaster.TransactOpts, transmitter, proposed) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) TransferPayeeship(transmitter common.Address, proposed common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.TransferPayeeship(&_IAutomationRegistryMaster.TransactOpts, transmitter, proposed) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) TransferUpkeepAdmin(opts *bind.TransactOpts, id *big.Int, proposed common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "transferUpkeepAdmin", id, proposed) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) TransferUpkeepAdmin(id *big.Int, proposed common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.TransferUpkeepAdmin(&_IAutomationRegistryMaster.TransactOpts, id, proposed) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) TransferUpkeepAdmin(id *big.Int, proposed common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.TransferUpkeepAdmin(&_IAutomationRegistryMaster.TransactOpts, id, proposed) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, rawReport []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "transmit", reportContext, rawReport, rs, ss, rawVs) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) Transmit(reportContext [3][32]byte, rawReport []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.Transmit(&_IAutomationRegistryMaster.TransactOpts, reportContext, rawReport, rs, ss, rawVs) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) Transmit(reportContext [3][32]byte, rawReport []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.Transmit(&_IAutomationRegistryMaster.TransactOpts, reportContext, rawReport, rs, ss, rawVs) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "unpause") +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) Unpause() (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.Unpause(&_IAutomationRegistryMaster.TransactOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) Unpause() (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.Unpause(&_IAutomationRegistryMaster.TransactOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) UnpauseUpkeep(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "unpauseUpkeep", id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) UnpauseUpkeep(id *big.Int) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.UnpauseUpkeep(&_IAutomationRegistryMaster.TransactOpts, id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) UnpauseUpkeep(id *big.Int) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.UnpauseUpkeep(&_IAutomationRegistryMaster.TransactOpts, id) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) WithdrawFunds(opts *bind.TransactOpts, id *big.Int, to common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "withdrawFunds", id, to) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) WithdrawFunds(id *big.Int, to common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.WithdrawFunds(&_IAutomationRegistryMaster.TransactOpts, id, to) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) WithdrawFunds(id *big.Int, to common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.WithdrawFunds(&_IAutomationRegistryMaster.TransactOpts, id, to) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) WithdrawOwnerFunds(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "withdrawOwnerFunds") +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) WithdrawOwnerFunds() (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.WithdrawOwnerFunds(&_IAutomationRegistryMaster.TransactOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) WithdrawOwnerFunds() (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.WithdrawOwnerFunds(&_IAutomationRegistryMaster.TransactOpts) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) WithdrawPayment(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.Transact(opts, "withdrawPayment", from, to) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) WithdrawPayment(from common.Address, to common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.WithdrawPayment(&_IAutomationRegistryMaster.TransactOpts, from, to) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) WithdrawPayment(from common.Address, to common.Address) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.WithdrawPayment(&_IAutomationRegistryMaster.TransactOpts, from, to) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.contract.RawTransact(opts, calldata) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.Fallback(&_IAutomationRegistryMaster.TransactOpts, calldata) +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _IAutomationRegistryMaster.Contract.Fallback(&_IAutomationRegistryMaster.TransactOpts, calldata) +} + +type IAutomationRegistryMasterAdminPrivilegeConfigSetIterator struct { + Event *IAutomationRegistryMasterAdminPrivilegeConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterAdminPrivilegeConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterAdminPrivilegeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterAdminPrivilegeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterAdminPrivilegeConfigSetIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterAdminPrivilegeConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterAdminPrivilegeConfigSet struct { + Admin common.Address + PrivilegeConfig []byte + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterAdminPrivilegeConfigSet(opts *bind.FilterOpts, admin []common.Address) (*IAutomationRegistryMasterAdminPrivilegeConfigSetIterator, error) { + + var adminRule []interface{} + for _, adminItem := range admin { + adminRule = append(adminRule, adminItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "AdminPrivilegeConfigSet", adminRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterAdminPrivilegeConfigSetIterator{contract: _IAutomationRegistryMaster.contract, event: "AdminPrivilegeConfigSet", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchAdminPrivilegeConfigSet(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterAdminPrivilegeConfigSet, admin []common.Address) (event.Subscription, error) { + + var adminRule []interface{} + for _, adminItem := range admin { + adminRule = append(adminRule, adminItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "AdminPrivilegeConfigSet", adminRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterAdminPrivilegeConfigSet) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "AdminPrivilegeConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseAdminPrivilegeConfigSet(log types.Log) (*IAutomationRegistryMasterAdminPrivilegeConfigSet, error) { + event := new(IAutomationRegistryMasterAdminPrivilegeConfigSet) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "AdminPrivilegeConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterCancelledUpkeepReportIterator struct { + Event *IAutomationRegistryMasterCancelledUpkeepReport + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterCancelledUpkeepReportIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterCancelledUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterCancelledUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterCancelledUpkeepReportIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterCancelledUpkeepReportIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterCancelledUpkeepReport struct { + Id *big.Int + Trigger []byte + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterCancelledUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterCancelledUpkeepReportIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "CancelledUpkeepReport", idRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterCancelledUpkeepReportIterator{contract: _IAutomationRegistryMaster.contract, event: "CancelledUpkeepReport", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchCancelledUpkeepReport(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterCancelledUpkeepReport, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "CancelledUpkeepReport", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterCancelledUpkeepReport) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "CancelledUpkeepReport", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseCancelledUpkeepReport(log types.Log) (*IAutomationRegistryMasterCancelledUpkeepReport, error) { + event := new(IAutomationRegistryMasterCancelledUpkeepReport) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "CancelledUpkeepReport", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterChainSpecificModuleUpdatedIterator struct { + Event *IAutomationRegistryMasterChainSpecificModuleUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterChainSpecificModuleUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterChainSpecificModuleUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterChainSpecificModuleUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterChainSpecificModuleUpdatedIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterChainSpecificModuleUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterChainSpecificModuleUpdated struct { + NewModule common.Address + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterChainSpecificModuleUpdated(opts *bind.FilterOpts) (*IAutomationRegistryMasterChainSpecificModuleUpdatedIterator, error) { + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "ChainSpecificModuleUpdated") + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterChainSpecificModuleUpdatedIterator{contract: _IAutomationRegistryMaster.contract, event: "ChainSpecificModuleUpdated", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchChainSpecificModuleUpdated(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterChainSpecificModuleUpdated) (event.Subscription, error) { + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "ChainSpecificModuleUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterChainSpecificModuleUpdated) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "ChainSpecificModuleUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseChainSpecificModuleUpdated(log types.Log) (*IAutomationRegistryMasterChainSpecificModuleUpdated, error) { + event := new(IAutomationRegistryMasterChainSpecificModuleUpdated) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "ChainSpecificModuleUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterConfigSetIterator struct { + Event *IAutomationRegistryMasterConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterConfigSetIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterConfigSet struct { + PreviousConfigBlockNumber uint32 + ConfigDigest [32]byte + ConfigCount uint64 + Signers []common.Address + Transmitters []common.Address + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterConfigSet(opts *bind.FilterOpts) (*IAutomationRegistryMasterConfigSetIterator, error) { + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterConfigSetIterator{contract: _IAutomationRegistryMaster.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterConfigSet) (event.Subscription, error) { + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterConfigSet) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseConfigSet(log types.Log) (*IAutomationRegistryMasterConfigSet, error) { + event := new(IAutomationRegistryMasterConfigSet) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterDedupKeyAddedIterator struct { + Event *IAutomationRegistryMasterDedupKeyAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterDedupKeyAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterDedupKeyAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterDedupKeyAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterDedupKeyAddedIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterDedupKeyAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterDedupKeyAdded struct { + DedupKey [32]byte + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterDedupKeyAdded(opts *bind.FilterOpts, dedupKey [][32]byte) (*IAutomationRegistryMasterDedupKeyAddedIterator, error) { + + var dedupKeyRule []interface{} + for _, dedupKeyItem := range dedupKey { + dedupKeyRule = append(dedupKeyRule, dedupKeyItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "DedupKeyAdded", dedupKeyRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterDedupKeyAddedIterator{contract: _IAutomationRegistryMaster.contract, event: "DedupKeyAdded", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchDedupKeyAdded(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterDedupKeyAdded, dedupKey [][32]byte) (event.Subscription, error) { + + var dedupKeyRule []interface{} + for _, dedupKeyItem := range dedupKey { + dedupKeyRule = append(dedupKeyRule, dedupKeyItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "DedupKeyAdded", dedupKeyRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterDedupKeyAdded) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "DedupKeyAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseDedupKeyAdded(log types.Log) (*IAutomationRegistryMasterDedupKeyAdded, error) { + event := new(IAutomationRegistryMasterDedupKeyAdded) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "DedupKeyAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterFundsAddedIterator struct { + Event *IAutomationRegistryMasterFundsAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterFundsAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterFundsAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterFundsAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterFundsAddedIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterFundsAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterFundsAdded struct { + Id *big.Int + From common.Address + Amount *big.Int + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterFundsAdded(opts *bind.FilterOpts, id []*big.Int, from []common.Address) (*IAutomationRegistryMasterFundsAddedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "FundsAdded", idRule, fromRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterFundsAddedIterator{contract: _IAutomationRegistryMaster.contract, event: "FundsAdded", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchFundsAdded(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterFundsAdded, id []*big.Int, from []common.Address) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "FundsAdded", idRule, fromRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterFundsAdded) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "FundsAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseFundsAdded(log types.Log) (*IAutomationRegistryMasterFundsAdded, error) { + event := new(IAutomationRegistryMasterFundsAdded) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "FundsAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterFundsWithdrawnIterator struct { + Event *IAutomationRegistryMasterFundsWithdrawn + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterFundsWithdrawnIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterFundsWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterFundsWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterFundsWithdrawnIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterFundsWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterFundsWithdrawn struct { + Id *big.Int + Amount *big.Int + To common.Address + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterFundsWithdrawn(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterFundsWithdrawnIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "FundsWithdrawn", idRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterFundsWithdrawnIterator{contract: _IAutomationRegistryMaster.contract, event: "FundsWithdrawn", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchFundsWithdrawn(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterFundsWithdrawn, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "FundsWithdrawn", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterFundsWithdrawn) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "FundsWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseFundsWithdrawn(log types.Log) (*IAutomationRegistryMasterFundsWithdrawn, error) { + event := new(IAutomationRegistryMasterFundsWithdrawn) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "FundsWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterInsufficientFundsUpkeepReportIterator struct { + Event *IAutomationRegistryMasterInsufficientFundsUpkeepReport + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterInsufficientFundsUpkeepReportIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterInsufficientFundsUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterInsufficientFundsUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterInsufficientFundsUpkeepReportIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterInsufficientFundsUpkeepReportIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterInsufficientFundsUpkeepReport struct { + Id *big.Int + Trigger []byte + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterInsufficientFundsUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterInsufficientFundsUpkeepReportIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "InsufficientFundsUpkeepReport", idRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterInsufficientFundsUpkeepReportIterator{contract: _IAutomationRegistryMaster.contract, event: "InsufficientFundsUpkeepReport", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchInsufficientFundsUpkeepReport(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterInsufficientFundsUpkeepReport, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "InsufficientFundsUpkeepReport", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterInsufficientFundsUpkeepReport) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "InsufficientFundsUpkeepReport", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseInsufficientFundsUpkeepReport(log types.Log) (*IAutomationRegistryMasterInsufficientFundsUpkeepReport, error) { + event := new(IAutomationRegistryMasterInsufficientFundsUpkeepReport) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "InsufficientFundsUpkeepReport", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterOwnerFundsWithdrawnIterator struct { + Event *IAutomationRegistryMasterOwnerFundsWithdrawn + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterOwnerFundsWithdrawnIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterOwnerFundsWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterOwnerFundsWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterOwnerFundsWithdrawnIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterOwnerFundsWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterOwnerFundsWithdrawn struct { + Amount *big.Int + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterOwnerFundsWithdrawn(opts *bind.FilterOpts) (*IAutomationRegistryMasterOwnerFundsWithdrawnIterator, error) { + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "OwnerFundsWithdrawn") + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterOwnerFundsWithdrawnIterator{contract: _IAutomationRegistryMaster.contract, event: "OwnerFundsWithdrawn", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchOwnerFundsWithdrawn(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterOwnerFundsWithdrawn) (event.Subscription, error) { + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "OwnerFundsWithdrawn") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterOwnerFundsWithdrawn) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "OwnerFundsWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseOwnerFundsWithdrawn(log types.Log) (*IAutomationRegistryMasterOwnerFundsWithdrawn, error) { + event := new(IAutomationRegistryMasterOwnerFundsWithdrawn) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "OwnerFundsWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterOwnershipTransferRequestedIterator struct { + Event *IAutomationRegistryMasterOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*IAutomationRegistryMasterOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterOwnershipTransferRequestedIterator{contract: _IAutomationRegistryMaster.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterOwnershipTransferRequested) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseOwnershipTransferRequested(log types.Log) (*IAutomationRegistryMasterOwnershipTransferRequested, error) { + event := new(IAutomationRegistryMasterOwnershipTransferRequested) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterOwnershipTransferredIterator struct { + Event *IAutomationRegistryMasterOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*IAutomationRegistryMasterOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterOwnershipTransferredIterator{contract: _IAutomationRegistryMaster.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterOwnershipTransferred) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseOwnershipTransferred(log types.Log) (*IAutomationRegistryMasterOwnershipTransferred, error) { + event := new(IAutomationRegistryMasterOwnershipTransferred) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterPausedIterator struct { + Event *IAutomationRegistryMasterPaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterPausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterPausedIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterPaused struct { + Account common.Address + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterPaused(opts *bind.FilterOpts) (*IAutomationRegistryMasterPausedIterator, error) { + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterPausedIterator{contract: _IAutomationRegistryMaster.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterPaused) (event.Subscription, error) { + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "Paused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterPaused) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "Paused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParsePaused(log types.Log) (*IAutomationRegistryMasterPaused, error) { + event := new(IAutomationRegistryMasterPaused) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterPayeesUpdatedIterator struct { + Event *IAutomationRegistryMasterPayeesUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterPayeesUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterPayeesUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterPayeesUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterPayeesUpdatedIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterPayeesUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterPayeesUpdated struct { + Transmitters []common.Address + Payees []common.Address + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterPayeesUpdated(opts *bind.FilterOpts) (*IAutomationRegistryMasterPayeesUpdatedIterator, error) { + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "PayeesUpdated") + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterPayeesUpdatedIterator{contract: _IAutomationRegistryMaster.contract, event: "PayeesUpdated", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchPayeesUpdated(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterPayeesUpdated) (event.Subscription, error) { + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "PayeesUpdated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterPayeesUpdated) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "PayeesUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParsePayeesUpdated(log types.Log) (*IAutomationRegistryMasterPayeesUpdated, error) { + event := new(IAutomationRegistryMasterPayeesUpdated) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "PayeesUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterPayeeshipTransferRequestedIterator struct { + Event *IAutomationRegistryMasterPayeeshipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterPayeeshipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterPayeeshipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterPayeeshipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterPayeeshipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterPayeeshipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterPayeeshipTransferRequested struct { + Transmitter common.Address + From common.Address + To common.Address + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterPayeeshipTransferRequested(opts *bind.FilterOpts, transmitter []common.Address, from []common.Address, to []common.Address) (*IAutomationRegistryMasterPayeeshipTransferRequestedIterator, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "PayeeshipTransferRequested", transmitterRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterPayeeshipTransferRequestedIterator{contract: _IAutomationRegistryMaster.contract, event: "PayeeshipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchPayeeshipTransferRequested(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterPayeeshipTransferRequested, transmitter []common.Address, from []common.Address, to []common.Address) (event.Subscription, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "PayeeshipTransferRequested", transmitterRule, fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterPayeeshipTransferRequested) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "PayeeshipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParsePayeeshipTransferRequested(log types.Log) (*IAutomationRegistryMasterPayeeshipTransferRequested, error) { + event := new(IAutomationRegistryMasterPayeeshipTransferRequested) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "PayeeshipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterPayeeshipTransferredIterator struct { + Event *IAutomationRegistryMasterPayeeshipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterPayeeshipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterPayeeshipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterPayeeshipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterPayeeshipTransferredIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterPayeeshipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterPayeeshipTransferred struct { + Transmitter common.Address + From common.Address + To common.Address + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterPayeeshipTransferred(opts *bind.FilterOpts, transmitter []common.Address, from []common.Address, to []common.Address) (*IAutomationRegistryMasterPayeeshipTransferredIterator, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "PayeeshipTransferred", transmitterRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterPayeeshipTransferredIterator{contract: _IAutomationRegistryMaster.contract, event: "PayeeshipTransferred", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchPayeeshipTransferred(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterPayeeshipTransferred, transmitter []common.Address, from []common.Address, to []common.Address) (event.Subscription, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "PayeeshipTransferred", transmitterRule, fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterPayeeshipTransferred) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "PayeeshipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParsePayeeshipTransferred(log types.Log) (*IAutomationRegistryMasterPayeeshipTransferred, error) { + event := new(IAutomationRegistryMasterPayeeshipTransferred) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "PayeeshipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterPaymentWithdrawnIterator struct { + Event *IAutomationRegistryMasterPaymentWithdrawn + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterPaymentWithdrawnIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterPaymentWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterPaymentWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterPaymentWithdrawnIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterPaymentWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterPaymentWithdrawn struct { + Transmitter common.Address + Amount *big.Int + To common.Address + Payee common.Address + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterPaymentWithdrawn(opts *bind.FilterOpts, transmitter []common.Address, amount []*big.Int, to []common.Address) (*IAutomationRegistryMasterPaymentWithdrawnIterator, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "PaymentWithdrawn", transmitterRule, amountRule, toRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterPaymentWithdrawnIterator{contract: _IAutomationRegistryMaster.contract, event: "PaymentWithdrawn", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchPaymentWithdrawn(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterPaymentWithdrawn, transmitter []common.Address, amount []*big.Int, to []common.Address) (event.Subscription, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var amountRule []interface{} + for _, amountItem := range amount { + amountRule = append(amountRule, amountItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "PaymentWithdrawn", transmitterRule, amountRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterPaymentWithdrawn) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "PaymentWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParsePaymentWithdrawn(log types.Log) (*IAutomationRegistryMasterPaymentWithdrawn, error) { + event := new(IAutomationRegistryMasterPaymentWithdrawn) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "PaymentWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterReorgedUpkeepReportIterator struct { + Event *IAutomationRegistryMasterReorgedUpkeepReport + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterReorgedUpkeepReportIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterReorgedUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterReorgedUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterReorgedUpkeepReportIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterReorgedUpkeepReportIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterReorgedUpkeepReport struct { + Id *big.Int + Trigger []byte + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterReorgedUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterReorgedUpkeepReportIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "ReorgedUpkeepReport", idRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterReorgedUpkeepReportIterator{contract: _IAutomationRegistryMaster.contract, event: "ReorgedUpkeepReport", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchReorgedUpkeepReport(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterReorgedUpkeepReport, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "ReorgedUpkeepReport", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterReorgedUpkeepReport) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "ReorgedUpkeepReport", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseReorgedUpkeepReport(log types.Log) (*IAutomationRegistryMasterReorgedUpkeepReport, error) { + event := new(IAutomationRegistryMasterReorgedUpkeepReport) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "ReorgedUpkeepReport", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterStaleUpkeepReportIterator struct { + Event *IAutomationRegistryMasterStaleUpkeepReport + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterStaleUpkeepReportIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterStaleUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterStaleUpkeepReport) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterStaleUpkeepReportIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterStaleUpkeepReportIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterStaleUpkeepReport struct { + Id *big.Int + Trigger []byte + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterStaleUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterStaleUpkeepReportIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "StaleUpkeepReport", idRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterStaleUpkeepReportIterator{contract: _IAutomationRegistryMaster.contract, event: "StaleUpkeepReport", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchStaleUpkeepReport(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterStaleUpkeepReport, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "StaleUpkeepReport", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterStaleUpkeepReport) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "StaleUpkeepReport", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseStaleUpkeepReport(log types.Log) (*IAutomationRegistryMasterStaleUpkeepReport, error) { + event := new(IAutomationRegistryMasterStaleUpkeepReport) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "StaleUpkeepReport", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterTransmittedIterator struct { + Event *IAutomationRegistryMasterTransmitted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterTransmittedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterTransmittedIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterTransmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterTransmitted struct { + ConfigDigest [32]byte + Epoch uint32 + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterTransmitted(opts *bind.FilterOpts) (*IAutomationRegistryMasterTransmittedIterator, error) { + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterTransmittedIterator{contract: _IAutomationRegistryMaster.contract, event: "Transmitted", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterTransmitted) (event.Subscription, error) { + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterTransmitted) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "Transmitted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseTransmitted(log types.Log) (*IAutomationRegistryMasterTransmitted, error) { + event := new(IAutomationRegistryMasterTransmitted) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "Transmitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterUnpausedIterator struct { + Event *IAutomationRegistryMasterUnpaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterUnpausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterUnpausedIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterUnpaused struct { + Account common.Address + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterUnpaused(opts *bind.FilterOpts) (*IAutomationRegistryMasterUnpausedIterator, error) { + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterUnpausedIterator{contract: _IAutomationRegistryMaster.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUnpaused) (event.Subscription, error) { + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterUnpaused) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "Unpaused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseUnpaused(log types.Log) (*IAutomationRegistryMasterUnpaused, error) { + event := new(IAutomationRegistryMasterUnpaused) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterUpkeepAdminTransferRequestedIterator struct { + Event *IAutomationRegistryMasterUpkeepAdminTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterUpkeepAdminTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepAdminTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepAdminTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterUpkeepAdminTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterUpkeepAdminTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterUpkeepAdminTransferRequested struct { + Id *big.Int + From common.Address + To common.Address + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterUpkeepAdminTransferRequested(opts *bind.FilterOpts, id []*big.Int, from []common.Address, to []common.Address) (*IAutomationRegistryMasterUpkeepAdminTransferRequestedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "UpkeepAdminTransferRequested", idRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterUpkeepAdminTransferRequestedIterator{contract: _IAutomationRegistryMaster.contract, event: "UpkeepAdminTransferRequested", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchUpkeepAdminTransferRequested(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepAdminTransferRequested, id []*big.Int, from []common.Address, to []common.Address) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "UpkeepAdminTransferRequested", idRule, fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterUpkeepAdminTransferRequested) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepAdminTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseUpkeepAdminTransferRequested(log types.Log) (*IAutomationRegistryMasterUpkeepAdminTransferRequested, error) { + event := new(IAutomationRegistryMasterUpkeepAdminTransferRequested) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepAdminTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterUpkeepAdminTransferredIterator struct { + Event *IAutomationRegistryMasterUpkeepAdminTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterUpkeepAdminTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepAdminTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepAdminTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterUpkeepAdminTransferredIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterUpkeepAdminTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterUpkeepAdminTransferred struct { + Id *big.Int + From common.Address + To common.Address + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterUpkeepAdminTransferred(opts *bind.FilterOpts, id []*big.Int, from []common.Address, to []common.Address) (*IAutomationRegistryMasterUpkeepAdminTransferredIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "UpkeepAdminTransferred", idRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterUpkeepAdminTransferredIterator{contract: _IAutomationRegistryMaster.contract, event: "UpkeepAdminTransferred", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchUpkeepAdminTransferred(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepAdminTransferred, id []*big.Int, from []common.Address, to []common.Address) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "UpkeepAdminTransferred", idRule, fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterUpkeepAdminTransferred) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepAdminTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseUpkeepAdminTransferred(log types.Log) (*IAutomationRegistryMasterUpkeepAdminTransferred, error) { + event := new(IAutomationRegistryMasterUpkeepAdminTransferred) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepAdminTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterUpkeepCanceledIterator struct { + Event *IAutomationRegistryMasterUpkeepCanceled + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterUpkeepCanceledIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepCanceled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepCanceled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterUpkeepCanceledIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterUpkeepCanceledIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterUpkeepCanceled struct { + Id *big.Int + AtBlockHeight uint64 + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterUpkeepCanceled(opts *bind.FilterOpts, id []*big.Int, atBlockHeight []uint64) (*IAutomationRegistryMasterUpkeepCanceledIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var atBlockHeightRule []interface{} + for _, atBlockHeightItem := range atBlockHeight { + atBlockHeightRule = append(atBlockHeightRule, atBlockHeightItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "UpkeepCanceled", idRule, atBlockHeightRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterUpkeepCanceledIterator{contract: _IAutomationRegistryMaster.contract, event: "UpkeepCanceled", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchUpkeepCanceled(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepCanceled, id []*big.Int, atBlockHeight []uint64) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var atBlockHeightRule []interface{} + for _, atBlockHeightItem := range atBlockHeight { + atBlockHeightRule = append(atBlockHeightRule, atBlockHeightItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "UpkeepCanceled", idRule, atBlockHeightRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterUpkeepCanceled) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepCanceled", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseUpkeepCanceled(log types.Log) (*IAutomationRegistryMasterUpkeepCanceled, error) { + event := new(IAutomationRegistryMasterUpkeepCanceled) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepCanceled", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterUpkeepCheckDataSetIterator struct { + Event *IAutomationRegistryMasterUpkeepCheckDataSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterUpkeepCheckDataSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepCheckDataSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepCheckDataSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterUpkeepCheckDataSetIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterUpkeepCheckDataSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterUpkeepCheckDataSet struct { + Id *big.Int + NewCheckData []byte + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterUpkeepCheckDataSet(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterUpkeepCheckDataSetIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "UpkeepCheckDataSet", idRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterUpkeepCheckDataSetIterator{contract: _IAutomationRegistryMaster.contract, event: "UpkeepCheckDataSet", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchUpkeepCheckDataSet(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepCheckDataSet, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "UpkeepCheckDataSet", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterUpkeepCheckDataSet) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepCheckDataSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseUpkeepCheckDataSet(log types.Log) (*IAutomationRegistryMasterUpkeepCheckDataSet, error) { + event := new(IAutomationRegistryMasterUpkeepCheckDataSet) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepCheckDataSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterUpkeepGasLimitSetIterator struct { + Event *IAutomationRegistryMasterUpkeepGasLimitSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterUpkeepGasLimitSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepGasLimitSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepGasLimitSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterUpkeepGasLimitSetIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterUpkeepGasLimitSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterUpkeepGasLimitSet struct { + Id *big.Int + GasLimit *big.Int + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterUpkeepGasLimitSet(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterUpkeepGasLimitSetIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "UpkeepGasLimitSet", idRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterUpkeepGasLimitSetIterator{contract: _IAutomationRegistryMaster.contract, event: "UpkeepGasLimitSet", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchUpkeepGasLimitSet(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepGasLimitSet, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "UpkeepGasLimitSet", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterUpkeepGasLimitSet) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepGasLimitSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseUpkeepGasLimitSet(log types.Log) (*IAutomationRegistryMasterUpkeepGasLimitSet, error) { + event := new(IAutomationRegistryMasterUpkeepGasLimitSet) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepGasLimitSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterUpkeepMigratedIterator struct { + Event *IAutomationRegistryMasterUpkeepMigrated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterUpkeepMigratedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepMigrated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepMigrated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterUpkeepMigratedIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterUpkeepMigratedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterUpkeepMigrated struct { + Id *big.Int + RemainingBalance *big.Int + Destination common.Address + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterUpkeepMigrated(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterUpkeepMigratedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "UpkeepMigrated", idRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterUpkeepMigratedIterator{contract: _IAutomationRegistryMaster.contract, event: "UpkeepMigrated", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchUpkeepMigrated(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepMigrated, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "UpkeepMigrated", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterUpkeepMigrated) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepMigrated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseUpkeepMigrated(log types.Log) (*IAutomationRegistryMasterUpkeepMigrated, error) { + event := new(IAutomationRegistryMasterUpkeepMigrated) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepMigrated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterUpkeepOffchainConfigSetIterator struct { + Event *IAutomationRegistryMasterUpkeepOffchainConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterUpkeepOffchainConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepOffchainConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepOffchainConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterUpkeepOffchainConfigSetIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterUpkeepOffchainConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterUpkeepOffchainConfigSet struct { + Id *big.Int + OffchainConfig []byte + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterUpkeepOffchainConfigSet(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterUpkeepOffchainConfigSetIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "UpkeepOffchainConfigSet", idRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterUpkeepOffchainConfigSetIterator{contract: _IAutomationRegistryMaster.contract, event: "UpkeepOffchainConfigSet", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchUpkeepOffchainConfigSet(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepOffchainConfigSet, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "UpkeepOffchainConfigSet", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterUpkeepOffchainConfigSet) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepOffchainConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseUpkeepOffchainConfigSet(log types.Log) (*IAutomationRegistryMasterUpkeepOffchainConfigSet, error) { + event := new(IAutomationRegistryMasterUpkeepOffchainConfigSet) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepOffchainConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterUpkeepPausedIterator struct { + Event *IAutomationRegistryMasterUpkeepPaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterUpkeepPausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterUpkeepPausedIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterUpkeepPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterUpkeepPaused struct { + Id *big.Int + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterUpkeepPaused(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterUpkeepPausedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "UpkeepPaused", idRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterUpkeepPausedIterator{contract: _IAutomationRegistryMaster.contract, event: "UpkeepPaused", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchUpkeepPaused(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepPaused, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "UpkeepPaused", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterUpkeepPaused) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepPaused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseUpkeepPaused(log types.Log) (*IAutomationRegistryMasterUpkeepPaused, error) { + event := new(IAutomationRegistryMasterUpkeepPaused) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepPaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterUpkeepPerformedIterator struct { + Event *IAutomationRegistryMasterUpkeepPerformed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterUpkeepPerformedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepPerformed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepPerformed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterUpkeepPerformedIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterUpkeepPerformedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterUpkeepPerformed struct { + Id *big.Int + Success bool + TotalPayment *big.Int + GasUsed *big.Int + GasOverhead *big.Int + Trigger []byte + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterUpkeepPerformed(opts *bind.FilterOpts, id []*big.Int, success []bool) (*IAutomationRegistryMasterUpkeepPerformedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var successRule []interface{} + for _, successItem := range success { + successRule = append(successRule, successItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "UpkeepPerformed", idRule, successRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterUpkeepPerformedIterator{contract: _IAutomationRegistryMaster.contract, event: "UpkeepPerformed", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchUpkeepPerformed(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepPerformed, id []*big.Int, success []bool) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + var successRule []interface{} + for _, successItem := range success { + successRule = append(successRule, successItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "UpkeepPerformed", idRule, successRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterUpkeepPerformed) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepPerformed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseUpkeepPerformed(log types.Log) (*IAutomationRegistryMasterUpkeepPerformed, error) { + event := new(IAutomationRegistryMasterUpkeepPerformed) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepPerformed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterUpkeepPrivilegeConfigSetIterator struct { + Event *IAutomationRegistryMasterUpkeepPrivilegeConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterUpkeepPrivilegeConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepPrivilegeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepPrivilegeConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterUpkeepPrivilegeConfigSetIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterUpkeepPrivilegeConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterUpkeepPrivilegeConfigSet struct { + Id *big.Int + PrivilegeConfig []byte + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterUpkeepPrivilegeConfigSet(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterUpkeepPrivilegeConfigSetIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "UpkeepPrivilegeConfigSet", idRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterUpkeepPrivilegeConfigSetIterator{contract: _IAutomationRegistryMaster.contract, event: "UpkeepPrivilegeConfigSet", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchUpkeepPrivilegeConfigSet(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepPrivilegeConfigSet, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "UpkeepPrivilegeConfigSet", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterUpkeepPrivilegeConfigSet) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepPrivilegeConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseUpkeepPrivilegeConfigSet(log types.Log) (*IAutomationRegistryMasterUpkeepPrivilegeConfigSet, error) { + event := new(IAutomationRegistryMasterUpkeepPrivilegeConfigSet) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepPrivilegeConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterUpkeepReceivedIterator struct { + Event *IAutomationRegistryMasterUpkeepReceived + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterUpkeepReceivedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterUpkeepReceivedIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterUpkeepReceivedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterUpkeepReceived struct { + Id *big.Int + StartingBalance *big.Int + ImportedFrom common.Address + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterUpkeepReceived(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterUpkeepReceivedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "UpkeepReceived", idRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterUpkeepReceivedIterator{contract: _IAutomationRegistryMaster.contract, event: "UpkeepReceived", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchUpkeepReceived(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepReceived, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "UpkeepReceived", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterUpkeepReceived) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepReceived", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseUpkeepReceived(log types.Log) (*IAutomationRegistryMasterUpkeepReceived, error) { + event := new(IAutomationRegistryMasterUpkeepReceived) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepReceived", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterUpkeepRegisteredIterator struct { + Event *IAutomationRegistryMasterUpkeepRegistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterUpkeepRegisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterUpkeepRegisteredIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterUpkeepRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterUpkeepRegistered struct { + Id *big.Int + PerformGas uint32 + Admin common.Address + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterUpkeepRegistered(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterUpkeepRegisteredIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "UpkeepRegistered", idRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterUpkeepRegisteredIterator{contract: _IAutomationRegistryMaster.contract, event: "UpkeepRegistered", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchUpkeepRegistered(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepRegistered, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "UpkeepRegistered", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterUpkeepRegistered) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseUpkeepRegistered(log types.Log) (*IAutomationRegistryMasterUpkeepRegistered, error) { + event := new(IAutomationRegistryMasterUpkeepRegistered) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterUpkeepTriggerConfigSetIterator struct { + Event *IAutomationRegistryMasterUpkeepTriggerConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterUpkeepTriggerConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepTriggerConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepTriggerConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterUpkeepTriggerConfigSetIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterUpkeepTriggerConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterUpkeepTriggerConfigSet struct { + Id *big.Int + TriggerConfig []byte + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterUpkeepTriggerConfigSet(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterUpkeepTriggerConfigSetIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "UpkeepTriggerConfigSet", idRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterUpkeepTriggerConfigSetIterator{contract: _IAutomationRegistryMaster.contract, event: "UpkeepTriggerConfigSet", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchUpkeepTriggerConfigSet(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepTriggerConfigSet, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "UpkeepTriggerConfigSet", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterUpkeepTriggerConfigSet) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepTriggerConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseUpkeepTriggerConfigSet(log types.Log) (*IAutomationRegistryMasterUpkeepTriggerConfigSet, error) { + event := new(IAutomationRegistryMasterUpkeepTriggerConfigSet) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepTriggerConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IAutomationRegistryMasterUpkeepUnpausedIterator struct { + Event *IAutomationRegistryMasterUpkeepUnpaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IAutomationRegistryMasterUpkeepUnpausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IAutomationRegistryMasterUpkeepUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IAutomationRegistryMasterUpkeepUnpausedIterator) Error() error { + return it.fail +} + +func (it *IAutomationRegistryMasterUpkeepUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IAutomationRegistryMasterUpkeepUnpaused struct { + Id *big.Int + Raw types.Log +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) FilterUpkeepUnpaused(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterUpkeepUnpausedIterator, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.FilterLogs(opts, "UpkeepUnpaused", idRule) + if err != nil { + return nil, err + } + return &IAutomationRegistryMasterUpkeepUnpausedIterator{contract: _IAutomationRegistryMaster.contract, event: "UpkeepUnpaused", logs: logs, sub: sub}, nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) WatchUpkeepUnpaused(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepUnpaused, id []*big.Int) (event.Subscription, error) { + + var idRule []interface{} + for _, idItem := range id { + idRule = append(idRule, idItem) + } + + logs, sub, err := _IAutomationRegistryMaster.contract.WatchLogs(opts, "UpkeepUnpaused", idRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IAutomationRegistryMasterUpkeepUnpaused) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepUnpaused", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMasterFilterer) ParseUpkeepUnpaused(log types.Log) (*IAutomationRegistryMasterUpkeepUnpaused, error) { + event := new(IAutomationRegistryMasterUpkeepUnpaused) + if err := _IAutomationRegistryMaster.contract.UnpackLog(event, "UpkeepUnpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CheckCallback struct { + UpkeepNeeded bool + PerformData []byte + UpkeepFailureReason uint8 + GasUsed *big.Int +} +type CheckUpkeep struct { + UpkeepNeeded bool + PerformData []byte + UpkeepFailureReason uint8 + GasUsed *big.Int + GasLimit *big.Int + FastGasWei *big.Int + LinkNative *big.Int +} +type CheckUpkeep0 struct { + UpkeepNeeded bool + PerformData []byte + UpkeepFailureReason uint8 + GasUsed *big.Int + GasLimit *big.Int + FastGasWei *big.Int + LinkNative *big.Int +} +type GetSignerInfo struct { + Active bool + Index uint8 +} +type GetState struct { + State AutomationRegistryBase23State + Config AutomationRegistryBase23OnchainConfigLegacy + Signers []common.Address + Transmitters []common.Address + F uint8 +} +type GetTransmitterInfo struct { + Active bool + Index uint8 + Balance *big.Int + LastCollected *big.Int + Payee common.Address +} +type LatestConfigDetails struct { + ConfigCount uint32 + BlockNumber uint32 + ConfigDigest [32]byte +} +type LatestConfigDigestAndEpoch struct { + ScanLogs bool + ConfigDigest [32]byte + Epoch uint32 +} +type SimulatePerformUpkeep struct { + Success bool + GasUsed *big.Int +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMaster) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _IAutomationRegistryMaster.abi.Events["AdminPrivilegeConfigSet"].ID: + return _IAutomationRegistryMaster.ParseAdminPrivilegeConfigSet(log) + case _IAutomationRegistryMaster.abi.Events["CancelledUpkeepReport"].ID: + return _IAutomationRegistryMaster.ParseCancelledUpkeepReport(log) + case _IAutomationRegistryMaster.abi.Events["ChainSpecificModuleUpdated"].ID: + return _IAutomationRegistryMaster.ParseChainSpecificModuleUpdated(log) + case _IAutomationRegistryMaster.abi.Events["ConfigSet"].ID: + return _IAutomationRegistryMaster.ParseConfigSet(log) + case _IAutomationRegistryMaster.abi.Events["DedupKeyAdded"].ID: + return _IAutomationRegistryMaster.ParseDedupKeyAdded(log) + case _IAutomationRegistryMaster.abi.Events["FundsAdded"].ID: + return _IAutomationRegistryMaster.ParseFundsAdded(log) + case _IAutomationRegistryMaster.abi.Events["FundsWithdrawn"].ID: + return _IAutomationRegistryMaster.ParseFundsWithdrawn(log) + case _IAutomationRegistryMaster.abi.Events["InsufficientFundsUpkeepReport"].ID: + return _IAutomationRegistryMaster.ParseInsufficientFundsUpkeepReport(log) + case _IAutomationRegistryMaster.abi.Events["OwnerFundsWithdrawn"].ID: + return _IAutomationRegistryMaster.ParseOwnerFundsWithdrawn(log) + case _IAutomationRegistryMaster.abi.Events["OwnershipTransferRequested"].ID: + return _IAutomationRegistryMaster.ParseOwnershipTransferRequested(log) + case _IAutomationRegistryMaster.abi.Events["OwnershipTransferred"].ID: + return _IAutomationRegistryMaster.ParseOwnershipTransferred(log) + case _IAutomationRegistryMaster.abi.Events["Paused"].ID: + return _IAutomationRegistryMaster.ParsePaused(log) + case _IAutomationRegistryMaster.abi.Events["PayeesUpdated"].ID: + return _IAutomationRegistryMaster.ParsePayeesUpdated(log) + case _IAutomationRegistryMaster.abi.Events["PayeeshipTransferRequested"].ID: + return _IAutomationRegistryMaster.ParsePayeeshipTransferRequested(log) + case _IAutomationRegistryMaster.abi.Events["PayeeshipTransferred"].ID: + return _IAutomationRegistryMaster.ParsePayeeshipTransferred(log) + case _IAutomationRegistryMaster.abi.Events["PaymentWithdrawn"].ID: + return _IAutomationRegistryMaster.ParsePaymentWithdrawn(log) + case _IAutomationRegistryMaster.abi.Events["ReorgedUpkeepReport"].ID: + return _IAutomationRegistryMaster.ParseReorgedUpkeepReport(log) + case _IAutomationRegistryMaster.abi.Events["StaleUpkeepReport"].ID: + return _IAutomationRegistryMaster.ParseStaleUpkeepReport(log) + case _IAutomationRegistryMaster.abi.Events["Transmitted"].ID: + return _IAutomationRegistryMaster.ParseTransmitted(log) + case _IAutomationRegistryMaster.abi.Events["Unpaused"].ID: + return _IAutomationRegistryMaster.ParseUnpaused(log) + case _IAutomationRegistryMaster.abi.Events["UpkeepAdminTransferRequested"].ID: + return _IAutomationRegistryMaster.ParseUpkeepAdminTransferRequested(log) + case _IAutomationRegistryMaster.abi.Events["UpkeepAdminTransferred"].ID: + return _IAutomationRegistryMaster.ParseUpkeepAdminTransferred(log) + case _IAutomationRegistryMaster.abi.Events["UpkeepCanceled"].ID: + return _IAutomationRegistryMaster.ParseUpkeepCanceled(log) + case _IAutomationRegistryMaster.abi.Events["UpkeepCheckDataSet"].ID: + return _IAutomationRegistryMaster.ParseUpkeepCheckDataSet(log) + case _IAutomationRegistryMaster.abi.Events["UpkeepGasLimitSet"].ID: + return _IAutomationRegistryMaster.ParseUpkeepGasLimitSet(log) + case _IAutomationRegistryMaster.abi.Events["UpkeepMigrated"].ID: + return _IAutomationRegistryMaster.ParseUpkeepMigrated(log) + case _IAutomationRegistryMaster.abi.Events["UpkeepOffchainConfigSet"].ID: + return _IAutomationRegistryMaster.ParseUpkeepOffchainConfigSet(log) + case _IAutomationRegistryMaster.abi.Events["UpkeepPaused"].ID: + return _IAutomationRegistryMaster.ParseUpkeepPaused(log) + case _IAutomationRegistryMaster.abi.Events["UpkeepPerformed"].ID: + return _IAutomationRegistryMaster.ParseUpkeepPerformed(log) + case _IAutomationRegistryMaster.abi.Events["UpkeepPrivilegeConfigSet"].ID: + return _IAutomationRegistryMaster.ParseUpkeepPrivilegeConfigSet(log) + case _IAutomationRegistryMaster.abi.Events["UpkeepReceived"].ID: + return _IAutomationRegistryMaster.ParseUpkeepReceived(log) + case _IAutomationRegistryMaster.abi.Events["UpkeepRegistered"].ID: + return _IAutomationRegistryMaster.ParseUpkeepRegistered(log) + case _IAutomationRegistryMaster.abi.Events["UpkeepTriggerConfigSet"].ID: + return _IAutomationRegistryMaster.ParseUpkeepTriggerConfigSet(log) + case _IAutomationRegistryMaster.abi.Events["UpkeepUnpaused"].ID: + return _IAutomationRegistryMaster.ParseUpkeepUnpaused(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (IAutomationRegistryMasterAdminPrivilegeConfigSet) Topic() common.Hash { + return common.HexToHash("0x7c44b4eb59ee7873514e7e43e7718c269d872965938b288aa143befca62f99d2") +} + +func (IAutomationRegistryMasterCancelledUpkeepReport) Topic() common.Hash { + return common.HexToHash("0xc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636") +} + +func (IAutomationRegistryMasterChainSpecificModuleUpdated) Topic() common.Hash { + return common.HexToHash("0xdefc28b11a7980dbe0c49dbbd7055a1584bc8075097d1e8b3b57fb7283df2ad7") +} + +func (IAutomationRegistryMasterConfigSet) Topic() common.Hash { + return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") +} + +func (IAutomationRegistryMasterDedupKeyAdded) Topic() common.Hash { + return common.HexToHash("0xa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f2") +} + +func (IAutomationRegistryMasterFundsAdded) Topic() common.Hash { + return common.HexToHash("0xafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa734891506203") +} + +func (IAutomationRegistryMasterFundsWithdrawn) Topic() common.Hash { + return common.HexToHash("0xf3b5906e5672f3e524854103bcafbbdba80dbdfeca2c35e116127b1060a68318") +} + +func (IAutomationRegistryMasterInsufficientFundsUpkeepReport) Topic() common.Hash { + return common.HexToHash("0x377c8b0c126ae5248d27aca1c76fac4608aff85673ee3caf09747e1044549e02") +} + +func (IAutomationRegistryMasterOwnerFundsWithdrawn) Topic() common.Hash { + return common.HexToHash("0x1d07d0b0be43d3e5fee41a80b579af370affee03fa595bf56d5d4c19328162f1") +} + +func (IAutomationRegistryMasterOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (IAutomationRegistryMasterOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (IAutomationRegistryMasterPaused) Topic() common.Hash { + return common.HexToHash("0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258") +} + +func (IAutomationRegistryMasterPayeesUpdated) Topic() common.Hash { + return common.HexToHash("0xa46de38886467c59be07a0675f14781206a5477d871628af46c2443822fcb725") +} + +func (IAutomationRegistryMasterPayeeshipTransferRequested) Topic() common.Hash { + return common.HexToHash("0x84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e38367") +} + +func (IAutomationRegistryMasterPayeeshipTransferred) Topic() common.Hash { + return common.HexToHash("0x78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b3") +} + +func (IAutomationRegistryMasterPaymentWithdrawn) Topic() common.Hash { + return common.HexToHash("0x9819093176a1851202c7bcfa46845809b4e47c261866550e94ed3775d2f40698") +} + +func (IAutomationRegistryMasterReorgedUpkeepReport) Topic() common.Hash { + return common.HexToHash("0x6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301") +} + +func (IAutomationRegistryMasterStaleUpkeepReport) Topic() common.Hash { + return common.HexToHash("0x405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8") +} + +func (IAutomationRegistryMasterTransmitted) Topic() common.Hash { + return common.HexToHash("0xb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62") +} + +func (IAutomationRegistryMasterUnpaused) Topic() common.Hash { + return common.HexToHash("0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa") +} + +func (IAutomationRegistryMasterUpkeepAdminTransferRequested) Topic() common.Hash { + return common.HexToHash("0xb1cbb2c4b8480034c27e06da5f096b8233a8fd4497028593a41ff6df79726b35") +} + +func (IAutomationRegistryMasterUpkeepAdminTransferred) Topic() common.Hash { + return common.HexToHash("0x5cff4db96bef051785e999f44bfcd21c18823e034fb92dd376e3db4ce0feeb2c") +} + +func (IAutomationRegistryMasterUpkeepCanceled) Topic() common.Hash { + return common.HexToHash("0x91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f791181") +} + +func (IAutomationRegistryMasterUpkeepCheckDataSet) Topic() common.Hash { + return common.HexToHash("0xcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d") +} + +func (IAutomationRegistryMasterUpkeepGasLimitSet) Topic() common.Hash { + return common.HexToHash("0xc24c07e655ce79fba8a589778987d3c015bc6af1632bb20cf9182e02a65d972c") +} + +func (IAutomationRegistryMasterUpkeepMigrated) Topic() common.Hash { + return common.HexToHash("0xb38647142fbb1ea4c000fc4569b37a4e9a9f6313317b84ee3e5326c1a6cd06ff") +} + +func (IAutomationRegistryMasterUpkeepOffchainConfigSet) Topic() common.Hash { + return common.HexToHash("0x3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf4850") +} + +func (IAutomationRegistryMasterUpkeepPaused) Topic() common.Hash { + return common.HexToHash("0x8ab10247ce168c27748e656ecf852b951fcaac790c18106b19aa0ae57a8b741f") +} + +func (IAutomationRegistryMasterUpkeepPerformed) Topic() common.Hash { + return common.HexToHash("0xad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b") +} + +func (IAutomationRegistryMasterUpkeepPrivilegeConfigSet) Topic() common.Hash { + return common.HexToHash("0x2fd8d70753a007014349d4591843cc031c2dd7a260d7dd82eca8253686ae7769") +} + +func (IAutomationRegistryMasterUpkeepReceived) Topic() common.Hash { + return common.HexToHash("0x74931a144e43a50694897f241d973aecb5024c0e910f9bb80a163ea3c1cf5a71") +} + +func (IAutomationRegistryMasterUpkeepRegistered) Topic() common.Hash { + return common.HexToHash("0xbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d012") +} + +func (IAutomationRegistryMasterUpkeepTriggerConfigSet) Topic() common.Hash { + return common.HexToHash("0x2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d5664") +} + +func (IAutomationRegistryMasterUpkeepUnpaused) Topic() common.Hash { + return common.HexToHash("0x7bada562044eb163f6b4003c4553e4e62825344c0418eea087bed5ee05a47456") +} + +func (_IAutomationRegistryMaster *IAutomationRegistryMaster) Address() common.Address { + return _IAutomationRegistryMaster.address +} + +type IAutomationRegistryMasterInterface interface { + CheckCallback(opts *bind.CallOpts, id *big.Int, values [][]byte, extraData []byte) (CheckCallback, + + error) + + CheckUpkeep(opts *bind.CallOpts, id *big.Int, triggerData []byte) (CheckUpkeep, + + error) + + CheckUpkeep0(opts *bind.CallOpts, id *big.Int) (CheckUpkeep0, + + error) + + FallbackTo(opts *bind.CallOpts) (common.Address, error) + + GetActiveUpkeepIDs(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) + + GetAdminPrivilegeConfig(opts *bind.CallOpts, admin common.Address) ([]byte, error) + + GetAllowedReadOnlyAddress(opts *bind.CallOpts) (common.Address, error) + + GetAutomationForwarderLogic(opts *bind.CallOpts) (common.Address, error) + + GetBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error) + + GetCancellationDelay(opts *bind.CallOpts) (*big.Int, error) + + GetChainModule(opts *bind.CallOpts) (common.Address, error) + + GetConditionalGasOverhead(opts *bind.CallOpts) (*big.Int, error) + + GetFastGasFeedAddress(opts *bind.CallOpts) (common.Address, error) + + GetForwarder(opts *bind.CallOpts, upkeepID *big.Int) (common.Address, error) + + GetLinkAddress(opts *bind.CallOpts) (common.Address, error) + + GetLinkNativeFeedAddress(opts *bind.CallOpts) (common.Address, error) + + GetLogGasOverhead(opts *bind.CallOpts) (*big.Int, error) + + GetMaxPaymentForGas(opts *bind.CallOpts, triggerType uint8, gasLimit uint32) (*big.Int, error) + + GetMinBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error) + + GetMinBalanceForUpkeep(opts *bind.CallOpts, id *big.Int) (*big.Int, error) + + GetPeerRegistryMigrationPermission(opts *bind.CallOpts, peer common.Address) (uint8, error) + + GetPerPerformByteGasOverhead(opts *bind.CallOpts) (*big.Int, error) + + GetPerSignerGasOverhead(opts *bind.CallOpts) (*big.Int, error) + + GetReorgProtectionEnabled(opts *bind.CallOpts) (bool, error) + + GetSignerInfo(opts *bind.CallOpts, query common.Address) (GetSignerInfo, + + error) + + GetState(opts *bind.CallOpts) (GetState, + + error) + + GetTransmitCalldataFixedBytesOverhead(opts *bind.CallOpts) (*big.Int, error) + + GetTransmitCalldataPerSignerBytesOverhead(opts *bind.CallOpts) (*big.Int, error) + + GetTransmitterInfo(opts *bind.CallOpts, query common.Address) (GetTransmitterInfo, + + error) + + GetTriggerType(opts *bind.CallOpts, upkeepId *big.Int) (uint8, error) + + GetUpkeep(opts *bind.CallOpts, id *big.Int) (AutomationRegistryBase23UpkeepInfo, error) + + GetUpkeepPrivilegeConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) + + GetUpkeepTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) + + HasDedupKey(opts *bind.CallOpts, dedupKey [32]byte) (bool, error) + + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) + + LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SimulatePerformUpkeep(opts *bind.CallOpts, id *big.Int, performData []byte) (SimulatePerformUpkeep, + + error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + UpkeepTranscoderVersion(opts *bind.CallOpts) (uint8, error) + + UpkeepVersion(opts *bind.CallOpts) (uint8, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + AcceptPayeeship(opts *bind.TransactOpts, transmitter common.Address) (*types.Transaction, error) + + AcceptUpkeepAdmin(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) + + AddFunds(opts *bind.TransactOpts, id *big.Int, amount *big.Int) (*types.Transaction, error) + + CancelUpkeep(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) + + ExecuteCallback(opts *bind.TransactOpts, id *big.Int, payload []byte) (*types.Transaction, error) + + MigrateUpkeeps(opts *bind.TransactOpts, ids []*big.Int, destination common.Address) (*types.Transaction, error) + + OnTokenTransfer(opts *bind.TransactOpts, sender common.Address, amount *big.Int, data []byte) (*types.Transaction, error) + + Pause(opts *bind.TransactOpts) (*types.Transaction, error) + + PauseUpkeep(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) + + ReceiveUpkeeps(opts *bind.TransactOpts, encodedUpkeeps []byte) (*types.Transaction, error) + + RecoverFunds(opts *bind.TransactOpts) (*types.Transaction, error) + + RegisterUpkeep(opts *bind.TransactOpts, target common.Address, gasLimit uint32, admin common.Address, triggerType uint8, checkData []byte, triggerConfig []byte, offchainConfig []byte) (*types.Transaction, error) + + RegisterUpkeep0(opts *bind.TransactOpts, target common.Address, gasLimit uint32, admin common.Address, checkData []byte, offchainConfig []byte) (*types.Transaction, error) + + SetAdminPrivilegeConfig(opts *bind.TransactOpts, admin common.Address, newPrivilegeConfig []byte) (*types.Transaction, error) + + SetConfig(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfigBytes []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + + SetConfigTypeSafe(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig AutomationRegistryBase23OnchainConfig, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + + SetPayees(opts *bind.TransactOpts, payees []common.Address) (*types.Transaction, error) + + SetPeerRegistryMigrationPermission(opts *bind.TransactOpts, peer common.Address, permission uint8) (*types.Transaction, error) + + SetUpkeepCheckData(opts *bind.TransactOpts, id *big.Int, newCheckData []byte) (*types.Transaction, error) + + SetUpkeepGasLimit(opts *bind.TransactOpts, id *big.Int, gasLimit uint32) (*types.Transaction, error) + + SetUpkeepOffchainConfig(opts *bind.TransactOpts, id *big.Int, config []byte) (*types.Transaction, error) + + SetUpkeepPrivilegeConfig(opts *bind.TransactOpts, upkeepId *big.Int, newPrivilegeConfig []byte) (*types.Transaction, error) + + SetUpkeepTriggerConfig(opts *bind.TransactOpts, id *big.Int, triggerConfig []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + TransferPayeeship(opts *bind.TransactOpts, transmitter common.Address, proposed common.Address) (*types.Transaction, error) + + TransferUpkeepAdmin(opts *bind.TransactOpts, id *big.Int, proposed common.Address) (*types.Transaction, error) + + Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, rawReport []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) + + Unpause(opts *bind.TransactOpts) (*types.Transaction, error) + + UnpauseUpkeep(opts *bind.TransactOpts, id *big.Int) (*types.Transaction, error) + + WithdrawFunds(opts *bind.TransactOpts, id *big.Int, to common.Address) (*types.Transaction, error) + + WithdrawOwnerFunds(opts *bind.TransactOpts) (*types.Transaction, error) + + WithdrawPayment(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) + + Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) + + FilterAdminPrivilegeConfigSet(opts *bind.FilterOpts, admin []common.Address) (*IAutomationRegistryMasterAdminPrivilegeConfigSetIterator, error) + + WatchAdminPrivilegeConfigSet(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterAdminPrivilegeConfigSet, admin []common.Address) (event.Subscription, error) + + ParseAdminPrivilegeConfigSet(log types.Log) (*IAutomationRegistryMasterAdminPrivilegeConfigSet, error) + + FilterCancelledUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterCancelledUpkeepReportIterator, error) + + WatchCancelledUpkeepReport(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterCancelledUpkeepReport, id []*big.Int) (event.Subscription, error) + + ParseCancelledUpkeepReport(log types.Log) (*IAutomationRegistryMasterCancelledUpkeepReport, error) + + FilterChainSpecificModuleUpdated(opts *bind.FilterOpts) (*IAutomationRegistryMasterChainSpecificModuleUpdatedIterator, error) + + WatchChainSpecificModuleUpdated(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterChainSpecificModuleUpdated) (event.Subscription, error) + + ParseChainSpecificModuleUpdated(log types.Log) (*IAutomationRegistryMasterChainSpecificModuleUpdated, error) + + FilterConfigSet(opts *bind.FilterOpts) (*IAutomationRegistryMasterConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*IAutomationRegistryMasterConfigSet, error) + + FilterDedupKeyAdded(opts *bind.FilterOpts, dedupKey [][32]byte) (*IAutomationRegistryMasterDedupKeyAddedIterator, error) + + WatchDedupKeyAdded(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterDedupKeyAdded, dedupKey [][32]byte) (event.Subscription, error) + + ParseDedupKeyAdded(log types.Log) (*IAutomationRegistryMasterDedupKeyAdded, error) + + FilterFundsAdded(opts *bind.FilterOpts, id []*big.Int, from []common.Address) (*IAutomationRegistryMasterFundsAddedIterator, error) + + WatchFundsAdded(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterFundsAdded, id []*big.Int, from []common.Address) (event.Subscription, error) + + ParseFundsAdded(log types.Log) (*IAutomationRegistryMasterFundsAdded, error) + + FilterFundsWithdrawn(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterFundsWithdrawnIterator, error) + + WatchFundsWithdrawn(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterFundsWithdrawn, id []*big.Int) (event.Subscription, error) + + ParseFundsWithdrawn(log types.Log) (*IAutomationRegistryMasterFundsWithdrawn, error) + + FilterInsufficientFundsUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterInsufficientFundsUpkeepReportIterator, error) + + WatchInsufficientFundsUpkeepReport(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterInsufficientFundsUpkeepReport, id []*big.Int) (event.Subscription, error) + + ParseInsufficientFundsUpkeepReport(log types.Log) (*IAutomationRegistryMasterInsufficientFundsUpkeepReport, error) + + FilterOwnerFundsWithdrawn(opts *bind.FilterOpts) (*IAutomationRegistryMasterOwnerFundsWithdrawnIterator, error) + + WatchOwnerFundsWithdrawn(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterOwnerFundsWithdrawn) (event.Subscription, error) + + ParseOwnerFundsWithdrawn(log types.Log) (*IAutomationRegistryMasterOwnerFundsWithdrawn, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*IAutomationRegistryMasterOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*IAutomationRegistryMasterOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*IAutomationRegistryMasterOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*IAutomationRegistryMasterOwnershipTransferred, error) + + FilterPaused(opts *bind.FilterOpts) (*IAutomationRegistryMasterPausedIterator, error) + + WatchPaused(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterPaused) (event.Subscription, error) + + ParsePaused(log types.Log) (*IAutomationRegistryMasterPaused, error) + + FilterPayeesUpdated(opts *bind.FilterOpts) (*IAutomationRegistryMasterPayeesUpdatedIterator, error) + + WatchPayeesUpdated(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterPayeesUpdated) (event.Subscription, error) + + ParsePayeesUpdated(log types.Log) (*IAutomationRegistryMasterPayeesUpdated, error) + + FilterPayeeshipTransferRequested(opts *bind.FilterOpts, transmitter []common.Address, from []common.Address, to []common.Address) (*IAutomationRegistryMasterPayeeshipTransferRequestedIterator, error) + + WatchPayeeshipTransferRequested(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterPayeeshipTransferRequested, transmitter []common.Address, from []common.Address, to []common.Address) (event.Subscription, error) + + ParsePayeeshipTransferRequested(log types.Log) (*IAutomationRegistryMasterPayeeshipTransferRequested, error) + + FilterPayeeshipTransferred(opts *bind.FilterOpts, transmitter []common.Address, from []common.Address, to []common.Address) (*IAutomationRegistryMasterPayeeshipTransferredIterator, error) + + WatchPayeeshipTransferred(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterPayeeshipTransferred, transmitter []common.Address, from []common.Address, to []common.Address) (event.Subscription, error) + + ParsePayeeshipTransferred(log types.Log) (*IAutomationRegistryMasterPayeeshipTransferred, error) + + FilterPaymentWithdrawn(opts *bind.FilterOpts, transmitter []common.Address, amount []*big.Int, to []common.Address) (*IAutomationRegistryMasterPaymentWithdrawnIterator, error) + + WatchPaymentWithdrawn(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterPaymentWithdrawn, transmitter []common.Address, amount []*big.Int, to []common.Address) (event.Subscription, error) + + ParsePaymentWithdrawn(log types.Log) (*IAutomationRegistryMasterPaymentWithdrawn, error) + + FilterReorgedUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterReorgedUpkeepReportIterator, error) + + WatchReorgedUpkeepReport(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterReorgedUpkeepReport, id []*big.Int) (event.Subscription, error) + + ParseReorgedUpkeepReport(log types.Log) (*IAutomationRegistryMasterReorgedUpkeepReport, error) + + FilterStaleUpkeepReport(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterStaleUpkeepReportIterator, error) + + WatchStaleUpkeepReport(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterStaleUpkeepReport, id []*big.Int) (event.Subscription, error) + + ParseStaleUpkeepReport(log types.Log) (*IAutomationRegistryMasterStaleUpkeepReport, error) + + FilterTransmitted(opts *bind.FilterOpts) (*IAutomationRegistryMasterTransmittedIterator, error) + + WatchTransmitted(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterTransmitted) (event.Subscription, error) + + ParseTransmitted(log types.Log) (*IAutomationRegistryMasterTransmitted, error) + + FilterUnpaused(opts *bind.FilterOpts) (*IAutomationRegistryMasterUnpausedIterator, error) + + WatchUnpaused(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUnpaused) (event.Subscription, error) + + ParseUnpaused(log types.Log) (*IAutomationRegistryMasterUnpaused, error) + + FilterUpkeepAdminTransferRequested(opts *bind.FilterOpts, id []*big.Int, from []common.Address, to []common.Address) (*IAutomationRegistryMasterUpkeepAdminTransferRequestedIterator, error) + + WatchUpkeepAdminTransferRequested(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepAdminTransferRequested, id []*big.Int, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseUpkeepAdminTransferRequested(log types.Log) (*IAutomationRegistryMasterUpkeepAdminTransferRequested, error) + + FilterUpkeepAdminTransferred(opts *bind.FilterOpts, id []*big.Int, from []common.Address, to []common.Address) (*IAutomationRegistryMasterUpkeepAdminTransferredIterator, error) + + WatchUpkeepAdminTransferred(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepAdminTransferred, id []*big.Int, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseUpkeepAdminTransferred(log types.Log) (*IAutomationRegistryMasterUpkeepAdminTransferred, error) + + FilterUpkeepCanceled(opts *bind.FilterOpts, id []*big.Int, atBlockHeight []uint64) (*IAutomationRegistryMasterUpkeepCanceledIterator, error) + + WatchUpkeepCanceled(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepCanceled, id []*big.Int, atBlockHeight []uint64) (event.Subscription, error) + + ParseUpkeepCanceled(log types.Log) (*IAutomationRegistryMasterUpkeepCanceled, error) + + FilterUpkeepCheckDataSet(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterUpkeepCheckDataSetIterator, error) + + WatchUpkeepCheckDataSet(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepCheckDataSet, id []*big.Int) (event.Subscription, error) + + ParseUpkeepCheckDataSet(log types.Log) (*IAutomationRegistryMasterUpkeepCheckDataSet, error) + + FilterUpkeepGasLimitSet(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterUpkeepGasLimitSetIterator, error) + + WatchUpkeepGasLimitSet(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepGasLimitSet, id []*big.Int) (event.Subscription, error) + + ParseUpkeepGasLimitSet(log types.Log) (*IAutomationRegistryMasterUpkeepGasLimitSet, error) + + FilterUpkeepMigrated(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterUpkeepMigratedIterator, error) + + WatchUpkeepMigrated(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepMigrated, id []*big.Int) (event.Subscription, error) + + ParseUpkeepMigrated(log types.Log) (*IAutomationRegistryMasterUpkeepMigrated, error) + + FilterUpkeepOffchainConfigSet(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterUpkeepOffchainConfigSetIterator, error) + + WatchUpkeepOffchainConfigSet(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepOffchainConfigSet, id []*big.Int) (event.Subscription, error) + + ParseUpkeepOffchainConfigSet(log types.Log) (*IAutomationRegistryMasterUpkeepOffchainConfigSet, error) + + FilterUpkeepPaused(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterUpkeepPausedIterator, error) + + WatchUpkeepPaused(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepPaused, id []*big.Int) (event.Subscription, error) + + ParseUpkeepPaused(log types.Log) (*IAutomationRegistryMasterUpkeepPaused, error) + + FilterUpkeepPerformed(opts *bind.FilterOpts, id []*big.Int, success []bool) (*IAutomationRegistryMasterUpkeepPerformedIterator, error) + + WatchUpkeepPerformed(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepPerformed, id []*big.Int, success []bool) (event.Subscription, error) + + ParseUpkeepPerformed(log types.Log) (*IAutomationRegistryMasterUpkeepPerformed, error) + + FilterUpkeepPrivilegeConfigSet(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterUpkeepPrivilegeConfigSetIterator, error) + + WatchUpkeepPrivilegeConfigSet(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepPrivilegeConfigSet, id []*big.Int) (event.Subscription, error) + + ParseUpkeepPrivilegeConfigSet(log types.Log) (*IAutomationRegistryMasterUpkeepPrivilegeConfigSet, error) + + FilterUpkeepReceived(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterUpkeepReceivedIterator, error) + + WatchUpkeepReceived(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepReceived, id []*big.Int) (event.Subscription, error) + + ParseUpkeepReceived(log types.Log) (*IAutomationRegistryMasterUpkeepReceived, error) + + FilterUpkeepRegistered(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterUpkeepRegisteredIterator, error) + + WatchUpkeepRegistered(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepRegistered, id []*big.Int) (event.Subscription, error) + + ParseUpkeepRegistered(log types.Log) (*IAutomationRegistryMasterUpkeepRegistered, error) + + FilterUpkeepTriggerConfigSet(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterUpkeepTriggerConfigSetIterator, error) + + WatchUpkeepTriggerConfigSet(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepTriggerConfigSet, id []*big.Int) (event.Subscription, error) + + ParseUpkeepTriggerConfigSet(log types.Log) (*IAutomationRegistryMasterUpkeepTriggerConfigSet, error) + + FilterUpkeepUnpaused(opts *bind.FilterOpts, id []*big.Int) (*IAutomationRegistryMasterUpkeepUnpausedIterator, error) + + WatchUpkeepUnpaused(opts *bind.WatchOpts, sink chan<- *IAutomationRegistryMasterUpkeepUnpaused, id []*big.Int) (event.Subscription, error) + + ParseUpkeepUnpaused(log types.Log) (*IAutomationRegistryMasterUpkeepUnpaused, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 545e5f6dfda..6bf2ad1b4b2 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -8,11 +8,16 @@ automation_consumer_benchmark: ../../contracts/solc/v0.8.16/AutomationConsumerBe automation_forwarder_logic: ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.abi ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.bin 15ae0c367297955fdab4b552dbb10e1f2be80a8fde0efec4a4d398693e9d72b5 automation_registrar_wrapper2_1: ../../contracts/solc/v0.8.16/AutomationRegistrar2_1/AutomationRegistrar2_1.abi ../../contracts/solc/v0.8.16/AutomationRegistrar2_1/AutomationRegistrar2_1.bin eb06d853aab39d3196c593b03e555851cbe8386e0fe54a74c2479f62d14b3c42 automation_registrar_wrapper2_2: ../../contracts/solc/v0.8.19/AutomationRegistrar2_2/AutomationRegistrar2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistrar2_2/AutomationRegistrar2_2.bin 7c61908c1bb1bfd05a4da22bb73d62c0e2c05240f3f8fb5e06331603ff2246a9 +automation_registrar_wrapper2_3: ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.bin 8e18d447009546ac8ad15d0d516ad4d663d0e1ca5f723300acb604b5571b63bf automation_registry_logic_a_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.bin 58d09c16be20a6d3f70be6d06299ed61415b7796c71f176d87ce015e1294e029 +automation_registry_logic_a_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.bin 56b9ed9923d0610fcc5c23c7e0d8f013195313138fbd2630b5148aced302582e automation_registry_logic_b_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.bin e5669214a6b747b17331ebbf8f2d13cf7100d3313d652c6f1304ccf158441fc6 +automation_registry_logic_b_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_3/AutomationRegistryLogicB2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_3/AutomationRegistryLogicB2_3.bin 94a4b8b2d8116c13a6a0b03d4d726856e0f9bfdaf88e46c2fd5427c10c5589ca automation_registry_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.bin eca1187a878b622ef3fced041a28a4229d45dd797d95630838ff6351b6afc437 +automation_registry_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.bin 188df879a68b5ea35b909d33b050f32e4195670152c243957f7c78e3499d1b4e automation_utils_2_1: ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.abi ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.bin 331bfa79685aee6ddf63b64c0747abee556c454cae3fb8175edff425b615d8aa automation_utils_2_2: ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.abi ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.bin 6fe2e41b1d3b74bee4013a48c10d84da25e559f28e22749aa13efabbf2cc2ee8 +automation_utils_2_3: ../../contracts/solc/v0.8.19/AutomationUtils2_3/AutomationUtils2_3.abi ../../contracts/solc/v0.8.19/AutomationUtils2_3/AutomationUtils2_3.bin aa2373b5913b9ad6a641011d9cbd77c5c7042a05a61672127609ebff58f75905 batch_blockhash_store: ../../contracts/solc/v0.8.6/BatchBlockhashStore/BatchBlockhashStore.abi ../../contracts/solc/v0.8.6/BatchBlockhashStore/BatchBlockhashStore.bin 14356c48ef70f66ef74f22f644450dbf3b2a147c1b68deaa7e7d1eb8ffab15db batch_vrf_coordinator_v2: ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2/BatchVRFCoordinatorV2.abi ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2/BatchVRFCoordinatorV2.bin d0a54963260d8c1f1bbd984b758285e6027cfb5a7e42701bcb562ab123219332 batch_vrf_coordinator_v2plus: ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2Plus/BatchVRFCoordinatorV2Plus.abi ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2Plus/BatchVRFCoordinatorV2Plus.bin 73cb626b5cb2c3464655b61b8ac42fe7a1963fe25e6a5eea40b8e4d5bff3de36 @@ -29,6 +34,7 @@ flux_aggregator_wrapper: ../../contracts/solc/v0.6/FluxAggregator/FluxAggregator gas_wrapper: ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.abi ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.bin 4a5dcdac486d18fcd58e3488c15c1710ae76b977556a3f3191bd269a4bc75723 gas_wrapper_mock: ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.abi ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.bin a9b08f18da59125c6fc305855710241f3d35161b8b9f3e3f635a7b1d5c6da9c8 i_automation_registry_master_wrapper_2_2: ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.bin 0886dd1df1f4dcf5b08012f8adcf30fd96caab28999610e70ce02beb2170c92f +i_automation_registry_master_wrapper_2_3: ../../contracts/solc/v0.8.19/IAutomationRegistryMaster2_3/IAutomationRegistryMaster.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster2_3/IAutomationRegistryMaster.bin fa3527675516bccfbc266697e37b60b77aee45018b80a5e98e027008f5fe2dfd i_chain_module: ../../contracts/solc/v0.8.19/IChainModule/IChainModule.abi ../../contracts/solc/v0.8.19/IChainModule/IChainModule.bin 383611981c86c70522f41b8750719faacc7d7933a22849d5004799ebef3371fa i_keeper_registry_master_wrapper_2_1: ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.abi ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.bin 6501bb9bcf5048bab2737b00685c6984a24867e234ddf5b60a65904eee9a4ebc i_log_automation: ../../contracts/solc/v0.8.16/ILogAutomation/ILogAutomation.abi ../../contracts/solc/v0.8.16/ILogAutomation/ILogAutomation.bin 296beccb6af655d6fc3a6e676b244831cce2da6688d3afc4f21f8738ae59e03e diff --git a/core/gethwrappers/go_generate.go b/core/gethwrappers/go_generate.go index c582583b783..2744f14c003 100644 --- a/core/gethwrappers/go_generate.go +++ b/core/gethwrappers/go_generate.go @@ -62,6 +62,12 @@ package gethwrappers //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.bin AutomationRegistryLogicB automation_registry_logic_b_wrapper_2_2 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.bin IAutomationRegistryMaster i_automation_registry_master_wrapper_2_2 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.abi ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.bin AutomationUtils automation_utils_2_2 +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.bin AutomationRegistrar automation_registrar_wrapper2_3 +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.bin AutomationRegistry automation_registry_wrapper_2_3 +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.bin AutomationRegistryLogicA automation_registry_logic_a_wrapper_2_3 +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_3/AutomationRegistryLogicB2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_3/AutomationRegistryLogicB2_3.bin AutomationRegistryLogicB automation_registry_logic_b_wrapper_2_3 +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/IAutomationRegistryMaster2_3/IAutomationRegistryMaster.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster2_3/IAutomationRegistryMaster.bin IAutomationRegistryMaster i_automation_registry_master_wrapper_2_3 +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationUtils2_3/AutomationUtils2_3.abi ../../contracts/solc/v0.8.19/AutomationUtils2_3/AutomationUtils2_3.bin AutomationUtils automation_utils_2_3 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/ArbitrumModule/ArbitrumModule.abi ../../contracts/solc/v0.8.19/ArbitrumModule/ArbitrumModule.bin ArbitrumModule arbitrum_module //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.abi ../../contracts/solc/v0.8.19/ChainModuleBase/ChainModuleBase.bin ChainModuleBase chain_module_base //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/OptimismModule/OptimismModule.abi ../../contracts/solc/v0.8.19/OptimismModule/OptimismModule.bin OptimismModule optimism_module From 03fc9adb34127396db050fd4136134dd3cedb769 Mon Sep 17 00:00:00 2001 From: Sergey Kudasov Date: Wed, 6 Mar 2024 02:53:35 +0100 Subject: [PATCH 22/34] Simple/scalable cluster update process for devs (#12299) * try multi-node sync * simplify, prefer image sync instead of dev, always use goreleaser image * Update charts/chainlink-cluster/devspace.yaml Co-authored-by: chainchad <96362174+chainchad@users.noreply.github.com> * Update charts/chainlink-cluster/devspace.yaml Co-authored-by: chainchad <96362174+chainchad@users.noreply.github.com> * simplify, prefer image sync instead of dev, always use goreleaser image --------- Co-authored-by: chainchad <96362174+chainchad@users.noreply.github.com> --- .goreleaser.devspace.yaml | 92 ++++++++++++++ GNUmakefile | 4 - charts/chainlink-cluster/README.md | 23 +--- charts/chainlink-cluster/devspace.yaml | 113 ++---------------- .../templates/runner-deployment.yaml | 71 ----------- .../templates/runner-networkpolicy.yaml | 21 ---- charts/chainlink-cluster/values.yaml | 32 ----- core/chainlink.devspace.Dockerfile | 73 ----------- 8 files changed, 108 insertions(+), 321 deletions(-) create mode 100644 .goreleaser.devspace.yaml delete mode 100644 charts/chainlink-cluster/templates/runner-deployment.yaml delete mode 100644 charts/chainlink-cluster/templates/runner-networkpolicy.yaml delete mode 100644 core/chainlink.devspace.Dockerfile diff --git a/.goreleaser.devspace.yaml b/.goreleaser.devspace.yaml new file mode 100644 index 00000000000..21888325fca --- /dev/null +++ b/.goreleaser.devspace.yaml @@ -0,0 +1,92 @@ +## goreleaser <1.14.0 +project_name: chainlink + +env: + - ZIG_EXEC={{ if index .Env "ZIG_EXEC" }}{{ .Env.ZIG_EXEC }}{{ else }}zig{{ end }} + - IMAGE_PREFIX={{ if index .Env "IMAGE_PREFIX" }}{{ .Env.IMAGE_PREFIX }}{{ else }}localhost:5001{{ end }} + - IMAGE_LABEL_DESCRIPTION="node of the decentralized oracle network, bridging on and off-chain computation" + - IMAGE_LABEL_LICENSES="MIT" + - IMAGE_LABEL_SOURCE="https://github.com/smartcontractkit/{{ .ProjectName }}" + +before: + hooks: + - go mod tidy + - ./tools/bin/goreleaser_utils before_hook + + +# See https://goreleaser.com/customization/build/ +builds: + - binary: chainlink + id: linux-amd64 + goos: + - linux + goarch: + - amd64 + hooks: + post: ./tools/bin/goreleaser_utils build_post_hook {{ dir .Path }} {{ .Os }} {{ .Arch }} + env: + - CGO_ENABLED=1 + - CC=$ZIG_EXEC cc -target x86_64-linux-gnu + - CCX=$ZIG_EXEC c++ -target x86_64-linux-gnu + flags: + - -trimpath + - -buildmode=pie + ldflags: + - -s -w -r=$ORIGIN/libs + - -X github.com/smartcontractkit/chainlink/v2/core/static.Version={{ .Env.CHAINLINK_VERSION }} + - -X github.com/smartcontractkit/chainlink/v2/core/static.Sha={{ .FullCommit }} +# See https://goreleaser.com/customization/docker/ +dockers: + - id: linux-amd64 + dockerfile: core/chainlink.goreleaser.Dockerfile + use: buildx + goos: linux + goarch: amd64 + extra_files: + - tmp/linux_amd64/libs + - tools/bin/ldd_fix + build_flag_templates: + - "--platform=linux/amd64" + - "--pull" + - "--build-arg=CHAINLINK_USER=chainlink" + - "--build-arg=COMMIT_SHA={{ .FullCommit }}" + - "--label=org.opencontainers.image.created={{ .Date }}" + - "--label=org.opencontainers.image.description={{ .Env.IMAGE_LABEL_DESCRIPTION }}" + - "--label=org.opencontainers.image.licenses={{ .Env.IMAGE_LABEL_LICENSES }}" + - "--label=org.opencontainers.image.revision={{ .FullCommit }}" + - "--label=org.opencontainers.image.source={{ .Env.IMAGE_LABEL_SOURCE }}" + - "--label=org.opencontainers.image.title={{ .ProjectName }}" + - "--label=org.opencontainers.image.version={{ .Env.CHAINLINK_VERSION }}" + - "--label=org.opencontainers.image.url={{ .Env.IMAGE_LABEL_SOURCE }}" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:develop-amd64" + - "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:sha-{{ .ShortCommit }}-amd64" +# See https://goreleaser.com/customization/docker_manifest/ +docker_manifests: + - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:develop" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:develop-amd64" + - name_template: "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:sha-{{ .ShortCommit }}" + image_templates: + - "{{ .Env.IMAGE_PREFIX }}/{{ .ProjectName }}-develop:sha-{{ .ShortCommit }}-amd64" + +# See https://goreleaser.com/customization/docker_sign/ +docker_signs: + - artifacts: all + stdin: "{{ .Env.COSIGN_PASSWORD }}" + +checksum: + name_template: "checksums.txt" + +snapshot: + name_template: "{{ .Env.CHAINLINK_VERSION }}-{{ .ShortCommit }}" + +changelog: + sort: asc + filters: + exclude: + - "^docs:" + - "^test:" +# modelines, feel free to remove those if you don't want/use them: +# yaml-language-server: $schema=https://goreleaser.com/static/schema.json +# vim: set ts=2 sw=2 tw=0 fo=cnqoj diff --git a/GNUmakefile b/GNUmakefile index c68e13f8ae6..46565a2778a 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -55,10 +55,6 @@ chainlink-dev: ## Build a dev build of chainlink binary. chainlink-test: ## Build a test build of chainlink binary. go build $(GOFLAGS) . -.PHONY: chainlink-local-start -chainlink-local-start: - ./chainlink -c /etc/node-secrets-volume/default.toml -c /etc/node-secrets-volume/overrides.toml -secrets /etc/node-secrets-volume/secrets.toml node start -d -p /etc/node-secrets-volume/node-password -a /etc/node-secrets-volume/apicredentials --vrfpassword=/etc/node-secrets-volume/apicredentials - .PHONY: install-medianpoc install-medianpoc: ## Build & install the chainlink-medianpoc binary. go install $(GOFLAGS) ./plugins/cmd/chainlink-medianpoc diff --git a/charts/chainlink-cluster/README.md b/charts/chainlink-cluster/README.md index 394e11d2070..0943ca5a8b6 100644 --- a/charts/chainlink-cluster/README.md +++ b/charts/chainlink-cluster/README.md @@ -19,10 +19,9 @@ We are using [devspace](https://www.devspace.sh/docs/getting-started/installatio Configure the cluster, see `deployments.app.helm.values` and [values.yaml](./values.yaml) comments for more details -Configure your `cluster` setup (one time setup, internal usage only) +Set up your K8s access ``` export DEVSPACE_IMAGE="..." -cd charts/chainlink-cluster ./setup.sh ${my-personal-namespace-name-crib} ``` @@ -38,12 +37,12 @@ Valid values are `1h`, `2m`, `3s`, etc. Go time format is invalid `1h2m3s` devspace run ttl ${namespace} 120h ``` -If you don't need a build use +If you don't need to build use ``` devspace deploy --skip-build ``` -To deploy particular commit (must be in registry) use +To deploy particular commit (must be in the registry) use ``` devspace deploy --skip-build ${short_sha_of_image} ``` @@ -53,22 +52,12 @@ Forward ports to check UI or run tests devspace run connect ${my-personal-namespace-name-crib} ``` -Connect to your environment, by replacing container with label `node-1` with your local repository files +Update some Go code of Chainlink node and quickly sync your cluster ``` -devspace dev -p node -make chainlink -make chainlink-local-start -``` -Fix something in the code locally, it'd automatically sync, rebuild it inside container and run again -``` -make chainlink -make chainlink-local-start +devspace dev ``` -Reset the pod to original image -``` -devspace reset pods -``` +To reset pods to original image just checkout needed commit and do `devspace deploy` again Destroy the cluster ``` diff --git a/charts/chainlink-cluster/devspace.yaml b/charts/chainlink-cluster/devspace.yaml index d2b412ba264..6256ae41bf0 100644 --- a/charts/chainlink-cluster/devspace.yaml +++ b/charts/chainlink-cluster/devspace.yaml @@ -15,14 +15,19 @@ vars: # This is a comma separated list of CIDR blocks that will be allowed to access the ingress. DEVSPACE_INGRESS_CIDRS: source: env + # Time to wait for pods to be in `Ready` condition + DEVSPACE_K8S_POD_WAIT_TIMEOUT: 600s # This is a list of `pipelines` that DevSpace can execute (you can define your own) pipelines: dev: + # We don't need a rollout here and image haven't been really changed, + # may not deserve to be commited, so we are just rebooting the app pods run: |- - run_dependencies --all # 1. Deploy any projects this project needs (see "dependencies") - ensure_pull_secrets --all # 2. Ensure pull secrets - start_dev app # 3. Start dev mode "app" (see "dev" section) + devspace run-pipeline deploy + kubectl get pods -n ${DEVSPACE_NAMESPACE} --no-headers=true | grep '^app-node-' | awk '{print $1}' | xargs kubectl delete pod -n ${DEVSPACE_NAMESPACE} + kubectl wait pods -n ${DEVSPACE_NAMESPACE} --selector=app=app --for=condition=Ready --timeout=${DEVSPACE_K8S_POD_WAIT_TIMEOUT} + # You can run this pipeline via `devspace deploy` (or `devspace run-pipeline deploy`) deploy: run: |- set -o pipefail @@ -101,7 +106,7 @@ images: pushd $TOPLEVEL pwd goreleaser --version - MACOS_SDK_DIR=$(pwd)/tools/bin/MacOSX12.3.sdk ./tools/bin/goreleaser_wrapper release --snapshot --clean --config .goreleaser.develop.yaml + MACOS_SDK_DIR=$(pwd)/tools/bin/MacOSX12.3.sdk ./tools/bin/goreleaser_wrapper release --snapshot --clean --config .goreleaser.devspace.yaml popd BUILT_IMAGE=$(cat $TOPLEVEL/dist/artifacts.json | jq -r '.[] | select(.type == "Docker Image" and .goarch == "amd64" and (.name | contains("sha")) and ( .name | contains("root") | not) ) | .name') @@ -280,36 +285,6 @@ deployments: limits: cpu: 1 memory: 1024Mi - runner: - securityContext: - capabilities: - drop: - - ALL - readOnlyRootFilesystem: false - runAsNonRoot: true - runAsUser: 999 - runAsGroup: 999 - stateful: false - resources: - requests: - cpu: 1 - memory: 512Mi - limits: - cpu: 1 - memory: 512Mi - affinity: {} - tolerations: [] - nodeSelector: {} - ingress: - enabled: false - className: "" - hosts: [] - tls: [] - annotations: {} - service: - type: NodePort - port: 8080 - # monitoring.coreos.com/v1 PodMonitor for each node prometheusMonitor: true @@ -429,72 +404,4 @@ deployments: podAnnotations: nodeSelector: tolerations: - affinity: - -profiles: - # this replaces only "runner" pod, usable when you'd like to run some system level tests inside k8s - - name: runner - patches: - - op: replace - path: dev.app.workingDir - value: /home/chainlink/integration-tests - - op: replace - path: dev.app.container - value: runner - - op: replace - path: dev.app.labelSelector.instance - value: runner-1 - - op: remove - path: dev.app.sync[1].uploadExcludePaths[0] - - op: remove - path: dev.app.open - - op: remove - path: dev.app.ports[1] - - name: node - patches: - - op: replace - path: dev.app.container - value: node - - op: replace - path: dev.app.labelSelector.instance - value: node-1 - -# This is a list of `dev` containers that are based on the containers created by your deployments -dev: - app: - workingDir: /home/chainlink - container: node - labelSelector: - instance: node-1 - # Sync files between the local filesystem and the development container - sync: - - path: ../../core/services/chainlink:/home/chainlink/core/services/chainlink - printLogs: true - disableDownload: true - - path: ../..:/home/chainlink - printLogs: true - disableDownload: true - uploadExcludePaths: - - integration-tests/ - - .github/ - - belt/ - - charts/ - - contracts/ - - node_modules/ - - integration/ - - integration-scripts/ - - testdata/ - - evm-test-helpers/ - # Open a terminal and use the following command - terminal: - command: bash - ssh: - enabled: true - proxyCommands: - # TODO: access issues - # - command: devspace - # - command: kubectl - # - command: helm - - gitCredentials: true - ports: - - port: "2345" + affinity: \ No newline at end of file diff --git a/charts/chainlink-cluster/templates/runner-deployment.yaml b/charts/chainlink-cluster/templates/runner-deployment.yaml deleted file mode 100644 index 9d80ac1bfab..00000000000 --- a/charts/chainlink-cluster/templates/runner-deployment.yaml +++ /dev/null @@ -1,71 +0,0 @@ -{{ if (hasKey .Values "runner")}} -apiVersion: apps/v1 -{{ if .Values.runner.stateful }} -kind: StatefulSet -{{ else }} -kind: Deployment -{{ end }} -metadata: - name: runner -spec: - selector: - matchLabels: - app: runner - instance: runner-1 - release: {{ .Release.Name }} - template: - metadata: - labels: - app: runner - instance: runner-1 - release: {{ .Release.Name }} - annotations: - prometheus.io/scrape: 'true' - spec: - securityContext: - {{- toYaml $.Values.runner.podSecurityContext | nindent 8 }} - containers: - - name: runner - securityContext: - {{- toYaml $.Values.runner.securityContext | nindent 12 }} - image: {{ default "public.ecr.aws/chainlink/chainlink" .Values.runner.image }} - imagePullPolicy: Always - command: [ "/bin/bash", "-c", "--" ] - args: [ "tail -f /dev/null" ] - {{ if (hasKey .Values.runner "env") }} - env: - {{- range $key, $value := .Values.runner.env }} - {{- if $value }} - - name: {{ $key | upper}} - {{- if kindIs "string" $value}} - value: {{ $value | quote}} - {{- else }} - value: {{ $value }} - {{- end }} - {{- end }} - {{- end }} - {{ end }} - {{ if (hasKey .Values.runner "resources") }} - resources: - requests: - memory: {{ default "1024Mi" .Values.runner.resources.requests.memory }} - cpu: {{ default "500m" $.Values.runner.resources.requests.cpu }} - limits: - memory: {{ default "1024Mi" $.Values.runner.resources.limits.memory }} - cpu: {{ default "500m" $.Values.runner.resources.limits.cpu }} - {{ else }} - {{ end }} -{{- with $.Values.nodeSelector }} - nodeSelector: -{{ toYaml . | indent 8 }} -{{- end }} -{{- with .Values.affinity }} - affinity: -{{ toYaml . | indent 8 }} -{{- end }} -{{- with .Values.tolerations }} - tolerations: -{{ toYaml . | indent 8 }} -{{- end }} ---- -{{ end }} \ No newline at end of file diff --git a/charts/chainlink-cluster/templates/runner-networkpolicy.yaml b/charts/chainlink-cluster/templates/runner-networkpolicy.yaml deleted file mode 100644 index b75a2ffa772..00000000000 --- a/charts/chainlink-cluster/templates/runner-networkpolicy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if .Values.networkPolicies.enabled }} -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: {{ $.Release.Name }}-runner -spec: - podSelector: - matchLabels: - app: runner - policyTypes: - - Ingress - ingress: - # Allow all ingress traffic between the node pods and from runner pod. - - from: - - podSelector: - matchLabels: - app: {{ $.Release.Name }} - - podSelector: - matchLabels: - app: runner -{{- end }} \ No newline at end of file diff --git a/charts/chainlink-cluster/values.yaml b/charts/chainlink-cluster/values.yaml index 303cec04213..b0866574c90 100644 --- a/charts/chainlink-cluster/values.yaml +++ b/charts/chainlink-cluster/values.yaml @@ -160,38 +160,6 @@ mockserver: limits: cpu: 1 memory: 1024Mi -runner: - podSecurityContext: - fsGroup: 999 - securityContext: - capabilities: - drop: - - ALL - readOnlyRootFilesystem: false - runAsNonRoot: true - runAsUser: 999 - runAsGroup: 999 - stateful: false - resources: - requests: - cpu: 1 - memory: 512Mi - limits: - cpu: 1 - memory: 512Mi - affinity: {} - tolerations: [] - nodeSelector: {} - ingress: - enabled: false - className: "" - hosts: [] - tls: [] - annotations: {} - service: - type: NodePort - port: 8080 - opentelemetry-collector: enabled: true mode: deployment diff --git a/core/chainlink.devspace.Dockerfile b/core/chainlink.devspace.Dockerfile deleted file mode 100644 index 28504b40d7a..00000000000 --- a/core/chainlink.devspace.Dockerfile +++ /dev/null @@ -1,73 +0,0 @@ -# Build image: Chainlink binary -FROM golang:1.21-bullseye AS buildgo -RUN go version -WORKDIR /chainlink - -COPY GNUmakefile VERSION ./ -COPY tools/bin/ldflags ./tools/bin/ - -ADD go.mod go.sum ./ -RUN go mod download - -# Env vars needed for chainlink build -ARG COMMIT_SHA - -COPY . . - -# Build the golang binary -RUN make install-chainlink - -# Link LOOP Plugin source dirs with simple names -RUN go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-feeds | xargs -I % ln -s % /chainlink-feeds -RUN go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-solana | xargs -I % ln -s % /chainlink-solana - -# Build image: Plugins -FROM golang:1.21-bullseye AS buildplugins -RUN go version - -WORKDIR /chainlink-feeds -COPY --from=buildgo /chainlink-feeds . -RUN go install ./cmd/chainlink-feeds - -WORKDIR /chainlink-solana -COPY --from=buildgo /chainlink-solana . -RUN go install ./pkg/solana/cmd/chainlink-solana - -# Final image: ubuntu with chainlink binary -FROM --platform=linux/amd64 golang:1.21-bullseye - -ARG CHAINLINK_USER=chainlink -ENV DEBIAN_FRONTEND noninteractive -RUN apt-get update && apt-get install -y ca-certificates gnupg lsb-release curl - -# Install Postgres for CLI tools, needed specifically for DB backups -RUN curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \ - && echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" |tee /etc/apt/sources.list.d/pgdg.list \ - && apt-get update && apt-get install -y postgresql-client-15 \ - && apt-get clean all - -COPY --from=buildgo /go/bin/chainlink /usr/local/bin/ - -# Install (but don't enable) LOOP Plugins -COPY --from=buildplugins /go/bin/chainlink-feeds /usr/local/bin/ -COPY --from=buildplugins /go/bin/chainlink-solana /usr/local/bin/ - -# Dependency of CosmWasm/wasmd -COPY --from=buildgo /go/pkg/mod/github.com/\!cosm\!wasm/wasmvm@v*/internal/api/libwasmvm.*.so /usr/lib/ -RUN chmod 755 /usr/lib/libwasmvm.*.so - -RUN if [ ${CHAINLINK_USER} != root ]; then \ - useradd --uid 14933 --create-home ${CHAINLINK_USER}; \ - fi -USER ${CHAINLINK_USER} -WORKDIR /home/${CHAINLINK_USER} -# explicit set the cache dir. needed so both root and non-root user has an explicit location -ENV XDG_CACHE_HOME /home/${CHAINLINK_USER}/.cache -RUN mkdir -p ${XDG_CACHE_HOME} - -EXPOSE 6688 -ENTRYPOINT ["chainlink"] - -HEALTHCHECK CMD curl -f http://localhost:6688/health || exit 1 - -CMD ["local", "node"] From f90cb4ec91cf492cf23e5e4b60423c6cbf44bea9 Mon Sep 17 00:00:00 2001 From: Anirudh Warrier <12178754+anirudhwarrier@users.noreply.github.com> Date: Wed, 6 Mar 2024 19:42:05 +0400 Subject: [PATCH 23/34] improve ondemand test workflow (#12237) * fix upgrade test * fix upgrade test * add input to disable chaos reorg test * skip build image if only upgrade test --- .../workflows/automation-ondemand-tests.yml | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/.github/workflows/automation-ondemand-tests.yml b/.github/workflows/automation-ondemand-tests.yml index b6638960aaf..830fb09186c 100644 --- a/.github/workflows/automation-ondemand-tests.yml +++ b/.github/workflows/automation-ondemand-tests.yml @@ -20,6 +20,16 @@ on: required: true default: public.ecr.aws/chainlink/chainlink type: string + enableChaos: + description: Check to enable chaos tests + type: boolean + default: false + required: true + enableReorg: + description: Check to enable reorg tests + type: boolean + default: false + required: true env: ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-tests:${{ github.sha }} @@ -104,6 +114,7 @@ jobs: with: ref: ${{ github.head_ref || github.ref_name }} - name: Build Test Image + if: inputs.enableChaos || inputs.enableReorg uses: ./.github/actions/build-test-image with: QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} @@ -130,6 +141,7 @@ jobs: suite: chaos nodes: 15 os: ubuntu-latest + enabled: ${{ inputs.enableChaos }} pyroscope_env: ci-automation-on-demand-chaos network: SIMULATED command: -run ^TestAutomationChaos$ ./chaos @@ -137,27 +149,34 @@ jobs: suite: reorg nodes: 5 os: ubuntu-latest + enabled: ${{ inputs.enableReorg }} pyroscope_env: ci-automation-on-demand-reorg network: SIMULATED_NONDEV command: -run ^TestAutomationReorg$ ./reorg - name: upgrade 2.0 + type: upgrade suite: smoke nodes: 1 os: ubuntu20.04-8cores-32GB + enabled: true pyroscope_env: ci-automation-on-demand-upgrade network: SIMULATED command: -run ^TestAutomationNodeUpgrade/registry_2_0 ./smoke - name: upgrade 2.1 + type: upgrade suite: smoke - nodes: 1 + nodes: 5 os: ubuntu20.04-8cores-32GB + enabled: true pyroscope_env: ci-automation-on-demand-upgrade network: SIMULATED command: -run ^TestAutomationNodeUpgrade/registry_2_1 ./smoke - name: upgrade 2.2 + type: upgrade suite: smoke - nodes: 1 + nodes: 5 os: ubuntu20.04-8cores-32GB + enabled: true pyroscope_env: ci-automation-on-demand-upgrade network: SIMULATED command: -run ^TestAutomationNodeUpgrade/registry_2_2 ./smoke @@ -185,7 +204,7 @@ jobs: echo "upgrade_version=${{ inputs.chainlinkVersion }}" >>$GITHUB_OUTPUT echo "upgrade_image=$READ_CL_IMAGE" >>$GITHUB_OUTPUT fi - if [[ "${{ matrix.tests.name }}" == "upgrade" ]]; then + if [[ "${{ matrix.tests.type }}" == "upgrade" ]]; then READ_CL_UPGR_IMAGE=$(jq -r '.inputs.chainlinkImageUpdate' $GITHUB_EVENT_PATH) echo ::add-mask::$READ_CL_UPGR_IMAGE echo "image=$READ_CL_UPGR_IMAGE" >>$GITHUB_OUTPUT @@ -240,6 +259,7 @@ jobs: echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - name: Run Tests uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@c67a09566412d153ff7640d99f96b43aa03abc04 # v2.3.6 + if: ${{ matrix.tests.enabled == true }} env: TEST_SUITE: ${{ matrix.tests.suite }} with: From 8ac40df9ab72d951f1a3ccb25c579575a5c60ffa Mon Sep 17 00:00:00 2001 From: krehermann Date: Wed, 6 Mar 2024 11:22:30 -0700 Subject: [PATCH 24/34] BCF-3043: test was not implementing the interface (#12317) * test was not implementing the interfaces. bug undercovered by recent chainlink-common refactoring * bump common * fix for BCF-3044 --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +-- core/services/relay/relay_test.go | 57 +++++++++++++++++++++++++++---- go.mod | 2 +- go.sum | 4 +-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +-- 9 files changed, 62 insertions(+), 19 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 39560095094..15a721dc380 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -20,7 +20,7 @@ require ( github.com/pelletier/go-toml/v2 v2.1.1 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240227191958-d13aad8b4d61 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240306173252-5cbf83ca3a69 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240229181116-bfb2432a7a66 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 424cd7b5939..4be489ecedc 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1174,8 +1174,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240227191958-d13aad8b4d61 h1:5aer8Pkw3XlXLjcPzWozy3RAbYQjVjpruxDeQENcVMw= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240227191958-d13aad8b4d61/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240306173252-5cbf83ca3a69 h1:LsusfMA80iEYoFOad9gcuLRQYdi0rP7PX/dsXq6Y7yw= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240306173252-5cbf83ca3a69/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= diff --git a/core/services/relay/relay_test.go b/core/services/relay/relay_test.go index 7b92bab37cd..dc12b769609 100644 --- a/core/services/relay/relay_test.go +++ b/core/services/relay/relay_test.go @@ -1,12 +1,13 @@ package relay import ( + "context" "testing" "github.com/stretchr/testify/assert" "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink-common/pkg/types" @@ -62,30 +63,72 @@ func TestNewID(t *testing.T) { } type staticMedianProvider struct { - types.MedianProvider } -func (s staticMedianProvider) OffchainConfigDigester() ocrtypes.OffchainConfigDigester { +var _ types.MedianProvider = staticMedianProvider{} + +// ContractConfigTracker implements types.MedianProvider. +func (s staticMedianProvider) ContractConfigTracker() ocr2types.ContractConfigTracker { return nil } -func (s staticMedianProvider) ContractConfigTracker() ocrtypes.ContractConfigTracker { +// ContractTransmitter implements types.MedianProvider. +func (s staticMedianProvider) ContractTransmitter() ocr2types.ContractTransmitter { return nil } -func (s staticMedianProvider) ContractTransmitter() ocrtypes.ContractTransmitter { +// MedianContract implements types.MedianProvider. +func (s staticMedianProvider) MedianContract() median.MedianContract { return nil } +// OffchainConfigDigester implements types.MedianProvider. +func (s staticMedianProvider) OffchainConfigDigester() ocr2types.OffchainConfigDigester { + return nil +} + +// OnchainConfigCodec implements types.MedianProvider. +func (s staticMedianProvider) OnchainConfigCodec() median.OnchainConfigCodec { + return nil +} + +// ReportCodec implements types.MedianProvider. func (s staticMedianProvider) ReportCodec() median.ReportCodec { return nil } -func (s staticMedianProvider) MedianContract() median.MedianContract { +// ChainReader implements types.MedianProvider. +func (s staticMedianProvider) ChainReader() types.ChainReader { return nil } -func (s staticMedianProvider) OnchainConfigCodec() median.OnchainConfigCodec { +// Close implements types.MedianProvider. +func (s staticMedianProvider) Close() error { + return nil +} + +// Codec implements types.MedianProvider. +func (s staticMedianProvider) Codec() types.Codec { + return nil +} + +// HealthReport implements types.MedianProvider. +func (s staticMedianProvider) HealthReport() map[string]error { + return nil +} + +// Name implements types.MedianProvider. +func (s staticMedianProvider) Name() string { + return "" +} + +// Ready implements types.MedianProvider. +func (s staticMedianProvider) Ready() error { + return nil +} + +// Start implements types.MedianProvider. +func (s staticMedianProvider) Start(context.Context) error { return nil } diff --git a/go.mod b/go.mod index 5cb8673e314..cf20ecf9ca7 100644 --- a/go.mod +++ b/go.mod @@ -69,7 +69,7 @@ require ( github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240227191958-d13aad8b4d61 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240306173252-5cbf83ca3a69 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240119021347-3c541a78cdb8 diff --git a/go.sum b/go.sum index 43eb172d22c..733b0e4b2d8 100644 --- a/go.sum +++ b/go.sum @@ -1169,8 +1169,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240227191958-d13aad8b4d61 h1:5aer8Pkw3XlXLjcPzWozy3RAbYQjVjpruxDeQENcVMw= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240227191958-d13aad8b4d61/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240306173252-5cbf83ca3a69 h1:LsusfMA80iEYoFOad9gcuLRQYdi0rP7PX/dsXq6Y7yw= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240306173252-5cbf83ca3a69/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 2f7ed16e3b2..30241cdc28d 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -23,7 +23,7 @@ require ( github.com/segmentio/ksuid v1.0.4 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240227191958-d13aad8b4d61 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240306173252-5cbf83ca3a69 github.com/smartcontractkit/chainlink-testing-framework v1.25.1 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index b5dda40ca97..7d1c024a761 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1516,8 +1516,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240227191958-d13aad8b4d61 h1:5aer8Pkw3XlXLjcPzWozy3RAbYQjVjpruxDeQENcVMw= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240227191958-d13aad8b4d61/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240306173252-5cbf83ca3a69 h1:LsusfMA80iEYoFOad9gcuLRQYdi0rP7PX/dsXq6Y7yw= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240306173252-5cbf83ca3a69/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index aed5be4806d..01ec14c9839 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -15,7 +15,7 @@ require ( github.com/rs/zerolog v1.30.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240227191958-d13aad8b4d61 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240306173252-5cbf83ca3a69 github.com/smartcontractkit/chainlink-testing-framework v1.25.1 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index bb3385b81f0..ac58e4c2b48 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1499,8 +1499,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429 h1:xkejUBZhcBpBrTSfxc91Iwzadrb6SXw8ks69bHIQ9Ww= github.com/smartcontractkit/chainlink-automation v1.0.2-0.20240118014648-1ab6a88c9429/go.mod h1:wJmVvDf4XSjsahWtfUq3wvIAYEAuhr7oxmxYnEL/LGQ= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240227191958-d13aad8b4d61 h1:5aer8Pkw3XlXLjcPzWozy3RAbYQjVjpruxDeQENcVMw= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240227191958-d13aad8b4d61/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240306173252-5cbf83ca3a69 h1:LsusfMA80iEYoFOad9gcuLRQYdi0rP7PX/dsXq6Y7yw= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240306173252-5cbf83ca3a69/go.mod h1:6aXWSEQawX2oZXcPPOdxnEGufAhj7PqPKolXf6ijRGA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8 h1:I326nw5GwHQHsLKHwtu5Sb9EBLylC8CfUd7BFAS0jtg= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240213120401-01a23955f9f8/go.mod h1:a65NtrK4xZb01mf0dDNghPkN2wXgcqFQ55ADthVBgMc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= From d3e067035dc196a86162b5ddb0efcbad296a4bca Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Wed, 6 Mar 2024 15:22:30 -0300 Subject: [PATCH 25/34] add missing funding log (#12316) --- integration-tests/actions/seth/actions.go | 72 +++++++++++++++++------ integration-tests/actions/seth/refund.go | 8 +-- 2 files changed, 57 insertions(+), 23 deletions(-) diff --git a/integration-tests/actions/seth/actions.go b/integration-tests/actions/seth/actions.go index 02cc2802517..ac536ac2f97 100644 --- a/integration-tests/actions/seth/actions.go +++ b/integration-tests/actions/seth/actions.go @@ -52,27 +52,44 @@ func FundChainlinkNodes( privateKey *ecdsa.PrivateKey, amount *big.Float, ) error { - refundErrors := []error{} + fundingErrors := []error{} for _, cl := range nodes { toAddress, err := cl.PrimaryEthAddress() if err != nil { return err } - err = SendFunds(logger, client, FundsToSendPayload{ + fromAddress, err := privateKeyToAddress(privateKey) + if err != nil { + return err + } + + receipt, err := SendFunds(logger, client, FundsToSendPayload{ ToAddress: common.HexToAddress(toAddress), Amount: conversions.EtherToWei(amount), PrivateKey: privateKey, }) if err != nil { - refundErrors = append(refundErrors, err) + fundingErrors = append(fundingErrors, err) + logger.Warn(). + Str("From", fromAddress.Hex()). + Str("To", toAddress). + Str("TxHash", receipt.TxHash.String()). + Msg("Failed to fund Chainlink node") } + + logger.Info(). + Str("From", fromAddress.Hex()). + Str("To", toAddress). + Str("TxHash", receipt.TxHash.String()). + Str("Amount", amount.String()). + Msg("Funded Chainlink node") } - if len(refundErrors) > 0 { + if len(fundingErrors) > 0 { var wrapped error - for _, e := range refundErrors { - wrapped = errors.Wrapf(e, ", ") + for _, e := range fundingErrors { + wrapped = errors.Wrapf(e, ",") } return fmt.Errorf("failed to fund chainlink nodes due to following errors: %w", wrapped) } @@ -90,19 +107,17 @@ type FundsToSendPayload struct { // TODO: move to CTF? // SendFunds sends native token amount (expressed in human-scale) from address controlled by private key // to given address. If no gas limit is set, then network's default will be used. -func SendFunds(logger zerolog.Logger, client *seth.Client, payload FundsToSendPayload) error { - ctx, cancel := context.WithTimeout(context.Background(), client.Cfg.Network.TxnTimeout.Duration()) - - publicKey := payload.PrivateKey.Public() - publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) - if !ok { - return errors.New("error casting public key to ECDSA") +func SendFunds(logger zerolog.Logger, client *seth.Client, payload FundsToSendPayload) (*types.Receipt, error) { + fromAddress, err := privateKeyToAddress(payload.PrivateKey) + if err != nil { + return nil, err } - fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA) + + ctx, cancel := context.WithTimeout(context.Background(), client.Cfg.Network.TxnTimeout.Duration()) nonce, err := client.Client.PendingNonceAt(ctx, fromAddress) defer cancel() if err != nil { - return err + return nil, err } gasLimit := uint64(client.Cfg.Network.GasLimit) @@ -119,17 +134,27 @@ func SendFunds(logger zerolog.Logger, client *seth.Client, payload FundsToSendPa } signedTx, err := types.SignNewTx(payload.PrivateKey, types.NewEIP155Signer(big.NewInt(client.ChainID)), rawTx) if err != nil { - return errors.Wrap(err, "failed to sign tx") + return nil, errors.Wrap(err, "failed to sign tx") } ctx, cancel = context.WithTimeout(ctx, client.Cfg.Network.TxnTimeout.Duration()) defer cancel() err = client.Client.SendTransaction(ctx, signedTx) if err != nil { - return errors.Wrap(err, "failed to send transaction") + return nil, errors.Wrap(err, "failed to send transaction") } - _, err = client.WaitMined(ctx, logger, client.Client, signedTx) - return err + + logger.Debug(). + Str("From", fromAddress.Hex()). + Str("To", payload.ToAddress.Hex()). + Str("TxHash", signedTx.Hash().String()). + Str("Amount", conversions.WeiToEther(payload.Amount).String()). + Uint64("Nonce", nonce). + Uint64("Gas Limit", gasLimit). + Int64("Gas Price", client.Cfg.Network.GasPrice). + Msg("Sent funds") + + return client.WaitMined(ctx, logger, client.Client, signedTx) } // DeployForwarderContracts first deploys Operator Factory and then uses it to deploy given number of @@ -526,3 +551,12 @@ func deployAnyOCRv1Contracts( return ocrInstances, nil } + +func privateKeyToAddress(privateKey *ecdsa.PrivateKey) (common.Address, error) { + publicKey := privateKey.Public() + publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) + if !ok { + return common.Address{}, errors.New("error casting public key to ECDSA") + } + return crypto.PubkeyToAddress(*publicKeyECDSA), nil +} diff --git a/integration-tests/actions/seth/refund.go b/integration-tests/actions/seth/refund.go index e2bfcc143c8..79fc60e6752 100644 --- a/integration-tests/actions/seth/refund.go +++ b/integration-tests/actions/seth/refund.go @@ -71,7 +71,7 @@ func (r *InsufficientFundTransferRetrier) Retry(ctx context.Context, logger zero payload.Amount = newAmount - retryErr := SendFunds(logger, client, payload) + _, retryErr := SendFunds(logger, client, payload) if retryErr == nil { logger.Info(). Str("retier", "InsufficientFundTransferRetrier"). @@ -135,7 +135,7 @@ func (r *GasTooLowTransferRetrier) Retry(ctx context.Context, logger zerolog.Log payload.GasLimit = &newGasLimit - retryErr := SendFunds(logger, client, payload) + _, retryErr := SendFunds(logger, client, payload) if retryErr == nil { logger.Info(). Str("retier", "GasTooLowTransferRetrier"). @@ -204,7 +204,7 @@ func (r *OvershotTransferRetrier) Retry(ctx context.Context, logger zerolog.Logg payload.Amount = newAmount - retryErr := SendFunds(logger, client, payload) + _, retryErr := SendFunds(logger, client, payload) if retryErr == nil { logger.Info(). Str("retier", "OvershotTransferRetrier"). @@ -275,7 +275,7 @@ func ReturnFunds(log zerolog.Logger, seth *seth.Client, chainlinkNodes []contrac payload := FundsToSendPayload{ToAddress: seth.Addresses[0], Amount: toSend, PrivateKey: decryptedKey.PrivateKey} - err = SendFunds(log, seth, payload) + _, err = SendFunds(log, seth, payload) if err != nil { handler := OvershotTransferRetrier{maxRetries: 3, nextRetrier: &InsufficientFundTransferRetrier{maxRetries: 3, nextRetrier: &GasTooLowTransferRetrier{maxGasLimit: seth.Cfg.Network.GasLimit * 3}}} return handler.Retry(context.Background(), log, seth, err, payload, 0) From a3870ad5dc440891ed68e9c87a5af3f778f08339 Mon Sep 17 00:00:00 2001 From: Jim W Date: Wed, 6 Mar 2024 16:31:21 -0500 Subject: [PATCH 26/34] add error for arbitrum (#12323) --- core/chains/evm/client/errors.go | 1 + core/chains/evm/client/errors_test.go | 1 + 2 files changed, 2 insertions(+) diff --git a/core/chains/evm/client/errors.go b/core/chains/evm/client/errors.go index cedeb37d2e4..8095c122508 100644 --- a/core/chains/evm/client/errors.go +++ b/core/chains/evm/client/errors.go @@ -140,6 +140,7 @@ var arbitrum = ClientErrors{ Fatal: arbitrumFatal, L2FeeTooLow: regexp.MustCompile(`(: |^)max fee per gas less than block base fee(:|$)`), L2Full: regexp.MustCompile(`(: |^)(queue full|sequencer pending tx pool full, please try again)(:|$)`), + ServiceUnavailable: regexp.MustCompile(`(: |^)502 Bad Gateway: [\s\S]*$`), } var celo = ClientErrors{ diff --git a/core/chains/evm/client/errors_test.go b/core/chains/evm/client/errors_test.go index 21b4981ff17..a59d3fbf719 100644 --- a/core/chains/evm/client/errors_test.go +++ b/core/chains/evm/client/errors_test.go @@ -213,6 +213,7 @@ func Test_Eth_Errors(t *testing.T) { t.Run("IsServiceUnavailable", func(t *testing.T) { tests := []errorCase{ {"call failed: 503 Service Unavailable: \r\n503 Service Temporarily Unavailable\r\n\r\n

503 Service Temporarily Unavailable

\r\n\r\n\r\n", true, "Nethermind"}, + {"call failed: 502 Bad Gateway: \r\n502 Bad Gateway\r\n\r\n

502 Bad Gateway

\r\n
", true, "Arbitrum"}, } for _, test := range tests { err = evmclient.NewSendErrorS(test.message) From 2869a7bac45023d79f4e3452c06d678363c0754b Mon Sep 17 00:00:00 2001 From: amit-momin <108959691+amit-momin@users.noreply.github.com> Date: Wed, 6 Mar 2024 17:13:58 -0600 Subject: [PATCH 27/34] Update LimitDefault and LimitMax type from uint32 to uint64 (#12307) * Updated LimitDefault and LimitMax type from uint32 to uint64 * Fixed linting * Fixed integration tests * Cleaned unnecessary uint64 conversions * Fixed mock * Fixed linting * Fixed config test * Fixed gas limit multiplier method * Fixed linting and tests * Fixed confirmer tests * Fixed VRF tests * Fixed linting * Undid unnecessary method signature changes * Fixed linting --- common/fee/utils.go | 8 +-- common/txmgr/broadcaster.go | 2 +- common/txmgr/confirmer.go | 6 +- common/txmgr/txmgr.go | 2 +- common/txmgr/types/client.go | 4 +- common/txmgr/types/config.go | 2 +- .../txmgr/types/mocks/tx_attempt_builder.go | 48 ++++++++-------- common/txmgr/types/tx.go | 6 +- common/txmgr/types/tx_attempt_builder.go | 10 ++-- core/capabilities/targets/write_target.go | 2 +- .../evm/config/chain_scoped_gas_estimator.go | 4 +- core/chains/evm/config/config.go | 4 +- core/chains/evm/config/config_test.go | 6 +- core/chains/evm/config/mocks/gas_estimator.go | 16 +++--- core/chains/evm/config/toml/config.go | 4 +- core/chains/evm/gas/arbitrum_estimator.go | 6 +- .../chains/evm/gas/arbitrum_estimator_test.go | 14 ++--- .../chains/evm/gas/block_history_estimator.go | 8 +-- core/chains/evm/gas/cmd/arbgas/main.go | 6 +- core/chains/evm/gas/fixed_price_estimator.go | 12 ++-- core/chains/evm/gas/gas_test.go | 4 +- core/chains/evm/gas/helpers_test.go | 4 +- core/chains/evm/gas/mocks/evm_estimator.go | 56 +++++++++---------- .../chains/evm/gas/mocks/evm_fee_estimator.go | 36 ++++++------ core/chains/evm/gas/models.go | 28 +++++----- core/chains/evm/gas/models_test.go | 2 +- .../evm/gas/suggested_price_estimator.go | 8 +-- .../evm/gas/suggested_price_estimator_test.go | 8 +-- core/chains/evm/txmgr/attempts.go | 30 +++++----- core/chains/evm/txmgr/attempts_test.go | 4 +- core/chains/evm/txmgr/broadcaster_test.go | 17 +++--- core/chains/evm/txmgr/client.go | 6 +- core/chains/evm/txmgr/config.go | 2 +- core/chains/evm/txmgr/confirmer_test.go | 18 +++--- core/chains/evm/txmgr/evm_tx_store.go | 4 +- core/chains/evm/txmgr/evm_tx_store_test.go | 4 +- core/chains/evm/txmgr/test_helpers.go | 4 +- core/chains/evm/txmgr/txmgr_test.go | 8 +-- core/cmd/shell_local.go | 2 +- core/internal/cltest/factories.go | 2 +- core/internal/features/features_test.go | 2 +- core/services/blockhashstore/batch_bhs.go | 2 +- core/services/blockhashstore/bhs.go | 2 +- core/services/chainlink/config_test.go | 4 +- core/services/fluxmonitorv2/config.go | 2 +- .../fluxmonitorv2/contract_submitter.go | 4 +- .../fluxmonitorv2/contract_submitter_test.go | 2 +- core/services/fluxmonitorv2/flux_monitor.go | 4 +- core/services/fluxmonitorv2/mocks/orm.go | 4 +- core/services/fluxmonitorv2/orm.go | 4 +- core/services/fluxmonitorv2/orm_test.go | 2 +- core/services/keeper/upkeep_executer_test.go | 6 +- .../v1/internal/testutils.go | 2 +- .../internal/ocr2vrf_integration_test.go | 2 +- core/services/ocrcommon/transmitter.go | 4 +- core/services/ocrcommon/transmitter_test.go | 8 +-- core/services/pipeline/common.go | 6 +- core/services/pipeline/common_test.go | 18 +++--- core/services/pipeline/task.estimategas.go | 2 +- core/services/pipeline/task.eth_call.go | 6 +- core/services/pipeline/task.eth_call_test.go | 2 +- core/services/pipeline/task.eth_tx.go | 2 +- core/services/pipeline/task.eth_tx_test.go | 18 +++--- core/services/relay/evm/evm.go | 4 +- core/services/relay/evm/functions.go | 2 +- core/services/vrf/mocks/fee_config.go | 8 +-- core/services/vrf/v2/bhs_feeder_test.go | 2 +- .../vrf/v2/integration_helpers_test.go | 14 ++--- .../vrf/v2/integration_v2_plus_test.go | 2 +- core/services/vrf/v2/integration_v2_test.go | 12 ++-- core/services/vrf/v2/listener_v2.go | 4 +- .../vrf/v2/listener_v2_log_processor.go | 8 +-- core/services/vrf/v2/listener_v2_types.go | 8 +-- .../services/vrf/v2/listener_v2_types_test.go | 4 +- core/services/vrf/v2/reverted_txns.go | 2 +- core/services/vrf/vrfcommon/types.go | 2 +- core/web/eth_keys_controller_test.go | 2 +- core/web/evm_transfer_controller.go | 2 +- core/web/presenters/eth_tx.go | 2 +- core/web/presenters/eth_tx_test.go | 2 +- integration-tests/types/config/node/core.go | 4 +- 81 files changed, 304 insertions(+), 305 deletions(-) diff --git a/common/fee/utils.go b/common/fee/utils.go index eeb2c966719..26323e11e26 100644 --- a/common/fee/utils.go +++ b/common/fee/utils.go @@ -8,13 +8,13 @@ import ( "github.com/shopspring/decimal" ) -func ApplyMultiplier(feeLimit uint32, multiplier float32) (uint32, error) { - result := decimal.NewFromBigInt(big.NewInt(0).SetUint64(uint64(feeLimit)), 0).Mul(decimal.NewFromFloat32(multiplier)).IntPart() +func ApplyMultiplier(feeLimit uint64, multiplier float32) (uint64, error) { + result := decimal.NewFromBigInt(big.NewInt(0).SetUint64(feeLimit), 0).Mul(decimal.NewFromFloat32(multiplier)) - if result > math.MaxUint32 { + if result.GreaterThan(decimal.NewFromBigInt(big.NewInt(0).SetUint64(math.MaxUint64), 0)) { return 0, fmt.Errorf("integer overflow when applying multiplier of %f to fee limit of %d", multiplier, feeLimit) } - return uint32(result), nil + return result.BigInt().Uint64(), nil } // Returns the input value increased by the given percentage. diff --git a/common/txmgr/broadcaster.go b/common/txmgr/broadcaster.go index 3e7520aff1a..f56e6b0368c 100644 --- a/common/txmgr/broadcaster.go +++ b/common/txmgr/broadcaster.go @@ -760,7 +760,7 @@ func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) tryA return eb.saveTryAgainAttempt(ctx, lgr, etx, attempt, replacementAttempt, initialBroadcastAt, fee, feeLimit) } -func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) saveTryAgainAttempt(ctx context.Context, lgr logger.Logger, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], replacementAttempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], initialBroadcastAt time.Time, newFee FEE, newFeeLimit uint32) (err error, retyrable bool) { +func (eb *Broadcaster[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) saveTryAgainAttempt(ctx context.Context, lgr logger.Logger, etx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], attempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], replacementAttempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], initialBroadcastAt time.Time, newFee FEE, newFeeLimit uint64) (err error, retyrable bool) { if err = eb.txStore.SaveReplacementInProgressAttempt(ctx, attempt, &replacementAttempt); err != nil { return fmt.Errorf("tryAgainWithNewFee failed: %w", err), true } diff --git a/common/txmgr/confirmer.go b/common/txmgr/confirmer.go index 073a6b90fa4..d76e70d9707 100644 --- a/common/txmgr/confirmer.go +++ b/common/txmgr/confirmer.go @@ -793,7 +793,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) bum logFields := ec.logFieldsPreviousAttempt(previousAttempt) var bumpedFee FEE - var bumpedFeeLimit uint32 + var bumpedFeeLimit uint64 bumpedAttempt, bumpedFee, bumpedFeeLimit, _, err = ec.NewBumpTxAttempt(ctx, etx, previousAttempt, previousAttempts, ec.lggr) // if no error, return attempt @@ -1039,7 +1039,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) mar // This operates completely orthogonal to the normal Confirmer and can result in untracked attempts! // Only for emergency usage. // This is in case of some unforeseen scenario where the node is refusing to release the lock. KISS. -func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) ForceRebroadcast(ctx context.Context, seqs []SEQ, fee FEE, address ADDR, overrideGasLimit uint32) error { +func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) ForceRebroadcast(ctx context.Context, seqs []SEQ, fee FEE, address ADDR, overrideGasLimit uint64) error { if len(seqs) == 0 { ec.lggr.Infof("ForceRebroadcast: No sequences provided. Skipping") return nil @@ -1082,7 +1082,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) For return nil } -func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) sendEmptyTransaction(ctx context.Context, fromAddress ADDR, seq SEQ, overrideGasLimit uint32, fee FEE) (string, error) { +func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) sendEmptyTransaction(ctx context.Context, fromAddress ADDR, seq SEQ, overrideGasLimit uint64, fee FEE) (string, error) { gasLimit := overrideGasLimit if gasLimit == 0 { gasLimit = ec.feeConfig.LimitDefault() diff --git a/common/txmgr/txmgr.go b/common/txmgr/txmgr.go index d0b33ad7e30..2bd9ed4d2d2 100644 --- a/common/txmgr/txmgr.go +++ b/common/txmgr/txmgr.go @@ -561,7 +561,7 @@ func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) SendNative ToAddress: to, EncodedPayload: []byte{}, Value: value, - FeeLimit: gasLimit, + FeeLimit: uint64(gasLimit), Strategy: NewSendEveryStrategy(), } etx, err = b.pruneQueueAndCreateTxn(ctx, txRequest, chainID) diff --git a/common/txmgr/types/client.go b/common/txmgr/types/client.go index 32527e5896e..759b15d6162 100644 --- a/common/txmgr/types/client.go +++ b/common/txmgr/types/client.go @@ -62,9 +62,9 @@ type TransactionClient[ ) (client.SendTxReturnCode, error) SendEmptyTransaction( ctx context.Context, - newTxAttempt func(ctx context.Context, seq SEQ, feeLimit uint32, fee FEE, fromAddress ADDR) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error), + newTxAttempt func(ctx context.Context, seq SEQ, feeLimit uint64, fee FEE, fromAddress ADDR) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error), seq SEQ, - gasLimit uint32, + gasLimit uint64, fee FEE, fromAddress ADDR, ) (txhash string, err error) diff --git a/common/txmgr/types/config.go b/common/txmgr/types/config.go index 502a7f42d5c..53e35cd4b6e 100644 --- a/common/txmgr/types/config.go +++ b/common/txmgr/types/config.go @@ -42,7 +42,7 @@ type BroadcasterListenerConfig interface { type ConfirmerFeeConfig interface { BumpTxDepth() uint32 - LimitDefault() uint32 + LimitDefault() uint64 // from gas.Config BumpThreshold() uint64 diff --git a/common/txmgr/types/mocks/tx_attempt_builder.go b/common/txmgr/types/mocks/tx_attempt_builder.go index 5b9b3e505ad..20ecbde0945 100644 --- a/common/txmgr/types/mocks/tx_attempt_builder.go +++ b/common/txmgr/types/mocks/tx_attempt_builder.go @@ -77,7 +77,7 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) } // NewBumpTxAttempt provides a mock function with given fields: ctx, tx, previousAttempt, priorAttempts, lggr -func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) NewBumpTxAttempt(ctx context.Context, tx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], previousAttempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], priorAttempts []txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint32, bool, error) { +func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) NewBumpTxAttempt(ctx context.Context, tx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], previousAttempt txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], priorAttempts []txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint64, bool, error) { ret := _m.Called(ctx, tx, previousAttempt, priorAttempts, lggr) if len(ret) == 0 { @@ -86,10 +86,10 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) var r0 txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE] var r1 FEE - var r2 uint32 + var r2 uint64 var r3 bool var r4 error - if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], []txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint32, bool, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], []txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint64, bool, error)); ok { return rf(ctx, tx, previousAttempt, priorAttempts, lggr) } if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], []txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger) txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok { @@ -104,10 +104,10 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) r1 = ret.Get(1).(FEE) } - if rf, ok := ret.Get(2).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], []txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger) uint32); ok { + if rf, ok := ret.Get(2).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], []txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger) uint64); ok { r2 = rf(ctx, tx, previousAttempt, priorAttempts, lggr) } else { - r2 = ret.Get(2).(uint32) + r2 = ret.Get(2).(uint64) } if rf, ok := ret.Get(3).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], []txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger) bool); ok { @@ -126,7 +126,7 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) } // NewCustomTxAttempt provides a mock function with given fields: ctx, tx, fee, gasLimit, txType, lggr -func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) NewCustomTxAttempt(ctx context.Context, tx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fee FEE, gasLimit uint32, txType int, lggr logger.Logger) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], bool, error) { +func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) NewCustomTxAttempt(ctx context.Context, tx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fee FEE, gasLimit uint64, txType int, lggr logger.Logger) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], bool, error) { ret := _m.Called(ctx, tx, fee, gasLimit, txType, lggr) if len(ret) == 0 { @@ -136,22 +136,22 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) var r0 txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE] var r1 bool var r2 error - if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint32, int, logger.Logger) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], bool, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint64, int, logger.Logger) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], bool, error)); ok { return rf(ctx, tx, fee, gasLimit, txType, lggr) } - if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint32, int, logger.Logger) txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok { + if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint64, int, logger.Logger) txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok { r0 = rf(ctx, tx, fee, gasLimit, txType, lggr) } else { r0 = ret.Get(0).(txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) } - if rf, ok := ret.Get(1).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint32, int, logger.Logger) bool); ok { + if rf, ok := ret.Get(1).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint64, int, logger.Logger) bool); ok { r1 = rf(ctx, tx, fee, gasLimit, txType, lggr) } else { r1 = ret.Get(1).(bool) } - if rf, ok := ret.Get(2).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint32, int, logger.Logger) error); ok { + if rf, ok := ret.Get(2).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint64, int, logger.Logger) error); ok { r2 = rf(ctx, tx, fee, gasLimit, txType, lggr) } else { r2 = ret.Error(2) @@ -161,7 +161,7 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) } // NewEmptyTxAttempt provides a mock function with given fields: ctx, seq, feeLimit, fee, fromAddress -func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) NewEmptyTxAttempt(ctx context.Context, seq SEQ, feeLimit uint32, fee FEE, fromAddress ADDR) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) { +func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) NewEmptyTxAttempt(ctx context.Context, seq SEQ, feeLimit uint64, fee FEE, fromAddress ADDR) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) { ret := _m.Called(ctx, seq, feeLimit, fee, fromAddress) if len(ret) == 0 { @@ -170,16 +170,16 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) var r0 txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE] var r1 error - if rf, ok := ret.Get(0).(func(context.Context, SEQ, uint32, FEE, ADDR) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, SEQ, uint64, FEE, ADDR) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error)); ok { return rf(ctx, seq, feeLimit, fee, fromAddress) } - if rf, ok := ret.Get(0).(func(context.Context, SEQ, uint32, FEE, ADDR) txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok { + if rf, ok := ret.Get(0).(func(context.Context, SEQ, uint64, FEE, ADDR) txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok { r0 = rf(ctx, seq, feeLimit, fee, fromAddress) } else { r0 = ret.Get(0).(txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) } - if rf, ok := ret.Get(1).(func(context.Context, SEQ, uint32, FEE, ADDR) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, SEQ, uint64, FEE, ADDR) error); ok { r1 = rf(ctx, seq, feeLimit, fee, fromAddress) } else { r1 = ret.Error(1) @@ -189,7 +189,7 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) } // NewTxAttempt provides a mock function with given fields: ctx, tx, lggr, opts -func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) NewTxAttempt(ctx context.Context, tx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger, opts ...feetypes.Opt) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint32, bool, error) { +func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) NewTxAttempt(ctx context.Context, tx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger, opts ...feetypes.Opt) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint64, bool, error) { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] @@ -205,10 +205,10 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) var r0 txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE] var r1 FEE - var r2 uint32 + var r2 uint64 var r3 bool var r4 error - if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, ...feetypes.Opt) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint32, bool, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, ...feetypes.Opt) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint64, bool, error)); ok { return rf(ctx, tx, lggr, opts...) } if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, ...feetypes.Opt) txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok { @@ -223,10 +223,10 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) r1 = ret.Get(1).(FEE) } - if rf, ok := ret.Get(2).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, ...feetypes.Opt) uint32); ok { + if rf, ok := ret.Get(2).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, ...feetypes.Opt) uint64); ok { r2 = rf(ctx, tx, lggr, opts...) } else { - r2 = ret.Get(2).(uint32) + r2 = ret.Get(2).(uint64) } if rf, ok := ret.Get(3).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, ...feetypes.Opt) bool); ok { @@ -245,7 +245,7 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) } // NewTxAttemptWithType provides a mock function with given fields: ctx, tx, lggr, txType, opts -func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) NewTxAttemptWithType(ctx context.Context, tx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger, txType int, opts ...feetypes.Opt) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint32, bool, error) { +func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) NewTxAttemptWithType(ctx context.Context, tx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger, txType int, opts ...feetypes.Opt) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint64, bool, error) { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] @@ -261,10 +261,10 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) var r0 txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE] var r1 FEE - var r2 uint32 + var r2 uint64 var r3 bool var r4 error - if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, int, ...feetypes.Opt) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint32, bool, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, int, ...feetypes.Opt) (txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], FEE, uint64, bool, error)); ok { return rf(ctx, tx, lggr, txType, opts...) } if rf, ok := ret.Get(0).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, int, ...feetypes.Opt) txmgrtypes.TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok { @@ -279,10 +279,10 @@ func (_m *TxAttemptBuilder[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]) r1 = ret.Get(1).(FEE) } - if rf, ok := ret.Get(2).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, int, ...feetypes.Opt) uint32); ok { + if rf, ok := ret.Get(2).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, int, ...feetypes.Opt) uint64); ok { r2 = rf(ctx, tx, lggr, txType, opts...) } else { - r2 = ret.Get(2).(uint32) + r2 = ret.Get(2).(uint64) } if rf, ok := ret.Get(3).(func(context.Context, txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], logger.Logger, int, ...feetypes.Opt) bool); ok { diff --git a/common/txmgr/types/tx.go b/common/txmgr/types/tx.go index 3b294adcd07..76fd7f4b3ab 100644 --- a/common/txmgr/types/tx.go +++ b/common/txmgr/types/tx.go @@ -79,7 +79,7 @@ type TxRequest[ADDR types.Hashable, TX_HASH types.Hashable] struct { ToAddress ADDR EncodedPayload []byte Value big.Int - FeeLimit uint32 + FeeLimit uint64 Meta *TxMeta[ADDR, TX_HASH] ForwarderAddress ADDR @@ -175,7 +175,7 @@ type TxAttempt[ Tx Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE] TxFee FEE // ChainSpecificFeeLimit on the TxAttempt is always the same as the on-chain encoded value for fee limit - ChainSpecificFeeLimit uint32 + ChainSpecificFeeLimit uint64 SignedRawTx []byte Hash TX_HASH CreatedAt time.Time @@ -205,7 +205,7 @@ type Tx[ Value big.Int // FeeLimit on the Tx is always the conceptual gas limit, which is not // necessarily the same as the on-chain encoded value (i.e. Optimism) - FeeLimit uint32 + FeeLimit uint64 Error null.String // BroadcastAt is updated every time an attempt for this tx is re-sent // In almost all cases it will be within a second or so of the actual send time. diff --git a/common/txmgr/types/tx_attempt_builder.go b/common/txmgr/types/tx_attempt_builder.go index 47c71abea35..b242f73e6fc 100644 --- a/common/txmgr/types/tx_attempt_builder.go +++ b/common/txmgr/types/tx_attempt_builder.go @@ -27,18 +27,18 @@ type TxAttemptBuilder[ types.HeadTrackable[HEAD, BLOCK_HASH] // NewTxAttempt builds a transaction using the configured transaction type and fee estimator (new estimation) - NewTxAttempt(ctx context.Context, tx Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger, opts ...feetypes.Opt) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fee FEE, feeLimit uint32, retryable bool, err error) + NewTxAttempt(ctx context.Context, tx Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger, opts ...feetypes.Opt) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fee FEE, feeLimit uint64, retryable bool, err error) // NewTxAttemptWithType builds a transaction using the configured fee estimator (new estimation) + passed in tx type - NewTxAttemptWithType(ctx context.Context, tx Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger, txType int, opts ...feetypes.Opt) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fee FEE, feeLimit uint32, retryable bool, err error) + NewTxAttemptWithType(ctx context.Context, tx Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger, txType int, opts ...feetypes.Opt) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fee FEE, feeLimit uint64, retryable bool, err error) // NewBumpTxAttempt builds a transaction using the configured fee estimator (bumping) + tx type from previous attempt // this should only be used after an initial attempt has been broadcast and the underlying gas estimator only needs to bump the fee - NewBumpTxAttempt(ctx context.Context, tx Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], previousAttempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], priorAttempts []TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], bumpedFee FEE, bumpedFeeLimit uint32, retryable bool, err error) + NewBumpTxAttempt(ctx context.Context, tx Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], previousAttempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], priorAttempts []TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], lggr logger.Logger) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], bumpedFee FEE, bumpedFeeLimit uint64, retryable bool, err error) // NewCustomTxAttempt builds a transaction using the passed in fee + tx type - NewCustomTxAttempt(ctx context.Context, tx Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fee FEE, gasLimit uint32, txType int, lggr logger.Logger) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], retryable bool, err error) + NewCustomTxAttempt(ctx context.Context, tx Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fee FEE, gasLimit uint64, txType int, lggr logger.Logger) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], retryable bool, err error) // NewEmptyTxAttempt is used in ForceRebroadcast to create a signed tx with zero value sent to the zero address - NewEmptyTxAttempt(ctx context.Context, seq SEQ, feeLimit uint32, fee FEE, fromAddress ADDR) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) + NewEmptyTxAttempt(ctx context.Context, seq SEQ, feeLimit uint64, fee FEE, fromAddress ADDR) (attempt TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) } diff --git a/core/capabilities/targets/write_target.go b/core/capabilities/targets/write_target.go index 531730cc089..a7452be7fc8 100644 --- a/core/capabilities/targets/write_target.go +++ b/core/capabilities/targets/write_target.go @@ -212,7 +212,7 @@ func (cap *EvmWrite) Execute(ctx context.Context, callback chan<- capabilities.C FromAddress: config.FromAddress().Address(), ToAddress: config.ForwarderAddress().Address(), EncodedPayload: calldata, - FeeLimit: uint32(defaultGasLimit), + FeeLimit: uint64(defaultGasLimit), Meta: txMeta, Strategy: strategy, Checker: checker, diff --git a/core/chains/evm/config/chain_scoped_gas_estimator.go b/core/chains/evm/config/chain_scoped_gas_estimator.go index 0c52cf0a468..9d7d10356f7 100644 --- a/core/chains/evm/config/chain_scoped_gas_estimator.go +++ b/core/chains/evm/config/chain_scoped_gas_estimator.go @@ -63,11 +63,11 @@ func (g *gasEstimatorConfig) FeeCapDefault() *assets.Wei { return g.c.FeeCapDefault } -func (g *gasEstimatorConfig) LimitDefault() uint32 { +func (g *gasEstimatorConfig) LimitDefault() uint64 { return *g.c.LimitDefault } -func (g *gasEstimatorConfig) LimitMax() uint32 { +func (g *gasEstimatorConfig) LimitMax() uint64 { return *g.c.LimitMax } diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go index c878fea46e9..c9c3273f086 100644 --- a/core/chains/evm/config/config.go +++ b/core/chains/evm/config/config.go @@ -97,8 +97,8 @@ type GasEstimator interface { BumpTxDepth() uint32 BumpMin() *assets.Wei FeeCapDefault() *assets.Wei - LimitDefault() uint32 - LimitMax() uint32 + LimitDefault() uint64 + LimitMax() uint64 LimitMultiplier() float32 LimitTransfer() uint32 PriceDefault() *assets.Wei diff --git a/core/chains/evm/config/config_test.go b/core/chains/evm/config/config_test.go index f62f540dafc..07fe392b69c 100644 --- a/core/chains/evm/config/config_test.go +++ b/core/chains/evm/config/config_test.go @@ -277,8 +277,8 @@ func TestChainScopedConfig_GasEstimator(t *testing.T) { assert.Equal(t, assets.GWei(20), ge.PriceDefault()) assert.Equal(t, assets.GWei(500), ge.PriceMax()) assert.Equal(t, assets.GWei(1), ge.PriceMin()) - assert.Equal(t, uint32(500000), ge.LimitDefault()) - assert.Equal(t, uint32(500000), ge.LimitMax()) + assert.Equal(t, uint64(500000), ge.LimitDefault()) + assert.Equal(t, uint64(500000), ge.LimitMax()) assert.Equal(t, float32(1), ge.LimitMultiplier()) assert.Equal(t, uint32(21000), ge.LimitTransfer()) assert.Equal(t, assets.GWei(5), ge.BumpMin()) @@ -317,7 +317,7 @@ func TestChainScopedConfig_Profiles(t *testing.T) { tests := []struct { name string chainID int64 - expectedGasLimitDefault uint32 + expectedGasLimitDefault uint64 expectedMinimumContractPayment string }{ {"default", 0, 500000, "0.00001"}, diff --git a/core/chains/evm/config/mocks/gas_estimator.go b/core/chains/evm/config/mocks/gas_estimator.go index 69a2c852757..b1b25c0ee41 100644 --- a/core/chains/evm/config/mocks/gas_estimator.go +++ b/core/chains/evm/config/mocks/gas_estimator.go @@ -149,18 +149,18 @@ func (_m *GasEstimator) FeeCapDefault() *assets.Wei { } // LimitDefault provides a mock function with given fields: -func (_m *GasEstimator) LimitDefault() uint32 { +func (_m *GasEstimator) LimitDefault() uint64 { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for LimitDefault") } - var r0 uint32 - if rf, ok := ret.Get(0).(func() uint32); ok { + var r0 uint64 + if rf, ok := ret.Get(0).(func() uint64); ok { r0 = rf() } else { - r0 = ret.Get(0).(uint32) + r0 = ret.Get(0).(uint64) } return r0 @@ -187,18 +187,18 @@ func (_m *GasEstimator) LimitJobType() config.LimitJobType { } // LimitMax provides a mock function with given fields: -func (_m *GasEstimator) LimitMax() uint32 { +func (_m *GasEstimator) LimitMax() uint64 { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for LimitMax") } - var r0 uint32 - if rf, ok := ret.Get(0).(func() uint32); ok { + var r0 uint64 + if rf, ok := ret.Get(0).(func() uint64); ok { r0 = rf() } else { - r0 = ret.Get(0).(uint32) + r0 = ret.Get(0).(uint64) } return r0 diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index 1ab4aa20d01..b84993b28a6 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -481,8 +481,8 @@ type GasEstimator struct { PriceMax *assets.Wei PriceMin *assets.Wei - LimitDefault *uint32 - LimitMax *uint32 + LimitDefault *uint64 + LimitMax *uint64 LimitMultiplier *decimal.Decimal LimitTransfer *uint32 LimitJobType GasLimitJobType `toml:",omitempty"` diff --git a/core/chains/evm/gas/arbitrum_estimator.go b/core/chains/evm/gas/arbitrum_estimator.go index 525d439e3e4..40366c5b998 100644 --- a/core/chains/evm/gas/arbitrum_estimator.go +++ b/core/chains/evm/gas/arbitrum_estimator.go @@ -23,7 +23,7 @@ import ( ) type ArbConfig interface { - LimitMax() uint32 + LimitMax() uint64 BumpPercent() uint16 BumpMin() *assets.Wei } @@ -105,7 +105,7 @@ func (a *arbitrumEstimator) HealthReport() map[string]error { // - Limit is computed from the dynamic values perL2Tx and perL1CalldataUnit, provided by the getPricesInArbGas() method // of the precompilie contract at ArbGasInfoAddress. perL2Tx is a constant amount of gas, and perL1CalldataUnit is // multiplied by the length of the tx calldata. The sum of these two values plus the original l2GasLimit is returned. -func (a *arbitrumEstimator) GetLegacyGas(ctx context.Context, calldata []byte, l2GasLimit uint32, maxGasPriceWei *assets.Wei, opts ...feetypes.Opt) (gasPrice *assets.Wei, chainSpecificGasLimit uint32, err error) { +func (a *arbitrumEstimator) GetLegacyGas(ctx context.Context, calldata []byte, l2GasLimit uint64, maxGasPriceWei *assets.Wei, opts ...feetypes.Opt) (gasPrice *assets.Wei, chainSpecificGasLimit uint64, err error) { gasPrice, _, err = a.EvmEstimator.GetLegacyGas(ctx, calldata, l2GasLimit, maxGasPriceWei, opts...) if err != nil { return @@ -134,7 +134,7 @@ func (a *arbitrumEstimator) GetLegacyGas(ctx context.Context, calldata []byte, l } } perL2Tx, perL1CalldataUnit := a.getPricesInArbGas() - chainSpecificGasLimit = l2GasLimit + perL2Tx + uint32(len(calldata))*perL1CalldataUnit + chainSpecificGasLimit = l2GasLimit + uint64(perL2Tx) + uint64(len(calldata))*uint64(perL1CalldataUnit) a.logger.Debugw("GetLegacyGas", "l2GasLimit", l2GasLimit, "calldataLen", len(calldata), "perL2Tx", perL2Tx, "perL1CalldataUnit", perL1CalldataUnit, "chainSpecificGasLimit", chainSpecificGasLimit) }) diff --git a/core/chains/evm/gas/arbitrum_estimator_test.go b/core/chains/evm/gas/arbitrum_estimator_test.go index e5a5af8d4f8..afac9e03276 100644 --- a/core/chains/evm/gas/arbitrum_estimator_test.go +++ b/core/chains/evm/gas/arbitrum_estimator_test.go @@ -23,12 +23,12 @@ import ( ) type arbConfig struct { - v uint32 + v uint64 bumpPercent uint16 bumpMin *assets.Wei } -func (a *arbConfig) LimitMax() uint32 { +func (a *arbConfig) LimitMax() uint64 { return a.v } @@ -44,9 +44,9 @@ func TestArbitrumEstimator(t *testing.T) { t.Parallel() maxGasPrice := assets.NewWeiI(100) - const maxGasLimit uint32 = 500_000 + const maxGasLimit uint64 = 500_000 calldata := []byte{0x00, 0x00, 0x01, 0x02, 0x03} - const gasLimit uint32 = 80000 + const gasLimit uint64 = 80000 const gasPriceBufferPercentage = 50 const bumpPercent = 10 var bumpMin = assets.NewWei(big.NewInt(1)) @@ -109,7 +109,7 @@ func TestArbitrumEstimator(t *testing.T) { require.Error(t, err) assert.EqualError(t, err, "estimated gas price: 42 wei is greater than the maximum gas price configured: 40 wei") assert.Nil(t, gasPrice) - assert.Equal(t, uint32(0), chainSpecificGasLimit) + assert.Equal(t, uint64(0), chainSpecificGasLimit) }) t.Run("gas price is lower than global max gas price", func(t *testing.T) { @@ -133,7 +133,7 @@ func TestArbitrumEstimator(t *testing.T) { gasPrice, chainSpecificGasLimit, err := o.GetLegacyGas(testutils.Context(t), calldata, gasLimit, assets.NewWeiI(110)) assert.EqualError(t, err, "estimated gas price: 120 wei is greater than the maximum gas price configured: 110 wei") assert.Nil(t, gasPrice) - assert.Equal(t, uint32(0), chainSpecificGasLimit) + assert.Equal(t, uint64(0), chainSpecificGasLimit) }) t.Run("calling BumpLegacyGas on unstarted arbitrum estimator returns error", func(t *testing.T) { @@ -195,7 +195,7 @@ func TestArbitrumEstimator(t *testing.T) { perL2Tx = 50_000 perL1Calldata = 10_000 ) - var expLimit = gasLimit + perL2Tx + perL1Calldata*uint32(len(calldata)) + var expLimit = gasLimit + perL2Tx + perL1Calldata*uint64(len(calldata)) var b bytes.Buffer b.Write(common.BigToHash(big.NewInt(perL2Tx)).Bytes()) diff --git a/core/chains/evm/gas/block_history_estimator.go b/core/chains/evm/gas/block_history_estimator.go index 27e20931af8..aae8d043ccd 100644 --- a/core/chains/evm/gas/block_history_estimator.go +++ b/core/chains/evm/gas/block_history_estimator.go @@ -248,7 +248,7 @@ func (b *BlockHistoryEstimator) HealthReport() map[string]error { return map[string]error{b.Name(): b.Healthy()} } -func (b *BlockHistoryEstimator) GetLegacyGas(_ context.Context, _ []byte, gasLimit uint32, maxGasPriceWei *assets.Wei, _ ...feetypes.Opt) (gasPrice *assets.Wei, chainSpecificGasLimit uint32, err error) { +func (b *BlockHistoryEstimator) GetLegacyGas(_ context.Context, _ []byte, gasLimit uint64, maxGasPriceWei *assets.Wei, _ ...feetypes.Opt) (gasPrice *assets.Wei, chainSpecificGasLimit uint64, err error) { ok := b.IfStarted(func() { gasPrice = b.getGasPrice() }) @@ -287,7 +287,7 @@ func (b *BlockHistoryEstimator) getTipCap() *assets.Wei { return b.tipCap } -func (b *BlockHistoryEstimator) BumpLegacyGas(_ context.Context, originalGasPrice *assets.Wei, gasLimit uint32, maxGasPriceWei *assets.Wei, attempts []EvmPriorAttempt) (bumpedGasPrice *assets.Wei, chainSpecificGasLimit uint32, err error) { +func (b *BlockHistoryEstimator) BumpLegacyGas(_ context.Context, originalGasPrice *assets.Wei, gasLimit uint64, maxGasPriceWei *assets.Wei, attempts []EvmPriorAttempt) (bumpedGasPrice *assets.Wei, chainSpecificGasLimit uint64, err error) { if b.bhConfig.CheckInclusionBlocks() > 0 { if err = b.checkConnectivity(attempts); err != nil { if pkgerrors.Is(err, commonfee.ErrConnectivity) { @@ -388,7 +388,7 @@ func (b *BlockHistoryEstimator) checkConnectivity(attempts []EvmPriorAttempt) er return nil } -func (b *BlockHistoryEstimator) GetDynamicFee(_ context.Context, gasLimit uint32, maxGasPriceWei *assets.Wei) (fee DynamicFee, chainSpecificGasLimit uint32, err error) { +func (b *BlockHistoryEstimator) GetDynamicFee(_ context.Context, gasLimit uint64, maxGasPriceWei *assets.Wei) (fee DynamicFee, chainSpecificGasLimit uint64, err error) { if !b.eConfig.EIP1559DynamicFees() { return fee, 0, pkgerrors.New("Can't get dynamic fee, EIP1559 is disabled") } @@ -461,7 +461,7 @@ func calcFeeCap(latestAvailableBaseFeePerGas *assets.Wei, bufferBlocks int, tipC return feeCap } -func (b *BlockHistoryEstimator) BumpDynamicFee(_ context.Context, originalFee DynamicFee, originalGasLimit uint32, maxGasPriceWei *assets.Wei, attempts []EvmPriorAttempt) (bumped DynamicFee, chainSpecificGasLimit uint32, err error) { +func (b *BlockHistoryEstimator) BumpDynamicFee(_ context.Context, originalFee DynamicFee, originalGasLimit uint64, maxGasPriceWei *assets.Wei, attempts []EvmPriorAttempt) (bumped DynamicFee, chainSpecificGasLimit uint64, err error) { if b.bhConfig.CheckInclusionBlocks() > 0 { if err = b.checkConnectivity(attempts); err != nil { if pkgerrors.Is(err, commonfee.ErrConnectivity) { diff --git a/core/chains/evm/gas/cmd/arbgas/main.go b/core/chains/evm/gas/cmd/arbgas/main.go index c457b091c96..dc107a50b52 100644 --- a/core/chains/evm/gas/cmd/arbgas/main.go +++ b/core/chains/evm/gas/cmd/arbgas/main.go @@ -34,7 +34,7 @@ func main() { }) } -func printGetLegacyGas(ctx context.Context, e gas.EvmEstimator, calldata []byte, l2GasLimit uint32, maxGasPrice *assets.Wei, opts ...feetypes.Opt) { +func printGetLegacyGas(ctx context.Context, e gas.EvmEstimator, calldata []byte, l2GasLimit uint64, maxGasPrice *assets.Wei, opts ...feetypes.Opt) { price, limit, err := e.GetLegacyGas(ctx, calldata, l2GasLimit, maxGasPrice, opts...) if err != nil { log.Println("failed to get legacy gas:", err) @@ -67,12 +67,12 @@ func withEstimator(ctx context.Context, lggr logger.SugaredLogger, url string, f var _ gas.ArbConfig = &config{} type config struct { - max uint32 + max uint64 bumpPercent uint16 bumpMin *assets.Wei } -func (c *config) LimitMax() uint32 { +func (c *config) LimitMax() uint64 { return c.max } diff --git a/core/chains/evm/gas/fixed_price_estimator.go b/core/chains/evm/gas/fixed_price_estimator.go index a69be3b0d05..53b7e93a871 100644 --- a/core/chains/evm/gas/fixed_price_estimator.go +++ b/core/chains/evm/gas/fixed_price_estimator.go @@ -58,7 +58,7 @@ func (f *fixedPriceEstimator) Start(context.Context) error { return nil } -func (f *fixedPriceEstimator) GetLegacyGas(_ context.Context, _ []byte, gasLimit uint32, maxGasPriceWei *assets.Wei, _ ...feetypes.Opt) (*assets.Wei, uint32, error) { +func (f *fixedPriceEstimator) GetLegacyGas(_ context.Context, _ []byte, gasLimit uint64, maxGasPriceWei *assets.Wei, _ ...feetypes.Opt) (*assets.Wei, uint64, error) { gasPrice := commonfee.CalculateFee(f.config.PriceDefault().ToInt(), maxGasPriceWei.ToInt(), f.config.PriceMax().ToInt()) chainSpecificGasLimit, err := commonfee.ApplyMultiplier(gasLimit, f.config.LimitMultiplier()) if err != nil { @@ -70,10 +70,10 @@ func (f *fixedPriceEstimator) GetLegacyGas(_ context.Context, _ []byte, gasLimit func (f *fixedPriceEstimator) BumpLegacyGas( _ context.Context, originalGasPrice *assets.Wei, - originalGasLimit uint32, + originalGasLimit uint64, maxGasPriceWei *assets.Wei, _ []EvmPriorAttempt, -) (*assets.Wei, uint32, error) { +) (*assets.Wei, uint64, error) { gasPrice, err := commonfee.CalculateBumpedFee( f.lggr, f.config.PriceDefault().ToInt(), @@ -95,7 +95,7 @@ func (f *fixedPriceEstimator) BumpLegacyGas( return assets.NewWei(gasPrice), chainSpecificGasLimit, err } -func (f *fixedPriceEstimator) GetDynamicFee(_ context.Context, originalGasLimit uint32, maxGasPriceWei *assets.Wei) (d DynamicFee, chainSpecificGasLimit uint32, err error) { +func (f *fixedPriceEstimator) GetDynamicFee(_ context.Context, originalGasLimit uint64, maxGasPriceWei *assets.Wei) (d DynamicFee, chainSpecificGasLimit uint64, err error) { gasTipCap := f.config.TipCapDefault() if gasTipCap == nil { @@ -124,10 +124,10 @@ func (f *fixedPriceEstimator) GetDynamicFee(_ context.Context, originalGasLimit func (f *fixedPriceEstimator) BumpDynamicFee( _ context.Context, originalFee DynamicFee, - originalGasLimit uint32, + originalGasLimit uint64, maxGasPriceWei *assets.Wei, _ []EvmPriorAttempt, -) (bumped DynamicFee, chainSpecificGasLimit uint32, err error) { +) (bumped DynamicFee, chainSpecificGasLimit uint64, err error) { return BumpDynamicFeeOnly( f.config, diff --git a/core/chains/evm/gas/gas_test.go b/core/chains/evm/gas/gas_test.go index 355d39b6ce8..43a1506bc24 100644 --- a/core/chains/evm/gas/gas_test.go +++ b/core/chains/evm/gas/gas_test.go @@ -24,7 +24,7 @@ func Test_BumpLegacyGasPriceOnly(t *testing.T) { bumpMin *assets.Wei priceMax *assets.Wei expectedGasPrice *assets.Wei - originalLimit uint32 + originalLimit uint64 limitMultiplierPercent float32 expectedLimit uint64 }{ @@ -156,7 +156,7 @@ func Test_BumpDynamicFeeOnly(t *testing.T) { bumpMin *assets.Wei priceMax *assets.Wei expectedFee gas.DynamicFee - originalLimit uint32 + originalLimit uint64 limitMultiplierPercent float32 expectedLimit uint64 }{ diff --git a/core/chains/evm/gas/helpers_test.go b/core/chains/evm/gas/helpers_test.go index 9a5076be6d6..908674bbeeb 100644 --- a/core/chains/evm/gas/helpers_test.go +++ b/core/chains/evm/gas/helpers_test.go @@ -143,7 +143,7 @@ type MockGasEstimatorConfig struct { PriceMinF *assets.Wei PriceDefaultF *assets.Wei FeeCapDefaultF *assets.Wei - LimitMaxF uint32 + LimitMaxF uint64 ModeF string } @@ -191,7 +191,7 @@ func (m *MockGasEstimatorConfig) FeeCapDefault() *assets.Wei { return m.FeeCapDefaultF } -func (m *MockGasEstimatorConfig) LimitMax() uint32 { +func (m *MockGasEstimatorConfig) LimitMax() uint64 { return m.LimitMaxF } diff --git a/core/chains/evm/gas/mocks/evm_estimator.go b/core/chains/evm/gas/mocks/evm_estimator.go index 29705b2a5d9..f9ea34b830d 100644 --- a/core/chains/evm/gas/mocks/evm_estimator.go +++ b/core/chains/evm/gas/mocks/evm_estimator.go @@ -22,7 +22,7 @@ type EvmEstimator struct { } // BumpDynamicFee provides a mock function with given fields: ctx, original, gasLimit, maxGasPriceWei, attempts -func (_m *EvmEstimator) BumpDynamicFee(ctx context.Context, original gas.DynamicFee, gasLimit uint32, maxGasPriceWei *assets.Wei, attempts []gas.EvmPriorAttempt) (gas.DynamicFee, uint32, error) { +func (_m *EvmEstimator) BumpDynamicFee(ctx context.Context, original gas.DynamicFee, gasLimit uint64, maxGasPriceWei *assets.Wei, attempts []gas.EvmPriorAttempt) (gas.DynamicFee, uint64, error) { ret := _m.Called(ctx, original, gasLimit, maxGasPriceWei, attempts) if len(ret) == 0 { @@ -30,24 +30,24 @@ func (_m *EvmEstimator) BumpDynamicFee(ctx context.Context, original gas.Dynamic } var r0 gas.DynamicFee - var r1 uint32 + var r1 uint64 var r2 error - if rf, ok := ret.Get(0).(func(context.Context, gas.DynamicFee, uint32, *assets.Wei, []gas.EvmPriorAttempt) (gas.DynamicFee, uint32, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, gas.DynamicFee, uint64, *assets.Wei, []gas.EvmPriorAttempt) (gas.DynamicFee, uint64, error)); ok { return rf(ctx, original, gasLimit, maxGasPriceWei, attempts) } - if rf, ok := ret.Get(0).(func(context.Context, gas.DynamicFee, uint32, *assets.Wei, []gas.EvmPriorAttempt) gas.DynamicFee); ok { + if rf, ok := ret.Get(0).(func(context.Context, gas.DynamicFee, uint64, *assets.Wei, []gas.EvmPriorAttempt) gas.DynamicFee); ok { r0 = rf(ctx, original, gasLimit, maxGasPriceWei, attempts) } else { r0 = ret.Get(0).(gas.DynamicFee) } - if rf, ok := ret.Get(1).(func(context.Context, gas.DynamicFee, uint32, *assets.Wei, []gas.EvmPriorAttempt) uint32); ok { + if rf, ok := ret.Get(1).(func(context.Context, gas.DynamicFee, uint64, *assets.Wei, []gas.EvmPriorAttempt) uint64); ok { r1 = rf(ctx, original, gasLimit, maxGasPriceWei, attempts) } else { - r1 = ret.Get(1).(uint32) + r1 = ret.Get(1).(uint64) } - if rf, ok := ret.Get(2).(func(context.Context, gas.DynamicFee, uint32, *assets.Wei, []gas.EvmPriorAttempt) error); ok { + if rf, ok := ret.Get(2).(func(context.Context, gas.DynamicFee, uint64, *assets.Wei, []gas.EvmPriorAttempt) error); ok { r2 = rf(ctx, original, gasLimit, maxGasPriceWei, attempts) } else { r2 = ret.Error(2) @@ -57,7 +57,7 @@ func (_m *EvmEstimator) BumpDynamicFee(ctx context.Context, original gas.Dynamic } // BumpLegacyGas provides a mock function with given fields: ctx, originalGasPrice, gasLimit, maxGasPriceWei, attempts -func (_m *EvmEstimator) BumpLegacyGas(ctx context.Context, originalGasPrice *assets.Wei, gasLimit uint32, maxGasPriceWei *assets.Wei, attempts []gas.EvmPriorAttempt) (*assets.Wei, uint32, error) { +func (_m *EvmEstimator) BumpLegacyGas(ctx context.Context, originalGasPrice *assets.Wei, gasLimit uint64, maxGasPriceWei *assets.Wei, attempts []gas.EvmPriorAttempt) (*assets.Wei, uint64, error) { ret := _m.Called(ctx, originalGasPrice, gasLimit, maxGasPriceWei, attempts) if len(ret) == 0 { @@ -65,12 +65,12 @@ func (_m *EvmEstimator) BumpLegacyGas(ctx context.Context, originalGasPrice *ass } var r0 *assets.Wei - var r1 uint32 + var r1 uint64 var r2 error - if rf, ok := ret.Get(0).(func(context.Context, *assets.Wei, uint32, *assets.Wei, []gas.EvmPriorAttempt) (*assets.Wei, uint32, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, *assets.Wei, uint64, *assets.Wei, []gas.EvmPriorAttempt) (*assets.Wei, uint64, error)); ok { return rf(ctx, originalGasPrice, gasLimit, maxGasPriceWei, attempts) } - if rf, ok := ret.Get(0).(func(context.Context, *assets.Wei, uint32, *assets.Wei, []gas.EvmPriorAttempt) *assets.Wei); ok { + if rf, ok := ret.Get(0).(func(context.Context, *assets.Wei, uint64, *assets.Wei, []gas.EvmPriorAttempt) *assets.Wei); ok { r0 = rf(ctx, originalGasPrice, gasLimit, maxGasPriceWei, attempts) } else { if ret.Get(0) != nil { @@ -78,13 +78,13 @@ func (_m *EvmEstimator) BumpLegacyGas(ctx context.Context, originalGasPrice *ass } } - if rf, ok := ret.Get(1).(func(context.Context, *assets.Wei, uint32, *assets.Wei, []gas.EvmPriorAttempt) uint32); ok { + if rf, ok := ret.Get(1).(func(context.Context, *assets.Wei, uint64, *assets.Wei, []gas.EvmPriorAttempt) uint64); ok { r1 = rf(ctx, originalGasPrice, gasLimit, maxGasPriceWei, attempts) } else { - r1 = ret.Get(1).(uint32) + r1 = ret.Get(1).(uint64) } - if rf, ok := ret.Get(2).(func(context.Context, *assets.Wei, uint32, *assets.Wei, []gas.EvmPriorAttempt) error); ok { + if rf, ok := ret.Get(2).(func(context.Context, *assets.Wei, uint64, *assets.Wei, []gas.EvmPriorAttempt) error); ok { r2 = rf(ctx, originalGasPrice, gasLimit, maxGasPriceWei, attempts) } else { r2 = ret.Error(2) @@ -112,7 +112,7 @@ func (_m *EvmEstimator) Close() error { } // GetDynamicFee provides a mock function with given fields: ctx, gasLimit, maxGasPriceWei -func (_m *EvmEstimator) GetDynamicFee(ctx context.Context, gasLimit uint32, maxGasPriceWei *assets.Wei) (gas.DynamicFee, uint32, error) { +func (_m *EvmEstimator) GetDynamicFee(ctx context.Context, gasLimit uint64, maxGasPriceWei *assets.Wei) (gas.DynamicFee, uint64, error) { ret := _m.Called(ctx, gasLimit, maxGasPriceWei) if len(ret) == 0 { @@ -120,24 +120,24 @@ func (_m *EvmEstimator) GetDynamicFee(ctx context.Context, gasLimit uint32, maxG } var r0 gas.DynamicFee - var r1 uint32 + var r1 uint64 var r2 error - if rf, ok := ret.Get(0).(func(context.Context, uint32, *assets.Wei) (gas.DynamicFee, uint32, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, uint64, *assets.Wei) (gas.DynamicFee, uint64, error)); ok { return rf(ctx, gasLimit, maxGasPriceWei) } - if rf, ok := ret.Get(0).(func(context.Context, uint32, *assets.Wei) gas.DynamicFee); ok { + if rf, ok := ret.Get(0).(func(context.Context, uint64, *assets.Wei) gas.DynamicFee); ok { r0 = rf(ctx, gasLimit, maxGasPriceWei) } else { r0 = ret.Get(0).(gas.DynamicFee) } - if rf, ok := ret.Get(1).(func(context.Context, uint32, *assets.Wei) uint32); ok { + if rf, ok := ret.Get(1).(func(context.Context, uint64, *assets.Wei) uint64); ok { r1 = rf(ctx, gasLimit, maxGasPriceWei) } else { - r1 = ret.Get(1).(uint32) + r1 = ret.Get(1).(uint64) } - if rf, ok := ret.Get(2).(func(context.Context, uint32, *assets.Wei) error); ok { + if rf, ok := ret.Get(2).(func(context.Context, uint64, *assets.Wei) error); ok { r2 = rf(ctx, gasLimit, maxGasPriceWei) } else { r2 = ret.Error(2) @@ -147,7 +147,7 @@ func (_m *EvmEstimator) GetDynamicFee(ctx context.Context, gasLimit uint32, maxG } // GetLegacyGas provides a mock function with given fields: ctx, calldata, gasLimit, maxGasPriceWei, opts -func (_m *EvmEstimator) GetLegacyGas(ctx context.Context, calldata []byte, gasLimit uint32, maxGasPriceWei *assets.Wei, opts ...types.Opt) (*assets.Wei, uint32, error) { +func (_m *EvmEstimator) GetLegacyGas(ctx context.Context, calldata []byte, gasLimit uint64, maxGasPriceWei *assets.Wei, opts ...types.Opt) (*assets.Wei, uint64, error) { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] @@ -162,12 +162,12 @@ func (_m *EvmEstimator) GetLegacyGas(ctx context.Context, calldata []byte, gasLi } var r0 *assets.Wei - var r1 uint32 + var r1 uint64 var r2 error - if rf, ok := ret.Get(0).(func(context.Context, []byte, uint32, *assets.Wei, ...types.Opt) (*assets.Wei, uint32, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) (*assets.Wei, uint64, error)); ok { return rf(ctx, calldata, gasLimit, maxGasPriceWei, opts...) } - if rf, ok := ret.Get(0).(func(context.Context, []byte, uint32, *assets.Wei, ...types.Opt) *assets.Wei); ok { + if rf, ok := ret.Get(0).(func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) *assets.Wei); ok { r0 = rf(ctx, calldata, gasLimit, maxGasPriceWei, opts...) } else { if ret.Get(0) != nil { @@ -175,13 +175,13 @@ func (_m *EvmEstimator) GetLegacyGas(ctx context.Context, calldata []byte, gasLi } } - if rf, ok := ret.Get(1).(func(context.Context, []byte, uint32, *assets.Wei, ...types.Opt) uint32); ok { + if rf, ok := ret.Get(1).(func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) uint64); ok { r1 = rf(ctx, calldata, gasLimit, maxGasPriceWei, opts...) } else { - r1 = ret.Get(1).(uint32) + r1 = ret.Get(1).(uint64) } - if rf, ok := ret.Get(2).(func(context.Context, []byte, uint32, *assets.Wei, ...types.Opt) error); ok { + if rf, ok := ret.Get(2).(func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) error); ok { r2 = rf(ctx, calldata, gasLimit, maxGasPriceWei, opts...) } else { r2 = ret.Error(2) diff --git a/core/chains/evm/gas/mocks/evm_fee_estimator.go b/core/chains/evm/gas/mocks/evm_fee_estimator.go index 66acbdbf7ff..7ebde8bc0fd 100644 --- a/core/chains/evm/gas/mocks/evm_fee_estimator.go +++ b/core/chains/evm/gas/mocks/evm_fee_estimator.go @@ -26,7 +26,7 @@ type EvmFeeEstimator struct { } // BumpFee provides a mock function with given fields: ctx, originalFee, feeLimit, maxFeePrice, attempts -func (_m *EvmFeeEstimator) BumpFee(ctx context.Context, originalFee gas.EvmFee, feeLimit uint32, maxFeePrice *assets.Wei, attempts []gas.EvmPriorAttempt) (gas.EvmFee, uint32, error) { +func (_m *EvmFeeEstimator) BumpFee(ctx context.Context, originalFee gas.EvmFee, feeLimit uint64, maxFeePrice *assets.Wei, attempts []gas.EvmPriorAttempt) (gas.EvmFee, uint64, error) { ret := _m.Called(ctx, originalFee, feeLimit, maxFeePrice, attempts) if len(ret) == 0 { @@ -34,24 +34,24 @@ func (_m *EvmFeeEstimator) BumpFee(ctx context.Context, originalFee gas.EvmFee, } var r0 gas.EvmFee - var r1 uint32 + var r1 uint64 var r2 error - if rf, ok := ret.Get(0).(func(context.Context, gas.EvmFee, uint32, *assets.Wei, []gas.EvmPriorAttempt) (gas.EvmFee, uint32, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, gas.EvmFee, uint64, *assets.Wei, []gas.EvmPriorAttempt) (gas.EvmFee, uint64, error)); ok { return rf(ctx, originalFee, feeLimit, maxFeePrice, attempts) } - if rf, ok := ret.Get(0).(func(context.Context, gas.EvmFee, uint32, *assets.Wei, []gas.EvmPriorAttempt) gas.EvmFee); ok { + if rf, ok := ret.Get(0).(func(context.Context, gas.EvmFee, uint64, *assets.Wei, []gas.EvmPriorAttempt) gas.EvmFee); ok { r0 = rf(ctx, originalFee, feeLimit, maxFeePrice, attempts) } else { r0 = ret.Get(0).(gas.EvmFee) } - if rf, ok := ret.Get(1).(func(context.Context, gas.EvmFee, uint32, *assets.Wei, []gas.EvmPriorAttempt) uint32); ok { + if rf, ok := ret.Get(1).(func(context.Context, gas.EvmFee, uint64, *assets.Wei, []gas.EvmPriorAttempt) uint64); ok { r1 = rf(ctx, originalFee, feeLimit, maxFeePrice, attempts) } else { - r1 = ret.Get(1).(uint32) + r1 = ret.Get(1).(uint64) } - if rf, ok := ret.Get(2).(func(context.Context, gas.EvmFee, uint32, *assets.Wei, []gas.EvmPriorAttempt) error); ok { + if rf, ok := ret.Get(2).(func(context.Context, gas.EvmFee, uint64, *assets.Wei, []gas.EvmPriorAttempt) error); ok { r2 = rf(ctx, originalFee, feeLimit, maxFeePrice, attempts) } else { r2 = ret.Error(2) @@ -79,7 +79,7 @@ func (_m *EvmFeeEstimator) Close() error { } // GetFee provides a mock function with given fields: ctx, calldata, feeLimit, maxFeePrice, opts -func (_m *EvmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit uint32, maxFeePrice *assets.Wei, opts ...types.Opt) (gas.EvmFee, uint32, error) { +func (_m *EvmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...types.Opt) (gas.EvmFee, uint64, error) { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] @@ -94,24 +94,24 @@ func (_m *EvmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit } var r0 gas.EvmFee - var r1 uint32 + var r1 uint64 var r2 error - if rf, ok := ret.Get(0).(func(context.Context, []byte, uint32, *assets.Wei, ...types.Opt) (gas.EvmFee, uint32, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) (gas.EvmFee, uint64, error)); ok { return rf(ctx, calldata, feeLimit, maxFeePrice, opts...) } - if rf, ok := ret.Get(0).(func(context.Context, []byte, uint32, *assets.Wei, ...types.Opt) gas.EvmFee); ok { + if rf, ok := ret.Get(0).(func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) gas.EvmFee); ok { r0 = rf(ctx, calldata, feeLimit, maxFeePrice, opts...) } else { r0 = ret.Get(0).(gas.EvmFee) } - if rf, ok := ret.Get(1).(func(context.Context, []byte, uint32, *assets.Wei, ...types.Opt) uint32); ok { + if rf, ok := ret.Get(1).(func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) uint64); ok { r1 = rf(ctx, calldata, feeLimit, maxFeePrice, opts...) } else { - r1 = ret.Get(1).(uint32) + r1 = ret.Get(1).(uint64) } - if rf, ok := ret.Get(2).(func(context.Context, []byte, uint32, *assets.Wei, ...types.Opt) error); ok { + if rf, ok := ret.Get(2).(func(context.Context, []byte, uint64, *assets.Wei, ...types.Opt) error); ok { r2 = rf(ctx, calldata, feeLimit, maxFeePrice, opts...) } else { r2 = ret.Error(2) @@ -121,7 +121,7 @@ func (_m *EvmFeeEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit } // GetMaxCost provides a mock function with given fields: ctx, amount, calldata, feeLimit, maxFeePrice, opts -func (_m *EvmFeeEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint32, maxFeePrice *assets.Wei, opts ...types.Opt) (*big.Int, error) { +func (_m *EvmFeeEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...types.Opt) (*big.Int, error) { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] @@ -137,10 +137,10 @@ func (_m *EvmFeeEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, ca var r0 *big.Int var r1 error - if rf, ok := ret.Get(0).(func(context.Context, assets.Eth, []byte, uint32, *assets.Wei, ...types.Opt) (*big.Int, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, ...types.Opt) (*big.Int, error)); ok { return rf(ctx, amount, calldata, feeLimit, maxFeePrice, opts...) } - if rf, ok := ret.Get(0).(func(context.Context, assets.Eth, []byte, uint32, *assets.Wei, ...types.Opt) *big.Int); ok { + if rf, ok := ret.Get(0).(func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, ...types.Opt) *big.Int); ok { r0 = rf(ctx, amount, calldata, feeLimit, maxFeePrice, opts...) } else { if ret.Get(0) != nil { @@ -148,7 +148,7 @@ func (_m *EvmFeeEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, ca } } - if rf, ok := ret.Get(1).(func(context.Context, assets.Eth, []byte, uint32, *assets.Wei, ...types.Opt) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, assets.Eth, []byte, uint64, *assets.Wei, ...types.Opt) error); ok { r1 = rf(ctx, amount, calldata, feeLimit, maxFeePrice, opts...) } else { r1 = ret.Error(1) diff --git a/core/chains/evm/gas/models.go b/core/chains/evm/gas/models.go index 44e85af37ff..ae041615f53 100644 --- a/core/chains/evm/gas/models.go +++ b/core/chains/evm/gas/models.go @@ -34,11 +34,11 @@ type EvmFeeEstimator interface { // L1Oracle returns the L1 gas price oracle only if the chain has one, e.g. OP stack L2s and Arbitrum. L1Oracle() rollups.L1Oracle - GetFee(ctx context.Context, calldata []byte, feeLimit uint32, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (fee EvmFee, chainSpecificFeeLimit uint32, err error) - BumpFee(ctx context.Context, originalFee EvmFee, feeLimit uint32, maxFeePrice *assets.Wei, attempts []EvmPriorAttempt) (bumpedFee EvmFee, chainSpecificFeeLimit uint32, err error) + GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (fee EvmFee, chainSpecificFeeLimit uint64, err error) + BumpFee(ctx context.Context, originalFee EvmFee, feeLimit uint64, maxFeePrice *assets.Wei, attempts []EvmPriorAttempt) (bumpedFee EvmFee, chainSpecificFeeLimit uint64, err error) // GetMaxCost returns the total value = max price x fee units + transferred value - GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint32, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (*big.Int, error) + GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (*big.Int, error) } // NewEstimator returns the estimator for a given config @@ -105,7 +105,7 @@ type DynamicFee struct { } type EvmPriorAttempt struct { - ChainSpecificFeeLimit uint32 + ChainSpecificFeeLimit uint64 BroadcastBeforeBlockNum *int64 TxHash common.Hash TxType int @@ -122,22 +122,22 @@ type EvmEstimator interface { // GetLegacyGas Calculates initial gas fee for non-EIP1559 transaction // maxGasPriceWei parameter is the highest possible gas fee cap that the function will return - GetLegacyGas(ctx context.Context, calldata []byte, gasLimit uint32, maxGasPriceWei *assets.Wei, opts ...feetypes.Opt) (gasPrice *assets.Wei, chainSpecificGasLimit uint32, err error) + GetLegacyGas(ctx context.Context, calldata []byte, gasLimit uint64, maxGasPriceWei *assets.Wei, opts ...feetypes.Opt) (gasPrice *assets.Wei, chainSpecificGasLimit uint64, err error) // BumpLegacyGas Increases gas price and/or limit for non-EIP1559 transactions // if the bumped gas fee is greater than maxGasPriceWei, the method returns an error // attempts must: // - be sorted in order from highest price to lowest price // - all be of transaction type 0x0 or 0x1 - BumpLegacyGas(ctx context.Context, originalGasPrice *assets.Wei, gasLimit uint32, maxGasPriceWei *assets.Wei, attempts []EvmPriorAttempt) (bumpedGasPrice *assets.Wei, chainSpecificGasLimit uint32, err error) + BumpLegacyGas(ctx context.Context, originalGasPrice *assets.Wei, gasLimit uint64, maxGasPriceWei *assets.Wei, attempts []EvmPriorAttempt) (bumpedGasPrice *assets.Wei, chainSpecificGasLimit uint64, err error) // GetDynamicFee Calculates initial gas fee for gas for EIP1559 transactions // maxGasPriceWei parameter is the highest possible gas fee cap that the function will return - GetDynamicFee(ctx context.Context, gasLimit uint32, maxGasPriceWei *assets.Wei) (fee DynamicFee, chainSpecificGasLimit uint32, err error) + GetDynamicFee(ctx context.Context, gasLimit uint64, maxGasPriceWei *assets.Wei) (fee DynamicFee, chainSpecificGasLimit uint64, err error) // BumpDynamicFee Increases gas price and/or limit for non-EIP1559 transactions // if the bumped gas fee or tip caps are greater than maxGasPriceWei, the method returns an error // attempts must: // - be sorted in order from highest price to lowest price // - all be of transaction type 0x2 - BumpDynamicFee(ctx context.Context, original DynamicFee, gasLimit uint32, maxGasPriceWei *assets.Wei, attempts []EvmPriorAttempt) (bumped DynamicFee, chainSpecificGasLimit uint32, err error) + BumpDynamicFee(ctx context.Context, original DynamicFee, gasLimit uint64, maxGasPriceWei *assets.Wei, attempts []EvmPriorAttempt) (bumped DynamicFee, chainSpecificGasLimit uint64, err error) } var _ feetypes.Fee = (*EvmFee)(nil) @@ -241,7 +241,7 @@ func (e *WrappedEvmEstimator) L1Oracle() rollups.L1Oracle { return e.l1Oracle } -func (e *WrappedEvmEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit uint32, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (fee EvmFee, chainSpecificFeeLimit uint32, err error) { +func (e *WrappedEvmEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (fee EvmFee, chainSpecificFeeLimit uint64, err error) { // get dynamic fee if e.EIP1559Enabled { var dynamicFee DynamicFee @@ -256,7 +256,7 @@ func (e *WrappedEvmEstimator) GetFee(ctx context.Context, calldata []byte, feeLi return } -func (e *WrappedEvmEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint32, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (*big.Int, error) { +func (e *WrappedEvmEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint64, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (*big.Int, error) { fees, gasLimit, err := e.GetFee(ctx, calldata, feeLimit, maxFeePrice, opts...) if err != nil { return nil, err @@ -274,7 +274,7 @@ func (e *WrappedEvmEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, return amountWithFees, nil } -func (e *WrappedEvmEstimator) BumpFee(ctx context.Context, originalFee EvmFee, feeLimit uint32, maxFeePrice *assets.Wei, attempts []EvmPriorAttempt) (bumpedFee EvmFee, chainSpecificFeeLimit uint32, err error) { +func (e *WrappedEvmEstimator) BumpFee(ctx context.Context, originalFee EvmFee, feeLimit uint64, maxFeePrice *assets.Wei, attempts []EvmPriorAttempt) (bumpedFee EvmFee, chainSpecificFeeLimit uint64, err error) { // validate only 1 fee type is present if (!originalFee.ValidDynamic() && originalFee.Legacy == nil) || (originalFee.ValidDynamic() && originalFee.Legacy != nil) { err = pkgerrors.New("only one dynamic or legacy fee can be defined") @@ -315,7 +315,7 @@ type GasEstimatorConfig interface { BumpThreshold() uint64 BumpMin() *assets.Wei FeeCapDefault() *assets.Wei - LimitMax() uint32 + LimitMax() uint64 LimitMultiplier() float32 PriceDefault() *assets.Wei TipCapDefault() *assets.Wei @@ -356,7 +356,7 @@ func HexToInt64(input interface{}) int64 { } // BumpLegacyGasPriceOnly will increase the price and apply multiplier to the gas limit -func BumpLegacyGasPriceOnly(cfg bumpConfig, lggr logger.SugaredLogger, currentGasPrice, originalGasPrice *assets.Wei, originalGasLimit uint32, maxGasPriceWei *assets.Wei) (gasPrice *assets.Wei, chainSpecificGasLimit uint32, err error) { +func BumpLegacyGasPriceOnly(cfg bumpConfig, lggr logger.SugaredLogger, currentGasPrice, originalGasPrice *assets.Wei, originalGasLimit uint64, maxGasPriceWei *assets.Wei) (gasPrice *assets.Wei, chainSpecificGasLimit uint64, err error) { gasPrice, err = bumpGasPrice(cfg, lggr, currentGasPrice, originalGasPrice, maxGasPriceWei) if err != nil { return nil, 0, err @@ -391,7 +391,7 @@ func bumpGasPrice(cfg bumpConfig, lggr logger.SugaredLogger, currentGasPrice, or } // BumpDynamicFeeOnly bumps the tip cap and max gas price if necessary -func BumpDynamicFeeOnly(config bumpConfig, feeCapBufferBlocks uint16, lggr logger.SugaredLogger, currentTipCap, currentBaseFee *assets.Wei, originalFee DynamicFee, originalGasLimit uint32, maxGasPriceWei *assets.Wei) (bumped DynamicFee, chainSpecificGasLimit uint32, err error) { +func BumpDynamicFeeOnly(config bumpConfig, feeCapBufferBlocks uint16, lggr logger.SugaredLogger, currentTipCap, currentBaseFee *assets.Wei, originalFee DynamicFee, originalGasLimit uint64, maxGasPriceWei *assets.Wei) (bumped DynamicFee, chainSpecificGasLimit uint64, err error) { bumped, err = bumpDynamicFee(config, feeCapBufferBlocks, lggr, currentTipCap, currentBaseFee, originalFee, maxGasPriceWei) if err != nil { return bumped, 0, err diff --git a/core/chains/evm/gas/models_test.go b/core/chains/evm/gas/models_test.go index 9c0e63a602b..76666143189 100644 --- a/core/chains/evm/gas/models_test.go +++ b/core/chains/evm/gas/models_test.go @@ -22,7 +22,7 @@ func TestWrappedEvmEstimator(t *testing.T) { ctx := testutils.Context(t) // fee values - gasLimit := uint32(10) + gasLimit := uint64(10) legacyFee := assets.NewWeiI(10) dynamicFee := gas.DynamicFee{ FeeCap: assets.NewWeiI(20), diff --git a/core/chains/evm/gas/suggested_price_estimator.go b/core/chains/evm/gas/suggested_price_estimator.go index d58a1155b91..89e497edbd3 100644 --- a/core/chains/evm/gas/suggested_price_estimator.go +++ b/core/chains/evm/gas/suggested_price_estimator.go @@ -154,17 +154,17 @@ func (o *SuggestedPriceEstimator) forceRefresh(ctx context.Context) (err error) func (o *SuggestedPriceEstimator) OnNewLongestChain(context.Context, *evmtypes.Head) {} -func (*SuggestedPriceEstimator) GetDynamicFee(_ context.Context, _ uint32, _ *assets.Wei) (fee DynamicFee, chainSpecificGasLimit uint32, err error) { +func (*SuggestedPriceEstimator) GetDynamicFee(_ context.Context, _ uint64, _ *assets.Wei) (fee DynamicFee, chainSpecificGasLimit uint64, err error) { err = pkgerrors.New("dynamic fees are not implemented for this estimator") return } -func (*SuggestedPriceEstimator) BumpDynamicFee(_ context.Context, _ DynamicFee, _ uint32, _ *assets.Wei, _ []EvmPriorAttempt) (bumped DynamicFee, chainSpecificGasLimit uint32, err error) { +func (*SuggestedPriceEstimator) BumpDynamicFee(_ context.Context, _ DynamicFee, _ uint64, _ *assets.Wei, _ []EvmPriorAttempt) (bumped DynamicFee, chainSpecificGasLimit uint64, err error) { err = pkgerrors.New("dynamic fees are not implemented for this estimator") return } -func (o *SuggestedPriceEstimator) GetLegacyGas(ctx context.Context, _ []byte, GasLimit uint32, maxGasPriceWei *assets.Wei, opts ...feetypes.Opt) (gasPrice *assets.Wei, chainSpecificGasLimit uint32, err error) { +func (o *SuggestedPriceEstimator) GetLegacyGas(ctx context.Context, _ []byte, GasLimit uint64, maxGasPriceWei *assets.Wei, opts ...feetypes.Opt) (gasPrice *assets.Wei, chainSpecificGasLimit uint64, err error) { chainSpecificGasLimit = GasLimit ok := o.IfStarted(func() { if slices.Contains(opts, feetypes.OptForceRefetch) { @@ -192,7 +192,7 @@ func (o *SuggestedPriceEstimator) GetLegacyGas(ctx context.Context, _ []byte, Ga // Adds the larger of BumpPercent and BumpMin configs as a buffer on top of the price returned from the RPC. // The only reason bumping logic would be called on the SuggestedPriceEstimator is if there was a significant price spike // between the last price update and when the tx was submitted. Refreshing the price helps ensure the latest market changes are accounted for. -func (o *SuggestedPriceEstimator) BumpLegacyGas(ctx context.Context, originalFee *assets.Wei, feeLimit uint32, maxGasPriceWei *assets.Wei, _ []EvmPriorAttempt) (newGasPrice *assets.Wei, chainSpecificGasLimit uint32, err error) { +func (o *SuggestedPriceEstimator) BumpLegacyGas(ctx context.Context, originalFee *assets.Wei, feeLimit uint64, maxGasPriceWei *assets.Wei, _ []EvmPriorAttempt) (newGasPrice *assets.Wei, chainSpecificGasLimit uint64, err error) { chainSpecificGasLimit = feeLimit ok := o.IfStarted(func() { // Immediately return error if original fee is greater than or equal to the max gas price diff --git a/core/chains/evm/gas/suggested_price_estimator_test.go b/core/chains/evm/gas/suggested_price_estimator_test.go index c09582774b8..ff5e004031b 100644 --- a/core/chains/evm/gas/suggested_price_estimator_test.go +++ b/core/chains/evm/gas/suggested_price_estimator_test.go @@ -24,7 +24,7 @@ func TestSuggestedPriceEstimator(t *testing.T) { maxGasPrice := assets.NewWeiI(100) calldata := []byte{0x00, 0x00, 0x01, 0x02, 0x03} - const gasLimit uint32 = 80000 + const gasLimit uint64 = 80000 cfg := &gas.MockGasEstimatorConfig{BumpPercentF: 10, BumpMinF: assets.NewWei(big.NewInt(1)), BumpThresholdF: 1} @@ -64,7 +64,7 @@ func TestSuggestedPriceEstimator(t *testing.T) { require.Error(t, err) assert.EqualError(t, err, "estimated gas price: 42 wei is greater than the maximum gas price configured: 40 wei") assert.Nil(t, gasPrice) - assert.Equal(t, uint32(0), chainSpecificGasLimit) + assert.Equal(t, uint64(0), chainSpecificGasLimit) }) t.Run("gas price is lower than global max gas price", func(t *testing.T) { @@ -80,7 +80,7 @@ func TestSuggestedPriceEstimator(t *testing.T) { gasPrice, chainSpecificGasLimit, err := o.GetLegacyGas(testutils.Context(t), calldata, gasLimit, assets.NewWeiI(110)) assert.EqualError(t, err, "estimated gas price: 120 wei is greater than the maximum gas price configured: 110 wei") assert.Nil(t, gasPrice) - assert.Equal(t, uint32(0), chainSpecificGasLimit) + assert.Equal(t, uint64(0), chainSpecificGasLimit) }) t.Run("calling GetLegacyGas on started estimator if initial call failed returns error", func(t *testing.T) { @@ -180,7 +180,7 @@ func TestSuggestedPriceEstimator(t *testing.T) { require.Error(t, err) assert.EqualError(t, err, "estimated gas price: 42 wei is greater than the maximum gas price configured: 40 wei") assert.Nil(t, gasPrice) - assert.Equal(t, uint32(0), chainSpecificGasLimit) + assert.Equal(t, uint64(0), chainSpecificGasLimit) }) t.Run("calling BumpLegacyGas on started estimator returns max gas price when suggested price under max but the buffer exceeds it", func(t *testing.T) { diff --git a/core/chains/evm/txmgr/attempts.go b/core/chains/evm/txmgr/attempts.go index 892920c0f67..aa1fa8cdeb2 100644 --- a/core/chains/evm/txmgr/attempts.go +++ b/core/chains/evm/txmgr/attempts.go @@ -45,7 +45,7 @@ func NewEvmTxAttemptBuilder(chainID big.Int, feeConfig evmTxAttemptBuilderFeeCon // NewTxAttempt builds an new attempt using the configured fee estimator + using the EIP1559 config to determine tx type // used for when a brand new transaction is being created in the txm -func (c *evmTxAttemptBuilder) NewTxAttempt(ctx context.Context, etx Tx, lggr logger.Logger, opts ...feetypes.Opt) (attempt TxAttempt, fee gas.EvmFee, feeLimit uint32, retryable bool, err error) { +func (c *evmTxAttemptBuilder) NewTxAttempt(ctx context.Context, etx Tx, lggr logger.Logger, opts ...feetypes.Opt) (attempt TxAttempt, fee gas.EvmFee, feeLimit uint64, retryable bool, err error) { txType := 0x0 if c.feeConfig.EIP1559DynamicFees() { txType = 0x2 @@ -55,7 +55,7 @@ func (c *evmTxAttemptBuilder) NewTxAttempt(ctx context.Context, etx Tx, lggr log // NewTxAttemptWithType builds a new attempt with a new fee estimation where the txType can be specified by the caller // used for L2 re-estimation on broadcasting (note EIP1559 must be disabled otherwise this will fail with mismatched fees + tx type) -func (c *evmTxAttemptBuilder) NewTxAttemptWithType(ctx context.Context, etx Tx, lggr logger.Logger, txType int, opts ...feetypes.Opt) (attempt TxAttempt, fee gas.EvmFee, feeLimit uint32, retryable bool, err error) { +func (c *evmTxAttemptBuilder) NewTxAttemptWithType(ctx context.Context, etx Tx, lggr logger.Logger, txType int, opts ...feetypes.Opt) (attempt TxAttempt, fee gas.EvmFee, feeLimit uint64, retryable bool, err error) { keySpecificMaxGasPriceWei := c.feeConfig.PriceMaxKey(etx.FromAddress) fee, feeLimit, err = c.EvmFeeEstimator.GetFee(ctx, etx.EncodedPayload, etx.FeeLimit, keySpecificMaxGasPriceWei, opts...) if err != nil { @@ -68,7 +68,7 @@ func (c *evmTxAttemptBuilder) NewTxAttemptWithType(ctx context.Context, etx Tx, // NewBumpTxAttempt builds a new attempt with a bumped fee - based on the previous attempt tx type // used in the txm broadcaster + confirmer when tx ix rejected for too low fee or is not included in a timely manner -func (c *evmTxAttemptBuilder) NewBumpTxAttempt(ctx context.Context, etx Tx, previousAttempt TxAttempt, priorAttempts []TxAttempt, lggr logger.Logger) (attempt TxAttempt, bumpedFee gas.EvmFee, bumpedFeeLimit uint32, retryable bool, err error) { +func (c *evmTxAttemptBuilder) NewBumpTxAttempt(ctx context.Context, etx Tx, previousAttempt TxAttempt, priorAttempts []TxAttempt, lggr logger.Logger) (attempt TxAttempt, bumpedFee gas.EvmFee, bumpedFeeLimit uint64, retryable bool, err error) { keySpecificMaxGasPriceWei := c.feeConfig.PriceMaxKey(etx.FromAddress) bumpedFee, bumpedFeeLimit, err = c.EvmFeeEstimator.BumpFee(ctx, previousAttempt.TxFee, etx.FeeLimit, keySpecificMaxGasPriceWei, newEvmPriorAttempts(priorAttempts)) @@ -82,7 +82,7 @@ func (c *evmTxAttemptBuilder) NewBumpTxAttempt(ctx context.Context, etx Tx, prev // NewCustomTxAttempt is the lowest level func where the fee parameters + tx type must be passed in // used in the txm for force rebroadcast where fees and tx type are pre-determined without an estimator -func (c *evmTxAttemptBuilder) NewCustomTxAttempt(ctx context.Context, etx Tx, fee gas.EvmFee, gasLimit uint32, txType int, lggr logger.Logger) (attempt TxAttempt, retryable bool, err error) { +func (c *evmTxAttemptBuilder) NewCustomTxAttempt(ctx context.Context, etx Tx, fee gas.EvmFee, gasLimit uint64, txType int, lggr logger.Logger) (attempt TxAttempt, retryable bool, err error) { switch txType { case 0x0: // legacy if fee.Legacy == nil { @@ -112,7 +112,7 @@ func (c *evmTxAttemptBuilder) NewCustomTxAttempt(ctx context.Context, etx Tx, fe } // NewEmptyTxAttempt is used in ForceRebroadcast to create a signed tx with zero value sent to the zero address -func (c *evmTxAttemptBuilder) NewEmptyTxAttempt(ctx context.Context, nonce evmtypes.Nonce, feeLimit uint32, fee gas.EvmFee, fromAddress common.Address) (attempt TxAttempt, err error) { +func (c *evmTxAttemptBuilder) NewEmptyTxAttempt(ctx context.Context, nonce evmtypes.Nonce, feeLimit uint64, fee gas.EvmFee, fromAddress common.Address) (attempt TxAttempt, err error) { value := big.NewInt(0) payload := []byte{} @@ -141,8 +141,8 @@ func (c *evmTxAttemptBuilder) NewEmptyTxAttempt(ctx context.Context, nonce evmty } -func (c *evmTxAttemptBuilder) newDynamicFeeAttempt(ctx context.Context, etx Tx, fee gas.DynamicFee, gasLimit uint32) (attempt TxAttempt, err error) { - if err = validateDynamicFeeGas(c.feeConfig, c.feeConfig.TipCapMin(), fee, gasLimit, etx); err != nil { +func (c *evmTxAttemptBuilder) newDynamicFeeAttempt(ctx context.Context, etx Tx, fee gas.DynamicFee, gasLimit uint64) (attempt TxAttempt, err error) { + if err = validateDynamicFeeGas(c.feeConfig, c.feeConfig.TipCapMin(), fee, etx); err != nil { return attempt, pkgerrors.Wrap(err, "error validating gas") } @@ -178,7 +178,7 @@ type keySpecificEstimator interface { // validateDynamicFeeGas is a sanity check - we have other checks elsewhere, but this // makes sure we _never_ create an invalid attempt -func validateDynamicFeeGas(kse keySpecificEstimator, tipCapMinimum *assets.Wei, fee gas.DynamicFee, gasLimit uint32, etx Tx) error { +func validateDynamicFeeGas(kse keySpecificEstimator, tipCapMinimum *assets.Wei, fee gas.DynamicFee, etx Tx) error { gasTipCap, gasFeeCap := fee.TipCap, fee.FeeCap if gasTipCap == nil { @@ -213,21 +213,21 @@ func validateDynamicFeeGas(kse keySpecificEstimator, tipCapMinimum *assets.Wei, return nil } -func newDynamicFeeTransaction(nonce uint64, to common.Address, value *big.Int, gasLimit uint32, chainID *big.Int, gasTipCap, gasFeeCap *assets.Wei, data []byte) types.DynamicFeeTx { +func newDynamicFeeTransaction(nonce uint64, to common.Address, value *big.Int, gasLimit uint64, chainID *big.Int, gasTipCap, gasFeeCap *assets.Wei, data []byte) types.DynamicFeeTx { return types.DynamicFeeTx{ ChainID: chainID, Nonce: nonce, GasTipCap: gasTipCap.ToInt(), GasFeeCap: gasFeeCap.ToInt(), - Gas: uint64(gasLimit), + Gas: gasLimit, To: &to, Value: value, Data: data, } } -func (c *evmTxAttemptBuilder) newLegacyAttempt(ctx context.Context, etx Tx, gasPrice *assets.Wei, gasLimit uint32) (attempt TxAttempt, err error) { - if err = validateLegacyGas(ctx, c.feeConfig, c.feeConfig.PriceMin(), gasPrice, gasLimit, etx); err != nil { +func (c *evmTxAttemptBuilder) newLegacyAttempt(ctx context.Context, etx Tx, gasPrice *assets.Wei, gasLimit uint64) (attempt TxAttempt, err error) { + if err = validateLegacyGas(c.feeConfig, c.feeConfig.PriceMin(), gasPrice, etx); err != nil { return attempt, pkgerrors.Wrap(err, "error validating gas") } @@ -260,7 +260,7 @@ func (c *evmTxAttemptBuilder) newLegacyAttempt(ctx context.Context, etx Tx, gasP // validateLegacyGas is a sanity check - we have other checks elsewhere, but this // makes sure we _never_ create an invalid attempt -func validateLegacyGas(ctx context.Context, kse keySpecificEstimator, minGasPriceWei, gasPrice *assets.Wei, gasLimit uint32, etx Tx) error { +func validateLegacyGas(kse keySpecificEstimator, minGasPriceWei, gasPrice *assets.Wei, etx Tx) error { if gasPrice == nil { panic("gas price missing") } @@ -290,12 +290,12 @@ func (c *evmTxAttemptBuilder) newSignedAttempt(ctx context.Context, etx Tx, tx * return attempt, nil } -func newLegacyTransaction(nonce uint64, to common.Address, value *big.Int, gasLimit uint32, gasPrice *assets.Wei, data []byte) types.LegacyTx { +func newLegacyTransaction(nonce uint64, to common.Address, value *big.Int, gasLimit uint64, gasPrice *assets.Wei, data []byte) types.LegacyTx { return types.LegacyTx{ Nonce: nonce, To: &to, Value: value, - Gas: uint64(gasLimit), + Gas: gasLimit, GasPrice: gasPrice.ToInt(), Data: data, } diff --git a/core/chains/evm/txmgr/attempts_test.go b/core/chains/evm/txmgr/attempts_test.go index b1e24984c37..ab8a5831b20 100644 --- a/core/chains/evm/txmgr/attempts_test.go +++ b/core/chains/evm/txmgr/attempts_test.go @@ -257,8 +257,8 @@ func TestTxm_NewCustomTxAttempt_NonRetryableErrors(t *testing.T) { func TestTxm_EvmTxAttemptBuilder_RetryableEstimatorError(t *testing.T) { est := gasmocks.NewEvmFeeEstimator(t) - est.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{}, uint32(0), pkgerrors.New("fail")) - est.On("BumpFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{}, uint32(0), pkgerrors.New("fail")) + est.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{}, uint64(0), pkgerrors.New("fail")) + est.On("BumpFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.EvmFee{}, uint64(0), pkgerrors.New("fail")) kst := ksmocks.NewEth(t) lggr := logger.Test(t) diff --git a/core/chains/evm/txmgr/broadcaster_test.go b/core/chains/evm/txmgr/broadcaster_test.go index 2af22d76a66..0b76f7fc6d1 100644 --- a/core/chains/evm/txmgr/broadcaster_test.go +++ b/core/chains/evm/txmgr/broadcaster_test.go @@ -36,7 +36,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" gasmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" @@ -188,7 +187,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success(t *testing.T) { encodedPayload := []byte{1, 2, 3} value := big.Int(assets.NewEthValue(142)) - gasLimit := uint32(242) + gasLimit := uint64(242) checker := txmgr.TransmitCheckerSpec{ CheckerType: txmgr.TransmitCheckerTypeSimulate, } @@ -276,7 +275,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success(t *testing.T) { return false } require.Equal(t, evmcfg.EVM().ChainID(), tx.ChainId()) - require.Equal(t, uint64(gasLimit), tx.Gas()) + require.Equal(t, gasLimit, tx.Gas()) require.Equal(t, evmcfg.EVM().GasEstimator().PriceDefault().ToInt(), tx.GasPrice()) require.Equal(t, toAddress, *tx.To()) require.Equal(t, value.String(), tx.Value().String()) @@ -299,7 +298,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success(t *testing.T) { return false } require.Equal(t, evmcfg.EVM().ChainID(), tx.ChainId()) - require.Equal(t, uint64(gasLimit), tx.Gas()) + require.Equal(t, gasLimit, tx.Gas()) require.Equal(t, evmcfg.EVM().GasEstimator().PriceDefault().ToInt(), tx.GasPrice()) require.Equal(t, toAddress, *tx.To()) require.Equal(t, value.String(), tx.Value().String()) @@ -615,7 +614,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_OptimisticLockingOnEthTx(t *testi chStartEstimate := make(chan struct{}) chBlock := make(chan struct{}) - estimator.On("GetFee", mock.Anything, mock.Anything, mock.Anything, ccfg.EVM().GasEstimator().PriceMaxKey(fromAddress)).Return(gas.EvmFee{Legacy: assets.GWei(32)}, uint32(500), nil).Run(func(_ mock.Arguments) { + estimator.On("GetFee", mock.Anything, mock.Anything, mock.Anything, ccfg.EVM().GasEstimator().PriceMaxKey(fromAddress)).Return(gas.EvmFee{Legacy: assets.GWei(32)}, uint64(500), nil).Run(func(_ mock.Arguments) { close(chStartEstimate) <-chBlock }).Once() @@ -705,7 +704,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success_WithMultiplier(t *testing func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { toAddress := gethCommon.HexToAddress("0x6C03DDA95a2AEd917EeCc6eddD4b9D16E6380411") value := big.Int(assets.NewEthValue(142)) - gasLimit := uint32(242) + gasLimit := uint64(242) encodedPayload := []byte{0, 1} nextNonce := evmtypes.Nonce(916714082576372851) firstNonce := nextNonce @@ -994,7 +993,7 @@ func getLocalNextNonce(t *testing.T, eb *txmgr.Broadcaster, fromAddress gethComm func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { toAddress := gethCommon.HexToAddress("0x6C03DDA95a2AEd917EeCc6eddD4b9D16E6380411") value := big.Int(assets.NewEthValue(142)) - gasLimit := uint32(242) + gasLimit := uint64(242) encodedPayload := []byte{0, 1} db := pgtest.NewSqlxDB(t) @@ -1632,7 +1631,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { func TestEthBroadcaster_ProcessUnstartedEthTxs_KeystoreErrors(t *testing.T) { toAddress := gethCommon.HexToAddress("0x6C03DDA95a2AEd917EeCc6eddD4b9D16E6380411") value := big.Int(assets.NewEthValue(142)) - gasLimit := uint32(242) + gasLimit := uint64(242) encodedPayload := []byte{0, 1} localNonce := 0 @@ -1679,7 +1678,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_KeystoreErrors(t *testing.T) { assert.Len(t, etx.TxAttempts, 0) // Check that the key did not have its nonce incremented - var nonce types.Nonce + var nonce evmtypes.Nonce nonce, err = eb.GetNextSequence(ctx, fromAddress) require.NoError(t, err) require.Equal(t, int64(localNonce), int64(nonce)) diff --git a/core/chains/evm/txmgr/client.go b/core/chains/evm/txmgr/client.go index e794f56ba31..89375e2d017 100644 --- a/core/chains/evm/txmgr/client.go +++ b/core/chains/evm/txmgr/client.go @@ -145,9 +145,9 @@ func (c *evmTxmClient) BatchGetReceipts(ctx context.Context, attempts []TxAttemp // May be useful for clearing stuck nonces func (c *evmTxmClient) SendEmptyTransaction( ctx context.Context, - newTxAttempt func(ctx context.Context, seq evmtypes.Nonce, feeLimit uint32, fee gas.EvmFee, fromAddress common.Address) (attempt TxAttempt, err error), + newTxAttempt func(ctx context.Context, seq evmtypes.Nonce, feeLimit uint64, fee gas.EvmFee, fromAddress common.Address) (attempt TxAttempt, err error), seq evmtypes.Nonce, - gasLimit uint32, + gasLimit uint64, fee gas.EvmFee, fromAddress common.Address, ) (txhash string, err error) { @@ -171,7 +171,7 @@ func (c *evmTxmClient) CallContract(ctx context.Context, a TxAttempt, blockNumbe _, errCall := c.client.CallContract(ctx, ethereum.CallMsg{ From: a.Tx.FromAddress, To: &a.Tx.ToAddress, - Gas: uint64(a.Tx.FeeLimit), + Gas: a.Tx.FeeLimit, GasPrice: a.TxFee.Legacy.ToInt(), GasFeeCap: a.TxFee.DynamicFeeCap.ToInt(), GasTipCap: a.TxFee.DynamicTipCap.ToInt(), diff --git a/core/chains/evm/txmgr/config.go b/core/chains/evm/txmgr/config.go index 8346a0d0551..b41753a070b 100644 --- a/core/chains/evm/txmgr/config.go +++ b/core/chains/evm/txmgr/config.go @@ -27,7 +27,7 @@ type FeeConfig interface { BumpPercent() uint16 BumpThreshold() uint64 BumpTxDepth() uint32 - LimitDefault() uint32 + LimitDefault() uint64 PriceDefault() *assets.Wei TipCapMin() *assets.Wei PriceMax() *assets.Wei diff --git a/core/chains/evm/txmgr/confirmer_test.go b/core/chains/evm/txmgr/confirmer_test.go index 1860b557335..ec09085bc44 100644 --- a/core/chains/evm/txmgr/confirmer_test.go +++ b/core/chains/evm/txmgr/confirmer_test.go @@ -1641,7 +1641,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing estimator := gasmocks.NewEvmEstimator(t) newEst := func(logger.Logger) gas.EvmEstimator { return estimator } - estimator.On("BumpLegacyGas", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, uint32(0), pkgerrors.Wrapf(commonfee.ErrConnectivity, "transaction...")) + estimator.On("BumpLegacyGas", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, uint64(0), pkgerrors.Wrapf(commonfee.ErrConnectivity, "transaction...")) ge := ccfg.EVM().GasEstimator() feeEstimator := gas.NewWrappedEvmEstimator(lggr, newEst, ge.EIP1559DynamicFees(), nil) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, kst, feeEstimator) @@ -1686,7 +1686,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing kst := ksmocks.NewEth(t) estimator := gasmocks.NewEvmEstimator(t) - estimator.On("BumpDynamicFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.DynamicFee{}, uint32(0), pkgerrors.Wrapf(commonfee.ErrConnectivity, "transaction...")) + estimator.On("BumpDynamicFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.DynamicFee{}, uint64(0), pkgerrors.Wrapf(commonfee.ErrConnectivity, "transaction...")) newEst := func(logger.Logger) gas.EvmEstimator { return estimator } // Create confirmer with necessary state ge := ccfg.EVM().GasEstimator() @@ -2839,7 +2839,7 @@ func TestEthConfirmer_ForceRebroadcast(t *testing.T) { etx2 := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 2, fromAddress) gasPriceWei := gas.EvmFee{Legacy: assets.GWei(52)} - overrideGasLimit := uint32(20000) + overrideGasLimit := uint64(20000) t.Run("rebroadcasts one eth_tx if it falls within in nonce range", func(t *testing.T) { ethClient := evmtest.NewEthClientMockWithDefaultChain(t) @@ -2848,7 +2848,7 @@ func TestEthConfirmer_ForceRebroadcast(t *testing.T) { ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(*etx1.Sequence) && tx.GasPrice().Int64() == gasPriceWei.Legacy.Int64() && - tx.Gas() == uint64(overrideGasLimit) && + tx.Gas() == overrideGasLimit && reflect.DeepEqual(tx.Data(), etx1.EncodedPayload) && tx.To().String() == etx1.ToAddress.String() }), mock.Anything).Return(commonclient.Successful, nil).Once() @@ -2863,7 +2863,7 @@ func TestEthConfirmer_ForceRebroadcast(t *testing.T) { ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(*etx1.Sequence) && tx.GasPrice().Int64() == gasPriceWei.Legacy.Int64() && - tx.Gas() == uint64(etx1.FeeLimit) && + tx.Gas() == etx1.FeeLimit && reflect.DeepEqual(tx.Data(), etx1.EncodedPayload) && tx.To().String() == etx1.ToAddress.String() }), mock.Anything).Return(commonclient.Successful, nil).Once() @@ -2876,10 +2876,10 @@ func TestEthConfirmer_ForceRebroadcast(t *testing.T) { ec := newEthConfirmer(t, txStore, ethClient, config, ethKeyStore, nil) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { - return tx.Nonce() == uint64(*etx1.Sequence) && tx.GasPrice().Int64() == gasPriceWei.Legacy.Int64() && tx.Gas() == uint64(overrideGasLimit) + return tx.Nonce() == uint64(*etx1.Sequence) && tx.GasPrice().Int64() == gasPriceWei.Legacy.Int64() && tx.Gas() == overrideGasLimit }), mock.Anything).Return(commonclient.Successful, nil).Once() ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { - return tx.Nonce() == uint64(*etx2.Sequence) && tx.GasPrice().Int64() == gasPriceWei.Legacy.Int64() && tx.Gas() == uint64(overrideGasLimit) + return tx.Nonce() == uint64(*etx2.Sequence) && tx.GasPrice().Int64() == gasPriceWei.Legacy.Int64() && tx.Gas() == overrideGasLimit }), mock.Anything).Return(commonclient.Successful, nil).Once() require.NoError(t, ec.ForceRebroadcast(testutils.Context(t), []evmtypes.Nonce{(1), (2)}, gasPriceWei, fromAddress, overrideGasLimit)) @@ -2900,7 +2900,7 @@ func TestEthConfirmer_ForceRebroadcast(t *testing.T) { ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return tx.Nonce() == uint64(nonce) && tx.GasPrice().Int64() == gasPriceWei.Legacy.Int64() && - tx.Gas() == uint64(overrideGasLimit) && + tx.Gas() == overrideGasLimit && *tx.To() == fromAddress && tx.Value().Cmp(big.NewInt(0)) == 0 && len(tx.Data()) == 0 @@ -2916,7 +2916,7 @@ func TestEthConfirmer_ForceRebroadcast(t *testing.T) { ec := newEthConfirmer(t, txStore, ethClient, config, ethKeyStore, nil) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { - return tx.Nonce() == uint64(0) && tx.GasPrice().Int64() == gasPriceWei.Legacy.Int64() && uint32(tx.Gas()) == config.EVM().GasEstimator().LimitDefault() + return tx.Nonce() == uint64(0) && tx.GasPrice().Int64() == gasPriceWei.Legacy.Int64() && tx.Gas() == config.EVM().GasEstimator().LimitDefault() }), mock.Anything).Return(commonclient.Successful, nil).Once() require.NoError(t, ec.ForceRebroadcast(testutils.Context(t), []evmtypes.Nonce{(0)}, gasPriceWei, fromAddress, 0)) diff --git a/core/chains/evm/txmgr/evm_tx_store.go b/core/chains/evm/txmgr/evm_tx_store.go index 364ee3f04d1..8187a390878 100644 --- a/core/chains/evm/txmgr/evm_tx_store.go +++ b/core/chains/evm/txmgr/evm_tx_store.go @@ -167,7 +167,7 @@ type DbEthTx struct { Value assets.Eth // GasLimit on the EthTx is always the conceptual gas limit, which is not // necessarily the same as the on-chain encoded value (i.e. Optimism) - GasLimit uint32 + GasLimit uint64 Error nullv4.String // BroadcastAt is updated every time an attempt for this eth_tx is re-sent // In almost all cases it will be within a second or so of the actual send time. @@ -276,7 +276,7 @@ type DbEthTxAttempt struct { BroadcastBeforeBlockNum *int64 State string CreatedAt time.Time - ChainSpecificGasLimit uint32 + ChainSpecificGasLimit uint64 TxType int GasTipCap *assets.Wei GasFeeCap *assets.Wei diff --git a/core/chains/evm/txmgr/evm_tx_store_test.go b/core/chains/evm/txmgr/evm_tx_store_test.go index 0994268037f..83d2381d007 100644 --- a/core/chains/evm/txmgr/evm_tx_store_test.go +++ b/core/chains/evm/txmgr/evm_tx_store_test.go @@ -1620,7 +1620,7 @@ func TestORM_CheckTxQueueCapacity(t *testing.T) { toAddress := testutils.NewAddress() encodedPayload := []byte{1, 2, 3} - feeLimit := uint32(1000000000) + feeLimit := uint64(1000000000) value := big.Int(assets.NewEthValue(142)) var maxUnconfirmedTransactions uint64 = 2 @@ -1713,7 +1713,7 @@ func TestORM_CreateTransaction(t *testing.T) { _, fromAddress := cltest.MustInsertRandomKey(t, kst.Eth()) toAddress := testutils.NewAddress() - gasLimit := uint32(1000) + gasLimit := uint64(1000) payload := []byte{1, 2, 3} ethClient := evmtest.NewEthClientMockWithDefaultChain(t) diff --git a/core/chains/evm/txmgr/test_helpers.go b/core/chains/evm/txmgr/test_helpers.go index e279dddf5fa..8cb771943b0 100644 --- a/core/chains/evm/txmgr/test_helpers.go +++ b/core/chains/evm/txmgr/test_helpers.go @@ -68,7 +68,7 @@ func (g *TestGasEstimatorConfig) BlockHistory() evmconfig.BlockHistory { } func (g *TestGasEstimatorConfig) EIP1559DynamicFees() bool { return false } -func (g *TestGasEstimatorConfig) LimitDefault() uint32 { return 42 } +func (g *TestGasEstimatorConfig) LimitDefault() uint64 { return 42 } func (g *TestGasEstimatorConfig) BumpPercent() uint16 { return 42 } func (g *TestGasEstimatorConfig) BumpThreshold() uint64 { return g.bumpThreshold } func (g *TestGasEstimatorConfig) BumpMin() *assets.Wei { return assets.NewWeiI(42) } @@ -76,7 +76,7 @@ func (g *TestGasEstimatorConfig) FeeCapDefault() *assets.Wei { return assets.New func (g *TestGasEstimatorConfig) PriceDefault() *assets.Wei { return assets.NewWeiI(42) } func (g *TestGasEstimatorConfig) TipCapDefault() *assets.Wei { return assets.NewWeiI(42) } func (g *TestGasEstimatorConfig) TipCapMin() *assets.Wei { return assets.NewWeiI(42) } -func (g *TestGasEstimatorConfig) LimitMax() uint32 { return 0 } +func (g *TestGasEstimatorConfig) LimitMax() uint64 { return 0 } func (g *TestGasEstimatorConfig) LimitMultiplier() float32 { return 0 } func (g *TestGasEstimatorConfig) BumpTxDepth() uint32 { return 42 } func (g *TestGasEstimatorConfig) LimitTransfer() uint32 { return 42 } diff --git a/core/chains/evm/txmgr/txmgr_test.go b/core/chains/evm/txmgr/txmgr_test.go index da18c592a55..0c812800f11 100644 --- a/core/chains/evm/txmgr/txmgr_test.go +++ b/core/chains/evm/txmgr/txmgr_test.go @@ -113,7 +113,7 @@ func TestTxm_CreateTransaction(t *testing.T) { _, fromAddress := cltest.MustInsertRandomKey(t, kst.Eth()) toAddress := testutils.NewAddress() - gasLimit := uint32(1000) + gasLimit := uint64(1000) payload := []byte{1, 2, 3} config, dbConfig, evmConfig := txmgr.MakeTestConfigs(t) @@ -396,7 +396,7 @@ func TestTxm_CreateTransaction_OutOfEth(t *testing.T) { fromAddress := thisKey.Address evmFromAddress := fromAddress - gasLimit := uint32(1000) + gasLimit := uint64(1000) toAddress := testutils.NewAddress() config, dbConfig, evmConfig := txmgr.MakeTestConfigs(t) @@ -784,13 +784,13 @@ func withDefaults() func(*txmgr.TxRequest) { tx.ToAddress = testutils.NewAddress() tx.EncodedPayload = []byte{1, 2, 3} tx.Value = big.Int(assets.NewEthValue(142)) - tx.FeeLimit = uint32(1000000000) + tx.FeeLimit = uint64(1000000000) tx.Strategy = txmgrcommon.NewSendEveryStrategy() // Set default values for other fields if needed } } -func mustCreateUnstartedTx(t testing.TB, txStore txmgr.EvmTxStore, fromAddress common.Address, toAddress common.Address, encodedPayload []byte, gasLimit uint32, value big.Int, chainID *big.Int, opts ...interface{}) (tx txmgr.Tx) { +func mustCreateUnstartedTx(t testing.TB, txStore txmgr.EvmTxStore, fromAddress common.Address, toAddress common.Address, encodedPayload []byte, gasLimit uint64, value big.Int, chainID *big.Int) (tx txmgr.Tx) { txRequest := txmgr.TxRequest{ FromAddress: fromAddress, ToAddress: toAddress, diff --git a/core/cmd/shell_local.go b/core/cmd/shell_local.go index 7e03fe719e1..8391e3bc70b 100644 --- a/core/cmd/shell_local.go +++ b/core/cmd/shell_local.go @@ -641,7 +641,7 @@ func (s *Shell) RebroadcastTransactions(c *cli.Context) (err error) { for i := int64(0); i < totalNonces; i++ { nonces[i] = evmtypes.Nonce(beginningNonce + i) } - err = ec.ForceRebroadcast(ctx, nonces, gas.EvmFee{Legacy: assets.NewWeiI(int64(gasPriceWei))}, address, uint32(overrideGasLimit)) + err = ec.ForceRebroadcast(ctx, nonces, gas.EvmFee{Legacy: assets.NewWeiI(int64(gasPriceWei))}, address, uint64(overrideGasLimit)) return s.errorOut(err) } diff --git a/core/internal/cltest/factories.go b/core/internal/cltest/factories.go index 2649cc47c6c..d192ce3d415 100644 --- a/core/internal/cltest/factories.go +++ b/core/internal/cltest/factories.go @@ -142,7 +142,7 @@ func NewEthTx(fromAddress common.Address) txmgr.Tx { ToAddress: testutils.NewAddress(), EncodedPayload: []byte{1, 2, 3}, Value: big.Int(assets.NewEthValue(142)), - FeeLimit: uint32(1000000000), + FeeLimit: uint64(1000000000), State: txmgrcommon.TxUnstarted, } } diff --git a/core/internal/features/features_test.go b/core/internal/features/features_test.go index d94452f2512..0b22d479da4 100644 --- a/core/internal/features/features_test.go +++ b/core/internal/features/features_test.go @@ -1334,7 +1334,7 @@ func TestIntegration_BlockHistoryEstimator(t *testing.T) { estimator := chain.GasEstimator() gasPrice, gasLimit, err := estimator.GetFee(testutils.Context(t), nil, 500_000, maxGasPrice) require.NoError(t, err) - assert.Equal(t, uint32(500000), gasLimit) + assert.Equal(t, uint64(500000), gasLimit) assert.Equal(t, "41.5 gwei", gasPrice.Legacy.String()) assert.Equal(t, initialDefaultGasPrice, chain.Config().EVM().GasEstimator().PriceDefault().Int64()) // unchanged diff --git a/core/services/blockhashstore/batch_bhs.go b/core/services/blockhashstore/batch_bhs.go index d8381ff6231..ffaa22b2463 100644 --- a/core/services/blockhashstore/batch_bhs.go +++ b/core/services/blockhashstore/batch_bhs.go @@ -18,7 +18,7 @@ import ( ) type batchBHSConfig interface { - LimitDefault() uint32 + LimitDefault() uint64 } type BatchBlockhashStore struct { diff --git a/core/services/blockhashstore/bhs.go b/core/services/blockhashstore/bhs.go index 0ca91c682e7..877e7b3dc25 100644 --- a/core/services/blockhashstore/bhs.go +++ b/core/services/blockhashstore/bhs.go @@ -25,7 +25,7 @@ import ( var _ BHS = &BulletproofBHS{} type bpBHSConfig interface { - LimitDefault() uint32 + LimitDefault() uint64 } type bpBHSDatabaseConfig interface { diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 44c19aa257d..4d6ab0993e3 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -487,8 +487,8 @@ func TestConfig_Marshal(t *testing.T) { BumpTxDepth: ptr[uint32](6), BumpMin: assets.NewWeiI(100), FeeCapDefault: assets.NewWeiI(math.MaxInt64), - LimitDefault: ptr[uint32](12), - LimitMax: ptr[uint32](17), + LimitDefault: ptr[uint64](12), + LimitMax: ptr[uint64](17), LimitMultiplier: mustDecimal("1.234"), LimitTransfer: ptr[uint32](100), TipCapDefault: assets.NewWeiI(2), diff --git a/core/services/fluxmonitorv2/config.go b/core/services/fluxmonitorv2/config.go index 18fdf72798b..585c3f3f329 100644 --- a/core/services/fluxmonitorv2/config.go +++ b/core/services/fluxmonitorv2/config.go @@ -15,7 +15,7 @@ type Config interface { } type EvmFeeConfig interface { - LimitDefault() uint32 // Evm + LimitDefault() uint64 // Evm LimitJobType() config.LimitJobType } diff --git a/core/services/fluxmonitorv2/contract_submitter.go b/core/services/fluxmonitorv2/contract_submitter.go index c5a6e599f5d..c8d98a1a2f2 100644 --- a/core/services/fluxmonitorv2/contract_submitter.go +++ b/core/services/fluxmonitorv2/contract_submitter.go @@ -25,7 +25,7 @@ type FluxAggregatorContractSubmitter struct { flux_aggregator_wrapper.FluxAggregatorInterface orm ORM keyStore KeyStoreInterface - gasLimit uint32 + gasLimit uint64 forwardingAllowed bool chainID *big.Int } @@ -35,7 +35,7 @@ func NewFluxAggregatorContractSubmitter( contract flux_aggregator_wrapper.FluxAggregatorInterface, orm ORM, keyStore KeyStoreInterface, - gasLimit uint32, + gasLimit uint64, forwardingAllowed bool, chainID *big.Int, ) *FluxAggregatorContractSubmitter { diff --git a/core/services/fluxmonitorv2/contract_submitter_test.go b/core/services/fluxmonitorv2/contract_submitter_test.go index 4c8ce019bfd..238cf96e033 100644 --- a/core/services/fluxmonitorv2/contract_submitter_test.go +++ b/core/services/fluxmonitorv2/contract_submitter_test.go @@ -19,7 +19,7 @@ func TestFluxAggregatorContractSubmitter_Submit(t *testing.T) { fluxAggregator = mocks.NewFluxAggregator(t) orm = fmmocks.NewORM(t) keyStore = fmmocks.NewKeyStoreInterface(t) - gasLimit = uint32(2100) + gasLimit = uint64(2100) forwardingAllowed = false submitter = fluxmonitorv2.NewFluxAggregatorContractSubmitter(fluxAggregator, orm, keyStore, gasLimit, forwardingAllowed, testutils.FixtureChainID) diff --git a/core/services/fluxmonitorv2/flux_monitor.go b/core/services/fluxmonitorv2/flux_monitor.go index f21e56cbc80..724c03daa91 100644 --- a/core/services/fluxmonitorv2/flux_monitor.go +++ b/core/services/fluxmonitorv2/flux_monitor.go @@ -188,9 +188,9 @@ func NewFromJobSpec( gasLimit := fcfg.LimitDefault() fmLimit := fcfg.LimitJobType().FM() if jobSpec.GasLimit.Valid { - gasLimit = jobSpec.GasLimit.Uint32 + gasLimit = uint64(jobSpec.GasLimit.Uint32) } else if fmLimit != nil { - gasLimit = *fmLimit + gasLimit = uint64(*fmLimit) } contractSubmitter := NewFluxAggregatorContractSubmitter( diff --git a/core/services/fluxmonitorv2/mocks/orm.go b/core/services/fluxmonitorv2/mocks/orm.go index 8d277d61d2e..287c7ebb5fa 100644 --- a/core/services/fluxmonitorv2/mocks/orm.go +++ b/core/services/fluxmonitorv2/mocks/orm.go @@ -48,7 +48,7 @@ func (_m *ORM) CountFluxMonitorRoundStats() (int, error) { } // CreateEthTransaction provides a mock function with given fields: ctx, fromAddress, toAddress, payload, gasLimit, idempotencyKey -func (_m *ORM) CreateEthTransaction(ctx context.Context, fromAddress common.Address, toAddress common.Address, payload []byte, gasLimit uint32, idempotencyKey *string) error { +func (_m *ORM) CreateEthTransaction(ctx context.Context, fromAddress common.Address, toAddress common.Address, payload []byte, gasLimit uint64, idempotencyKey *string) error { ret := _m.Called(ctx, fromAddress, toAddress, payload, gasLimit, idempotencyKey) if len(ret) == 0 { @@ -56,7 +56,7 @@ func (_m *ORM) CreateEthTransaction(ctx context.Context, fromAddress common.Addr } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, common.Address, common.Address, []byte, uint32, *string) error); ok { + if rf, ok := ret.Get(0).(func(context.Context, common.Address, common.Address, []byte, uint64, *string) error); ok { r0 = rf(ctx, fromAddress, toAddress, payload, gasLimit, idempotencyKey) } else { r0 = ret.Error(0) diff --git a/core/services/fluxmonitorv2/orm.go b/core/services/fluxmonitorv2/orm.go index f85ab146c7e..91973387e32 100644 --- a/core/services/fluxmonitorv2/orm.go +++ b/core/services/fluxmonitorv2/orm.go @@ -27,7 +27,7 @@ type ORM interface { DeleteFluxMonitorRoundsBackThrough(aggregator common.Address, roundID uint32) error FindOrCreateFluxMonitorRoundStats(aggregator common.Address, roundID uint32, newRoundLogs uint) (FluxMonitorRoundStatsV2, error) UpdateFluxMonitorRoundStats(aggregator common.Address, roundID uint32, runID int64, newRoundLogsAddition uint, qopts ...pg.QOpt) error - CreateEthTransaction(ctx context.Context, fromAddress, toAddress common.Address, payload []byte, gasLimit uint32, idempotencyKey *string) error + CreateEthTransaction(ctx context.Context, fromAddress, toAddress common.Address, payload []byte, gasLimit uint64, idempotencyKey *string) error CountFluxMonitorRoundStats() (count int, err error) } @@ -119,7 +119,7 @@ func (o *orm) CreateEthTransaction( fromAddress common.Address, toAddress common.Address, payload []byte, - gasLimit uint32, + gasLimit uint64, idempotencyKey *string, ) (err error) { diff --git a/core/services/fluxmonitorv2/orm_test.go b/core/services/fluxmonitorv2/orm_test.go index bcbec4363e2..17e03a674f0 100644 --- a/core/services/fluxmonitorv2/orm_test.go +++ b/core/services/fluxmonitorv2/orm_test.go @@ -180,7 +180,7 @@ func TestORM_CreateEthTransaction(t *testing.T) { _, from = cltest.MustInsertRandomKey(t, ethKeyStore) to = testutils.NewAddress() payload = []byte{1, 0, 0} - gasLimit = uint32(21000) + gasLimit = uint64(21000) ) idempotencyKey := uuid.New().String() txm.On("CreateTransaction", mock.Anything, txmgr.TxRequest{ diff --git a/core/services/keeper/upkeep_executer_test.go b/core/services/keeper/upkeep_executer_test.go index 1018d5f2aab..9b6d64c2e20 100644 --- a/core/services/keeper/upkeep_executer_test.go +++ b/core/services/keeper/upkeep_executer_test.go @@ -132,7 +132,7 @@ func Test_UpkeepExecuter_PerformsUpkeep_Happy(t *testing.T) { c.EVM[0].ChainID = (*ubig.Big)(testutils.SimulatedChainID) }) - gasLimit := 5_000_000 + config.Keeper().Registry().PerformGasOverhead() + gasLimit := uint64(5_000_000 + config.Keeper().Registry().PerformGasOverhead()) ethTxCreated := cltest.NewAwaiter() txm.On("CreateTransaction", @@ -177,7 +177,7 @@ func Test_UpkeepExecuter_PerformsUpkeep_Happy(t *testing.T) { c.EVM[0].ChainID = (*ubig.Big)(testutils.SimulatedChainID) }) - gasLimit := 5_000_000 + config.Keeper().Registry().PerformGasOverhead() + gasLimit := uint64(5_000_000 + config.Keeper().Registry().PerformGasOverhead()) ethTxCreated := cltest.NewAwaiter() txm.On("CreateTransaction", @@ -287,7 +287,7 @@ func Test_UpkeepExecuter_PerformsUpkeep_Happy(t *testing.T) { cltest.NewAwaiter(), cltest.NewAwaiter(), } - gasLimit := 5_000_000 + config.Keeper().Registry().PerformGasOverhead() + gasLimit := uint64(5_000_000 + config.Keeper().Registry().PerformGasOverhead()) txm.On("CreateTransaction", mock.Anything, mock.MatchedBy(func(txRequest txmgr.TxRequest) bool { return txRequest.FeeLimit == gasLimit }), diff --git a/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go index 7f562c9adb3..1216eec0a63 100644 --- a/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go +++ b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go @@ -337,7 +337,7 @@ func StartNewNode( c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(1 * time.Second) c.EVM[0].Transactions.ForwardersEnabled = ptr(false) - c.EVM[0].GasEstimator.LimitDefault = ptr(maxGas) + c.EVM[0].GasEstimator.LimitDefault = ptr(uint64(maxGas)) c.EVM[0].GasEstimator.Mode = ptr("FixedPrice") c.EVM[0].GasEstimator.PriceDefault = assets.NewWei(big.NewInt(int64(DefaultGasPrice))) diff --git a/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go b/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go index 8d50b8076bb..8a496355c40 100644 --- a/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go +++ b/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go @@ -246,7 +246,7 @@ func setupNodeOCR2( c.OCR2.Enabled = ptr(true) c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(500 * time.Millisecond) - c.EVM[0].GasEstimator.LimitDefault = ptr[uint32](3_500_000) + c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](3_500_000) c.EVM[0].Transactions.ForwardersEnabled = &useForwarders c.OCR2.ContractPollInterval = commonconfig.MustNewDuration(10 * time.Second) }) diff --git a/core/services/ocrcommon/transmitter.go b/core/services/ocrcommon/transmitter.go index 1c4173798ea..423db2316a7 100644 --- a/core/services/ocrcommon/transmitter.go +++ b/core/services/ocrcommon/transmitter.go @@ -27,7 +27,7 @@ type Transmitter interface { type transmitter struct { txm txManager fromAddresses []common.Address - gasLimit uint32 + gasLimit uint64 effectiveTransmitterAddress common.Address strategy types.TxStrategy checker txmgr.TransmitCheckerSpec @@ -39,7 +39,7 @@ type transmitter struct { func NewTransmitter( txm txManager, fromAddresses []common.Address, - gasLimit uint32, + gasLimit uint64, effectiveTransmitterAddress common.Address, strategy types.TxStrategy, checker txmgr.TransmitCheckerSpec, diff --git a/core/services/ocrcommon/transmitter_test.go b/core/services/ocrcommon/transmitter_test.go index d954da869bc..c56896ab2b9 100644 --- a/core/services/ocrcommon/transmitter_test.go +++ b/core/services/ocrcommon/transmitter_test.go @@ -31,7 +31,7 @@ func Test_DefaultTransmitter_CreateEthTransaction(t *testing.T) { _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) - gasLimit := uint32(1000) + gasLimit := uint64(1000) chainID := big.NewInt(0) effectiveTransmitterAddress := fromAddress toAddress := testutils.NewAddress() @@ -73,7 +73,7 @@ func Test_DefaultTransmitter_Forwarding_Enabled_CreateEthTransaction(t *testing. _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) _, fromAddress2 := cltest.MustInsertRandomKey(t, ethKeyStore) - gasLimit := uint32(1000) + gasLimit := uint64(1000) chainID := big.NewInt(0) effectiveTransmitterAddress := common.Address{} toAddress := testutils.NewAddress() @@ -124,7 +124,7 @@ func Test_DefaultTransmitter_Forwarding_Enabled_CreateEthTransaction_Round_Robin fromAddress := common.Address{} - gasLimit := uint32(1000) + gasLimit := uint64(1000) chainID := big.NewInt(0) effectiveTransmitterAddress := common.Address{} toAddress := testutils.NewAddress() @@ -156,7 +156,7 @@ func Test_DefaultTransmitter_Forwarding_Enabled_CreateEthTransaction_No_Keystore _, fromAddress := cltest.MustInsertRandomKey(t, ethKeyStore) _, fromAddress2 := cltest.MustInsertRandomKey(t, ethKeyStore) - gasLimit := uint32(1000) + gasLimit := uint64(1000) chainID := big.NewInt(0) effectiveTransmitterAddress := common.Address{} txm := txmmocks.NewMockEvmTxManager(t) diff --git a/core/services/pipeline/common.go b/core/services/pipeline/common.go index 6e7ad1e7e4e..a07319643c3 100644 --- a/core/services/pipeline/common.go +++ b/core/services/pipeline/common.go @@ -560,9 +560,9 @@ func CheckInputs(inputs []Result, minLen, maxLen, maxErrors int) ([]interface{}, var ErrInvalidEVMChainID = errors.New("invalid EVM chain ID") -func SelectGasLimit(ge config.GasEstimator, jobType string, specGasLimit *uint32) uint32 { +func SelectGasLimit(ge config.GasEstimator, jobType string, specGasLimit *uint32) uint64 { if specGasLimit != nil { - return *specGasLimit + return uint64(*specGasLimit) } jt := ge.LimitJobType() @@ -583,7 +583,7 @@ func SelectGasLimit(ge config.GasEstimator, jobType string, specGasLimit *uint32 } if jobTypeGasLimit != nil { - return *jobTypeGasLimit + return uint64(*jobTypeGasLimit) } return ge.LimitDefault() } diff --git a/core/services/pipeline/common_test.go b/core/services/pipeline/common_test.go index 7da80d3af47..ea3f4d90c3b 100644 --- a/core/services/pipeline/common_test.go +++ b/core/services/pipeline/common_test.go @@ -324,7 +324,7 @@ func TestSelectGasLimit(t *testing.T) { t.Parallel() gcfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].GasEstimator.LimitDefault = ptr(uint32(999)) + c.EVM[0].GasEstimator.LimitDefault = ptr(uint64(999)) c.EVM[0].GasEstimator.LimitJobType = toml.GasLimitJobType{ DR: ptr(uint32(100)), VRF: ptr(uint32(101)), @@ -339,42 +339,42 @@ func TestSelectGasLimit(t *testing.T) { t.Run("spec defined gas limit", func(t *testing.T) { var specGasLimit uint32 = 1 gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.DirectRequestJobType, &specGasLimit) - assert.Equal(t, uint32(1), gasLimit) + assert.Equal(t, uint64(1), gasLimit) }) t.Run("direct request specific gas limit", func(t *testing.T) { gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.DirectRequestJobType, nil) - assert.Equal(t, uint32(100), gasLimit) + assert.Equal(t, uint64(100), gasLimit) }) t.Run("OCR specific gas limit", func(t *testing.T) { gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.OffchainReportingJobType, nil) - assert.Equal(t, uint32(103), gasLimit) + assert.Equal(t, uint64(103), gasLimit) }) t.Run("OCR2 specific gas limit", func(t *testing.T) { gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.OffchainReporting2JobType, nil) - assert.Equal(t, uint32(105), gasLimit) + assert.Equal(t, uint64(105), gasLimit) }) t.Run("VRF specific gas limit", func(t *testing.T) { gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.VRFJobType, nil) - assert.Equal(t, uint32(101), gasLimit) + assert.Equal(t, uint64(101), gasLimit) }) t.Run("flux monitor specific gas limit", func(t *testing.T) { gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.FluxMonitorJobType, nil) - assert.Equal(t, uint32(102), gasLimit) + assert.Equal(t, uint64(102), gasLimit) }) t.Run("keeper specific gas limit", func(t *testing.T) { gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.KeeperJobType, nil) - assert.Equal(t, uint32(104), gasLimit) + assert.Equal(t, uint64(104), gasLimit) }) t.Run("fallback to default gas limit", func(t *testing.T) { gasLimit := pipeline.SelectGasLimit(cfg.EVM().GasEstimator(), pipeline.WebhookJobType, nil) - assert.Equal(t, uint32(999), gasLimit) + assert.Equal(t, uint64(999), gasLimit) }) } func TestGetNextTaskOf(t *testing.T) { diff --git a/core/services/pipeline/task.estimategas.go b/core/services/pipeline/task.estimategas.go index 8fccc5e8eac..54be6273057 100644 --- a/core/services/pipeline/task.estimategas.go +++ b/core/services/pipeline/task.estimategas.go @@ -123,7 +123,7 @@ func (t *EstimateGasLimitTask) Run(ctx context.Context, lggr logger.Logger, vars if !gasLimitWithMultiplier.IsUint64() { return Result{Error: ErrInvalidMultiplier}, retryableRunInfo() } - gasLimitFinal := uint32(gasLimitWithMultiplier.Uint64()) + gasLimitFinal := gasLimitWithMultiplier.Uint64() if gasLimitFinal > maximumGasLimit { lggr.Warnw("EstimateGas: estimated amount is greater than configured limit, fallback to configured limit", "estimate", gasLimitFinal, diff --git a/core/services/pipeline/task.eth_call.go b/core/services/pipeline/task.eth_call.go index f011cd7a9b6..a3e95c3cfc1 100644 --- a/core/services/pipeline/task.eth_call.go +++ b/core/services/pipeline/task.eth_call.go @@ -106,14 +106,14 @@ func (t *ETHCallTask) Run(ctx context.Context, lggr logger.Logger, vars Vars, in return Result{Error: err}, runInfo } - var selectedGas uint32 + var selectedGas uint64 if gasUnlimited { if gas > 0 { return Result{Error: errors.Wrapf(ErrBadInput, "gas must be zero when gasUnlimited is true")}, runInfo } } else { if gas > 0 { - selectedGas = uint32(gas) + selectedGas = uint64(gas) } else { selectedGas = SelectGasLimit(chain.Config().EVM().GasEstimator(), t.jobType, t.specGasLimit) } @@ -123,7 +123,7 @@ func (t *ETHCallTask) Run(ctx context.Context, lggr logger.Logger, vars Vars, in To: (*common.Address)(&contractAddr), From: (common.Address)(from), Data: []byte(data), - Gas: uint64(selectedGas), + Gas: selectedGas, GasPrice: gasPrice.BigInt(), GasTipCap: gasTipCap.BigInt(), GasFeeCap: gasFeeCap.BigInt(), diff --git a/core/services/pipeline/task.eth_call_test.go b/core/services/pipeline/task.eth_call_test.go index 28af94ba25c..b21b3065f8c 100644 --- a/core/services/pipeline/task.eth_call_test.go +++ b/core/services/pipeline/task.eth_call_test.go @@ -33,7 +33,7 @@ func TestETHCallTask(t *testing.T) { testutils.SkipShortDB(t) var specGasLimit uint32 = 123 - const gasLimit uint32 = 500_000 + const gasLimit uint64 = 500_000 const drJobTypeGasLimit uint32 = 789 tests := []struct { diff --git a/core/services/pipeline/task.eth_tx.go b/core/services/pipeline/task.eth_tx.go index ffd496c486d..354651acbb4 100644 --- a/core/services/pipeline/task.eth_tx.go +++ b/core/services/pipeline/task.eth_tx.go @@ -150,7 +150,7 @@ func (t *ETHTxTask) Run(ctx context.Context, lggr logger.Logger, vars Vars, inpu FromAddress: fromAddr, ToAddress: common.Address(toAddr), EncodedPayload: []byte(data), - FeeLimit: uint32(gasLimit), + FeeLimit: uint64(gasLimit), Meta: txMeta, ForwarderAddress: forwarderAddress, Strategy: strategy, diff --git a/core/services/pipeline/task.eth_tx_test.go b/core/services/pipeline/task.eth_tx_test.go index d50949e120d..c38c338df20 100644 --- a/core/services/pipeline/task.eth_tx_test.go +++ b/core/services/pipeline/task.eth_tx_test.go @@ -31,7 +31,7 @@ func TestETHTxTask(t *testing.T) { reqID := common.HexToHash("0x5198616554d738d9485d1a7cf53b2f33e09c3bbc8fe9ac0020bd672cd2bc15d2") reqTxHash := common.HexToHash("0xc524fafafcaec40652b1f84fca09c231185437d008d195fccf2f51e64b7062f8") specGasLimit := uint32(123) - const defaultGasLimit uint32 = 999 + const defaultGasLimit uint64 = 999 const drJobTypeGasLimit uint32 = 789 from := common.HexToAddress("0x882969652440ccf14a5dbb9bd53eb21cb1e11e5c") @@ -74,7 +74,7 @@ func TestETHTxTask(t *testing.T) { func(keyStore *keystoremocks.Eth, txManager *txmmocks.MockEvmTxManager) { data := []byte("foobar") - gasLimit := uint32(12345) + gasLimit := uint64(12345) jobID := int32(321) addr := common.HexToAddress("0x2E396ecbc8223Ebc16EC45136228AE5EDB649943") txMeta := &txmgr.TxMeta{ @@ -124,7 +124,7 @@ func TestETHTxTask(t *testing.T) { nil, func(keyStore *keystoremocks.Eth, txManager *txmmocks.MockEvmTxManager) { data := []byte("foobar") - gasLimit := uint32(12345) + gasLimit := uint64(12345) txMeta := &txmgr.TxMeta{ JobID: &jid, RequestID: &reqID, @@ -202,7 +202,7 @@ func TestETHTxTask(t *testing.T) { nil, func(keyStore *keystoremocks.Eth, txManager *txmmocks.MockEvmTxManager) { data := []byte("foobar") - gasLimit := uint32(12345) + gasLimit := uint64(12345) txMeta := &txmgr.TxMeta{ JobID: &jid, RequestID: &reqID, @@ -248,7 +248,7 @@ func TestETHTxTask(t *testing.T) { nil, func(keyStore *keystoremocks.Eth, txManager *txmmocks.MockEvmTxManager) { data := []byte("foobar") - gasLimit := uint32(12345) + gasLimit := uint64(12345) txMeta := &txmgr.TxMeta{ JobID: &jid, RequestID: &reqID, @@ -284,7 +284,7 @@ func TestETHTxTask(t *testing.T) { nil, func(keyStore *keystoremocks.Eth, txManager *txmmocks.MockEvmTxManager) { data := []byte("foobar") - gasLimit := uint32(12345) + gasLimit := uint64(12345) txMeta := &txmgr.TxMeta{FailOnRevert: null.BoolFrom(false)} keyStore.On("GetRoundRobinAddress", mock.Anything, testutils.FixtureChainID, from).Return(from, nil) txManager.On("CreateTransaction", mock.Anything, txmgr.TxRequest{ @@ -326,7 +326,7 @@ func TestETHTxTask(t *testing.T) { FromAddress: from, ToAddress: to, EncodedPayload: data, - FeeLimit: drJobTypeGasLimit, + FeeLimit: uint64(drJobTypeGasLimit), Meta: txMeta, Strategy: txmgrcommon.NewSendEveryStrategy(), SignalCallback: true, @@ -361,7 +361,7 @@ func TestETHTxTask(t *testing.T) { FromAddress: from, ToAddress: to, EncodedPayload: data, - FeeLimit: specGasLimit, + FeeLimit: uint64(specGasLimit), Meta: txMeta, Strategy: txmgrcommon.NewSendEveryStrategy(), SignalCallback: true, @@ -415,7 +415,7 @@ func TestETHTxTask(t *testing.T) { nil, func(keyStore *keystoremocks.Eth, txManager *txmmocks.MockEvmTxManager) { data := []byte("foobar") - gasLimit := uint32(12345) + gasLimit := uint64(12345) txMeta := &txmgr.TxMeta{ JobID: &jid, RequestID: &reqID, diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index a02885cb556..94d971b61e0 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -498,10 +498,10 @@ func newOnChainContractTransmitter(ctx context.Context, lggr logger.Logger, rarg gasLimit := configWatcher.chain.Config().EVM().GasEstimator().LimitDefault() ocr2Limit := configWatcher.chain.Config().EVM().GasEstimator().LimitJobType().OCR2() if ocr2Limit != nil { - gasLimit = *ocr2Limit + gasLimit = uint64(*ocr2Limit) } if opts.pluginGasLimit != nil { - gasLimit = *opts.pluginGasLimit + gasLimit = uint64(*opts.pluginGasLimit) } transmitter, err := ocrcommon.NewTransmitter( diff --git a/core/services/relay/evm/functions.go b/core/services/relay/evm/functions.go index c10134f3acc..41d9f93c5aa 100644 --- a/core/services/relay/evm/functions.go +++ b/core/services/relay/evm/functions.go @@ -194,7 +194,7 @@ func newFunctionsContractTransmitter(ctx context.Context, contractVersion uint32 gasLimit := configWatcher.chain.Config().EVM().GasEstimator().LimitDefault() ocr2Limit := configWatcher.chain.Config().EVM().GasEstimator().LimitJobType().OCR2() if ocr2Limit != nil { - gasLimit = *ocr2Limit + gasLimit = uint64(*ocr2Limit) } transmitter, err := ocrcommon.NewTransmitter( diff --git a/core/services/vrf/mocks/fee_config.go b/core/services/vrf/mocks/fee_config.go index 2f33415b338..ee7ea4e9a58 100644 --- a/core/services/vrf/mocks/fee_config.go +++ b/core/services/vrf/mocks/fee_config.go @@ -17,18 +17,18 @@ type FeeConfig struct { } // LimitDefault provides a mock function with given fields: -func (_m *FeeConfig) LimitDefault() uint32 { +func (_m *FeeConfig) LimitDefault() uint64 { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for LimitDefault") } - var r0 uint32 - if rf, ok := ret.Get(0).(func() uint32); ok { + var r0 uint64 + if rf, ok := ret.Get(0).(func() uint64); ok { r0 = rf() } else { - r0 = ret.Get(0).(uint32) + r0 = ret.Get(0).(uint64) } return r0 diff --git a/core/services/vrf/v2/bhs_feeder_test.go b/core/services/vrf/v2/bhs_feeder_test.go index 6f857c80834..0ce674f5168 100644 --- a/core/services/vrf/v2/bhs_feeder_test.go +++ b/core/services/vrf/v2/bhs_feeder_test.go @@ -57,7 +57,7 @@ func TestStartHeartbeats(t *testing.T) { c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) c.Feature.LogPoller = ptr(true) c.EVM[0].FinalityDepth = ptr[uint32](2) - c.EVM[0].GasEstimator.LimitDefault = ptr(uint32(gasLimit)) + c.EVM[0].GasEstimator.LimitDefault = ptr(uint64(gasLimit)) c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(time.Second) }) diff --git a/core/services/vrf/v2/integration_helpers_test.go b/core/services/vrf/v2/integration_helpers_test.go index 6649b5972e0..71724b928c1 100644 --- a/core/services/vrf/v2/integration_helpers_test.go +++ b/core/services/vrf/v2/integration_helpers_test.go @@ -356,7 +356,7 @@ func testMultipleConsumersNeedTrustedBHS( config, db := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { simulatedOverrides(t, assets.GWei(10), keySpecificOverrides...)(c, s) c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) - c.EVM[0].GasEstimator.LimitDefault = ptr(uint32(5_000_000)) + c.EVM[0].GasEstimator.LimitDefault = ptr(uint64(5_000_000)) c.Feature.LogPoller = ptr(true) c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(1 * time.Second) c.EVM[0].FinalityDepth = ptr[uint32](2) @@ -541,7 +541,7 @@ func testSingleConsumerHappyPathBatchFulfillment( Key: ptr(key1.EIP55Address), GasEstimator: toml.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, })(c, s) - c.EVM[0].GasEstimator.LimitDefault = ptr[uint32](5_000_000) + c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](5_000_000) c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) c.EVM[0].ChainID = (*ubig.Big)(testutils.SimulatedChainID) c.Feature.LogPoller = ptr(true) @@ -1074,7 +1074,7 @@ func testSingleConsumerEIP150( Key: ptr(key1.EIP55Address), GasEstimator: v2.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, })(c, s) - c.EVM[0].GasEstimator.LimitDefault = ptr(uint32(3.5e6)) + c.EVM[0].GasEstimator.LimitDefault = ptr(uint64(3.5e6)) c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) c.Feature.LogPoller = ptr(true) c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(1 * time.Second) @@ -1144,7 +1144,7 @@ func testSingleConsumerEIP150Revert( Key: ptr(key1.EIP55Address), GasEstimator: v2.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, })(c, s) - c.EVM[0].GasEstimator.LimitDefault = ptr(uint32(gasLimit)) + c.EVM[0].GasEstimator.LimitDefault = ptr(uint64(gasLimit)) c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) c.Feature.LogPoller = ptr(true) c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(1 * time.Second) @@ -1209,7 +1209,7 @@ func testSingleConsumerBigGasCallbackSandwich( Key: ptr(key1.EIP55Address), GasEstimator: v2.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, })(c, s) - c.EVM[0].GasEstimator.LimitDefault = ptr[uint32](5_000_000) + c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](5_000_000) c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) c.Feature.LogPoller = ptr(true) c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(1 * time.Second) @@ -1332,7 +1332,7 @@ func testSingleConsumerMultipleGasLanes( GasEstimator: v2.KeySpecificGasEstimator{PriceMax: expensiveGasLane}, })(c, s) c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) - c.EVM[0].GasEstimator.LimitDefault = ptr[uint32](5_000_000) + c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](5_000_000) c.Feature.LogPoller = ptr(true) c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(1 * time.Second) }) @@ -1644,7 +1644,7 @@ func testMaliciousConsumer( vrfVersion vrfcommon.Version, ) { config, _ := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.EVM[0].GasEstimator.LimitDefault = ptr[uint32](2_000_000) + c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](2_000_000) c.EVM[0].GasEstimator.PriceMax = assets.GWei(1) c.EVM[0].GasEstimator.PriceDefault = assets.GWei(1) c.EVM[0].GasEstimator.FeeCapDefault = assets.GWei(1) diff --git a/core/services/vrf/v2/integration_v2_plus_test.go b/core/services/vrf/v2/integration_v2_plus_test.go index 9d89911f0f2..22b10b61c84 100644 --- a/core/services/vrf/v2/integration_v2_plus_test.go +++ b/core/services/vrf/v2/integration_v2_plus_test.go @@ -1151,7 +1151,7 @@ func TestVRFV2PlusIntegration_Migration(t *testing.T) { Key: ptr(key1.EIP55Address), GasEstimator: toml.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, })(c, s) - c.EVM[0].GasEstimator.LimitDefault = ptr[uint32](5_000_000) + c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](5_000_000) c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) c.Feature.LogPoller = ptr(true) c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(1 * time.Second) diff --git a/core/services/vrf/v2/integration_v2_test.go b/core/services/vrf/v2/integration_v2_test.go index 18be6d8e408..3b7cdfa0a62 100644 --- a/core/services/vrf/v2/integration_v2_test.go +++ b/core/services/vrf/v2/integration_v2_test.go @@ -1012,7 +1012,7 @@ func testEoa( Key: ptr(key1.EIP55Address), GasEstimator: toml.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, })(c, s) - c.EVM[0].GasEstimator.LimitDefault = ptr(uint32(gasLimit)) + c.EVM[0].GasEstimator.LimitDefault = ptr(uint64(gasLimit)) c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) c.EVM[0].FinalityDepth = ptr(finalityDepth) }) @@ -1173,7 +1173,7 @@ func TestVRFV2Integration_SingleConsumer_Wrapper(t *testing.T) { Key: ptr(key1.EIP55Address), GasEstimator: toml.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, })(c, s) - c.EVM[0].GasEstimator.LimitDefault = ptr[uint32](3_500_000) + c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](3_500_000) c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) }) ownerKey := cltest.MustGenerateRandomKey(t) @@ -1253,7 +1253,7 @@ func TestVRFV2Integration_Wrapper_High_Gas(t *testing.T) { Key: ptr(key1.EIP55Address), GasEstimator: toml.KeySpecificGasEstimator{PriceMax: gasLanePriceWei}, })(c, s) - c.EVM[0].GasEstimator.LimitDefault = ptr[uint32](3_500_000) + c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](3_500_000) c.EVM[0].MinIncomingConfirmations = ptr[uint32](2) c.Feature.LogPoller = ptr(true) c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(1 * time.Second) @@ -1492,7 +1492,7 @@ func simulatedOverrides(t *testing.T, defaultGasPrice *assets.Wei, ks ...toml.Ke if defaultGasPrice != nil { c.EVM[0].GasEstimator.PriceDefault = defaultGasPrice } - c.EVM[0].GasEstimator.LimitDefault = ptr[uint32](3_500_000) + c.EVM[0].GasEstimator.LimitDefault = ptr[uint64](3_500_000) c.Feature.LogPoller = ptr(true) c.EVM[0].LogPollInterval = commonconfig.MustNewDuration(1 * time.Second) @@ -2178,7 +2178,7 @@ func TestStartingCountsV1(t *testing.T) { BroadcastBeforeBlockNum: &broadcastBlock, State: txmgrtypes.TxAttemptBroadcast, CreatedAt: time.Now(), - ChainSpecificFeeLimit: uint32(100), + ChainSpecificFeeLimit: uint64(100), }) } // add tx attempt for unconfirmed @@ -2190,7 +2190,7 @@ func TestStartingCountsV1(t *testing.T) { Hash: evmutils.NewHash(), State: txmgrtypes.TxAttemptInProgress, CreatedAt: time.Now(), - ChainSpecificFeeLimit: uint32(100), + ChainSpecificFeeLimit: uint64(100), }) } for _, txAttempt := range txAttempts { diff --git a/core/services/vrf/v2/listener_v2.go b/core/services/vrf/v2/listener_v2.go index cb87921e86b..71c6e72a06f 100644 --- a/core/services/vrf/v2/listener_v2.go +++ b/core/services/vrf/v2/listener_v2.go @@ -170,11 +170,11 @@ func (lsn *listenerV2) Start(ctx context.Context) error { gasLimit := lsn.feeCfg.LimitDefault() vrfLimit := lsn.feeCfg.LimitJobType().VRF() if vrfLimit != nil { - gasLimit = *vrfLimit + gasLimit = uint64(*vrfLimit) } if err != nil { lsn.l.Criticalw("Error getting coordinator config for gas limit check, starting anyway.", "err", err) - } else if conf.MaxGasLimit()+(GasProofVerification*2) > gasLimit { + } else if uint64(conf.MaxGasLimit()+(GasProofVerification*2)) > gasLimit { lsn.l.Criticalw("Node gas limit setting may not be high enough to fulfill all requests; it should be increased. Starting anyway.", "currentGasLimit", gasLimit, "neededGasLimit", conf.MaxGasLimit()+(GasProofVerification*2), diff --git a/core/services/vrf/v2/listener_v2_log_processor.go b/core/services/vrf/v2/listener_v2_log_processor.go index 7f61dd4cf3e..db84fb47e3e 100644 --- a/core/services/vrf/v2/listener_v2_log_processor.go +++ b/core/services/vrf/v2/listener_v2_log_processor.go @@ -591,8 +591,8 @@ func (lsn *listenerV2) enqueueForceFulfillment( lsn.l.Infow("Estimated gas limit on force fulfillment", "estimateGasLimit", estimateGasLimit, "pipelineGasLimit", p.gasLimit) - if estimateGasLimit < uint64(p.gasLimit) { - estimateGasLimit = uint64(p.gasLimit) + if estimateGasLimit < p.gasLimit { + estimateGasLimit = p.gasLimit } requestID := common.BytesToHash(p.req.req.RequestID().Bytes()) @@ -602,7 +602,7 @@ func (lsn *listenerV2) enqueueForceFulfillment( FromAddress: fromAddress, ToAddress: lsn.vrfOwner.Address(), EncodedPayload: txData, - FeeLimit: uint32(estimateGasLimit), + FeeLimit: estimateGasLimit, Strategy: txmgrcommon.NewSendEveryStrategy(), Meta: &txmgr.TxMeta{ RequestID: &requestID, @@ -1205,7 +1205,7 @@ func (lsn *listenerV2) simulateFulfillment( } if trr.Task.Type() == pipeline.TaskTypeEstimateGasLimit { - res.gasLimit = trr.Result.Value.(uint32) + res.gasLimit = trr.Result.Value.(uint64) } } return res diff --git a/core/services/vrf/v2/listener_v2_types.go b/core/services/vrf/v2/listener_v2_types.go index b3cbbff4713..f10297f31a9 100644 --- a/core/services/vrf/v2/listener_v2_types.go +++ b/core/services/vrf/v2/listener_v2_types.go @@ -72,7 +72,7 @@ type vrfPipelineResult struct { fundsNeeded *big.Int run *pipeline.Run payload string - gasLimit uint32 + gasLimit uint64 req pendingRequest proof VRFProof reqCommitment RequestCommitment @@ -83,7 +83,7 @@ type vrfPipelineResult struct { type batchFulfillment struct { proofs []VRFProof commitments []RequestCommitment - totalGasLimit uint32 + totalGasLimit uint64 runs []*pipeline.Run reqIDs []*big.Int maxFees []*big.Int @@ -144,7 +144,7 @@ func (b *batchFulfillments) addRun(result vrfPipelineResult, fromAddress common. b.fulfillments = append(b.fulfillments, newBatchFulfillment(result, fromAddress, b.version)) } else { currBatch := b.fulfillments[b.currIndex] - if (currBatch.totalGasLimit + result.gasLimit) >= b.batchGasLimit { + if (currBatch.totalGasLimit + result.gasLimit) >= uint64(b.batchGasLimit) { // don't add to curr batch, add new batch and increment index b.fulfillments = append(b.fulfillments, newBatchFulfillment(result, fromAddress, b.version)) b.currIndex++ @@ -240,7 +240,7 @@ func (lsn *listenerV2) processBatch( FromAddress: fromAddress, ToAddress: lsn.batchCoordinator.Address(), EncodedPayload: payload, - FeeLimit: totalGasLimitBumped, + FeeLimit: uint64(totalGasLimitBumped), Strategy: txmgrcommon.NewSendEveryStrategy(), Meta: &txmgr.TxMeta{ RequestIDs: reqIDHashes, diff --git a/core/services/vrf/v2/listener_v2_types_test.go b/core/services/vrf/v2/listener_v2_types_test.go index c66270210b9..3ca76fb70d2 100644 --- a/core/services/vrf/v2/listener_v2_types_test.go +++ b/core/services/vrf/v2/listener_v2_types_test.go @@ -35,7 +35,7 @@ func Test_BatchFulfillments_AddRun(t *testing.T) { require.Len(t, bfs.fulfillments, 1) } - require.Equal(t, uint32(2000), bfs.fulfillments[0].totalGasLimit) + require.Equal(t, uint64(2000), bfs.fulfillments[0].totalGasLimit) // This addition should create and add a new batch bfs.addRun(vrfPipelineResult{ @@ -73,7 +73,7 @@ func Test_BatchFulfillments_AddRun_V2Plus(t *testing.T) { require.Len(t, bfs.fulfillments, 1) } - require.Equal(t, uint32(2000), bfs.fulfillments[0].totalGasLimit) + require.Equal(t, uint64(2000), bfs.fulfillments[0].totalGasLimit) // This addition should create and add a new batch bfs.addRun(vrfPipelineResult{ diff --git a/core/services/vrf/v2/reverted_txns.go b/core/services/vrf/v2/reverted_txns.go index be20738a8f5..d2f62fbf271 100644 --- a/core/services/vrf/v2/reverted_txns.go +++ b/core/services/vrf/v2/reverted_txns.go @@ -707,7 +707,7 @@ func (lsn *listenerV2) enqueueForceFulfillmentForRevertedTxn( FromAddress: fromAddress, ToAddress: lsn.vrfOwner.Address(), EncodedPayload: txData, - FeeLimit: uint32(estimateGasLimit), + FeeLimit: estimateGasLimit, Strategy: txmgrcommon.NewSendEveryStrategy(), Meta: &txmgr.TxMeta{ RequestID: &reqID, diff --git a/core/services/vrf/vrfcommon/types.go b/core/services/vrf/vrfcommon/types.go index 06988633e8e..a27fcd5beb8 100644 --- a/core/services/vrf/vrfcommon/types.go +++ b/core/services/vrf/vrfcommon/types.go @@ -22,7 +22,7 @@ type Config interface { //go:generate mockery --quiet --name FeeConfig --output ../mocks/ --case=underscore type FeeConfig interface { - LimitDefault() uint32 + LimitDefault() uint64 LimitJobType() config.LimitJobType PriceMaxKey(addr common.Address) *assets.Wei } diff --git a/core/web/eth_keys_controller_test.go b/core/web/eth_keys_controller_test.go index 545abefcd3e..94d92849887 100644 --- a/core/web/eth_keys_controller_test.go +++ b/core/web/eth_keys_controller_test.go @@ -409,7 +409,7 @@ func TestETHKeysController_ChainSuccess_ResetWithAbandon(t *testing.T) { FromAddress: addr, ToAddress: testutils.NewAddress(), EncodedPayload: []byte{1, 2, 3}, - FeeLimit: uint32(1000), + FeeLimit: uint64(1000), Meta: nil, Strategy: strategy, }) diff --git a/core/web/evm_transfer_controller.go b/core/web/evm_transfer_controller.go index 4a1bf46feea..26f199ed961 100644 --- a/core/web/evm_transfer_controller.go +++ b/core/web/evm_transfer_controller.go @@ -113,7 +113,7 @@ func ValidateEthBalanceForTransfer(c *gin.Context, chain legacyevm.Chain, fromAd return errors.Errorf("balance is too low for this transaction to be executed: %v", balance) } - gasLimit := chain.Config().EVM().GasEstimator().LimitTransfer() + gasLimit := uint64(chain.Config().EVM().GasEstimator().LimitTransfer()) estimator := chain.GasEstimator() amountWithFees, err := estimator.GetMaxCost(c, amount, nil, gasLimit, chain.Config().EVM().GasEstimator().PriceMaxKey(fromAddr)) diff --git a/core/web/presenters/eth_tx.go b/core/web/presenters/eth_tx.go index 65df01ef095..e1ba3664a8f 100644 --- a/core/web/presenters/eth_tx.go +++ b/core/web/presenters/eth_tx.go @@ -43,7 +43,7 @@ func NewEthTxResource(tx txmgr.Tx) EthTxResource { r := EthTxResource{ Data: hexutil.Bytes(tx.EncodedPayload), From: &tx.FromAddress, - GasLimit: strconv.FormatUint(uint64(tx.FeeLimit), 10), + GasLimit: strconv.FormatUint(tx.FeeLimit, 10), State: string(tx.State), To: &tx.ToAddress, Value: v.String(), diff --git a/core/web/presenters/eth_tx_test.go b/core/web/presenters/eth_tx_test.go index 193fa774ce9..3bcdab5edfb 100644 --- a/core/web/presenters/eth_tx_test.go +++ b/core/web/presenters/eth_tx_test.go @@ -26,7 +26,7 @@ func TestEthTxResource(t *testing.T) { EncodedPayload: []byte(`{"data": "is wilding out"}`), FromAddress: common.HexToAddress("0x1"), ToAddress: common.HexToAddress("0x2"), - FeeLimit: uint32(5000), + FeeLimit: uint64(5000), ChainID: chainID, State: txmgrcommon.TxConfirmed, Value: big.Int(assets.NewEthValue(1)), diff --git a/integration-tests/types/config/node/core.go b/integration-tests/types/config/node/core.go index 3508f77555f..024a05f63e4 100644 --- a/integration-tests/types/config/node/core.go +++ b/integration-tests/types/config/node/core.go @@ -188,7 +188,7 @@ func WithPrivateEVMs(networks []blockchain.EVMNetwork) NodeConfigOpt { HistoryDepth: ptr.Ptr(uint32(100)), }, GasEstimator: evmcfg.GasEstimator{ - LimitDefault: ptr.Ptr(uint32(6000000)), + LimitDefault: ptr.Ptr(uint64(6000000)), PriceMax: assets.GWei(200), FeeCapDefault: assets.GWei(200), }, @@ -223,7 +223,7 @@ func WithVRFv2EVMEstimator(addresses []string, maxGasPriceGWei int64) NodeConfig return func(c *chainlink.Config) { c.EVM[0].KeySpecific = keySpecicifArr c.EVM[0].Chain.GasEstimator = evmcfg.GasEstimator{ - LimitDefault: ptr.Ptr[uint32](3500000), + LimitDefault: ptr.Ptr[uint64](3500000), } c.EVM[0].Chain.Transactions = evmcfg.Transactions{ MaxQueued: ptr.Ptr[uint32](10000), From ad0817fd82bab2f13932a8e474ee135d7317cb6f Mon Sep 17 00:00:00 2001 From: Dimitris Grigoriou Date: Thu, 7 Mar 2024 01:58:53 +0200 Subject: [PATCH 28/34] Downgrade unknown transaction log message (#12297) --- core/chains/evm/gas/block_history_estimator.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/chains/evm/gas/block_history_estimator.go b/core/chains/evm/gas/block_history_estimator.go index aae8d043ccd..fcd0d627063 100644 --- a/core/chains/evm/gas/block_history_estimator.go +++ b/core/chains/evm/gas/block_history_estimator.go @@ -864,7 +864,7 @@ func (b *BlockHistoryEstimator) EffectiveGasPrice(block evmtypes.Block, tx evmty case 0x2, 0x3: return b.getEffectiveGasPrice(block, tx) default: - b.logger.Warnw(fmt.Sprintf("Ignoring unknown transaction type %v", tx.Type), "block", block, "tx", tx) + b.logger.Debugw(fmt.Sprintf("Ignoring unknown transaction type %v", tx.Type), "block", block, "tx", tx) return nil } } @@ -916,7 +916,7 @@ func (b *BlockHistoryEstimator) EffectiveTipCap(block evmtypes.Block, tx evmtype } return effectiveTipCap default: - b.logger.Warnw(fmt.Sprintf("Ignoring unknown transaction type %v", tx.Type), "block", block, "tx", tx) + b.logger.Debugw(fmt.Sprintf("Ignoring unknown transaction type %v", tx.Type), "block", block, "tx", tx) return nil } } From 3934c7a3aa1863a17d41d42eba4207fd55a7754a Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Wed, 6 Mar 2024 22:15:10 -0500 Subject: [PATCH 29/34] remove unused registrar 2_2 (#12322) --- .../native_solc_compile_all_automation | 1 - .../dev/v2_2/AutomationRegistrar2_2.sol | 535 --------- .../automation/AutomationRegistrar2_2.test.ts | 1013 ----------------- ...rapper-dependency-versions-do-not-edit.txt | 1 - core/gethwrappers/go_generate.go | 1 - 5 files changed, 1551 deletions(-) delete mode 100644 contracts/src/v0.8/automation/dev/v2_2/AutomationRegistrar2_2.sol delete mode 100644 contracts/test/v0.8/automation/AutomationRegistrar2_2.test.ts diff --git a/contracts/scripts/native_solc_compile_all_automation b/contracts/scripts/native_solc_compile_all_automation index 248462f421a..cbb78a2cb40 100755 --- a/contracts/scripts/native_solc_compile_all_automation +++ b/contracts/scripts/native_solc_compile_all_automation @@ -86,7 +86,6 @@ solc-select use $SOLC_VERSION export SOLC_VERSION=$SOLC_VERSION # v0.8.19 -compileContract automation/dev/v2_2/AutomationRegistrar2_2.sol compileContract automation/dev/v2_2/AutomationRegistry2_2.sol compileContract automation/dev/v2_2/AutomationRegistryLogicA2_2.sol compileContract automation/dev/v2_2/AutomationRegistryLogicB2_2.sol diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistrar2_2.sol b/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistrar2_2.sol deleted file mode 100644 index 8d2fe775ee8..00000000000 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistrar2_2.sol +++ /dev/null @@ -1,535 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.19; - -import {LinkTokenInterface} from "../../../shared/interfaces/LinkTokenInterface.sol"; -import {IAutomationRegistryMaster} from "../interfaces/v2_2/IAutomationRegistryMaster.sol"; -import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol"; -import {ConfirmedOwner} from "../../../shared/access/ConfirmedOwner.sol"; -import {IERC677Receiver} from "../../../shared/interfaces/IERC677Receiver.sol"; - -/** - * @notice Contract to accept requests for upkeep registrations - * @dev There are 2 registration workflows in this contract - * Flow 1. auto approve OFF / manual registration - UI calls `register` function on this contract, this contract owner at a later time then manually - * calls `approve` to register upkeep and emit events to inform UI and others interested. - * Flow 2. auto approve ON / real time registration - UI calls `register` function as before, which calls the `registerUpkeep` function directly on - * keeper registry and then emits approved event to finish the flow automatically without manual intervention. - * The idea is to have same interface(functions,events) for UI or anyone using this contract irrespective of auto approve being enabled or not. - * they can just listen to `RegistrationRequested` & `RegistrationApproved` events and know the status on registrations. - */ -contract AutomationRegistrar2_2 is TypeAndVersionInterface, ConfirmedOwner, IERC677Receiver { - /** - * DISABLED: No auto approvals, all new upkeeps should be approved manually. - * ENABLED_SENDER_ALLOWLIST: Auto approvals for allowed senders subject to max allowed. Manual for rest. - * ENABLED_ALL: Auto approvals for all new upkeeps subject to max allowed. - */ - enum AutoApproveType { - DISABLED, - ENABLED_SENDER_ALLOWLIST, - ENABLED_ALL - } - - bytes4 private constant REGISTER_REQUEST_SELECTOR = this.register.selector; - - mapping(bytes32 => PendingRequest) private s_pendingRequests; - mapping(uint8 => TriggerRegistrationStorage) private s_triggerRegistrations; - - LinkTokenInterface public immutable LINK; - - /** - * @notice versions: - * - KeeperRegistrar 2.1.0: Update for compatability with registry 2.1.0 - * Add auto approval levels by type - * - KeeperRegistrar 2.0.0: Remove source from register - * Breaks our example of "Register an Upkeep using your own deployed contract" - * - KeeperRegistrar 1.1.0: Add functionality for sender allowlist in auto approve - * : Remove rate limit and add max allowed for auto approve - * - KeeperRegistrar 1.0.0: initial release - */ - string public constant override typeAndVersion = "AutomationRegistrar 2.1.0"; - - /** - * @notice TriggerRegistrationStorage stores the auto-approval levels for upkeeps by type - * @member autoApproveType the auto approval setting (see enum) - * @member autoApproveMaxAllowed the max number of upkeeps that can be auto approved of this type - * @member approvedCount the count of upkeeps auto approved of this type - */ - struct TriggerRegistrationStorage { - AutoApproveType autoApproveType; - uint32 autoApproveMaxAllowed; - uint32 approvedCount; - } - - /** - * @notice InitialTriggerConfig configures the auto-approval levels for upkeeps by trigger type - * @dev this struct is only used in the constructor to set the initial values for various trigger configs - * @member triggerType the upkeep type to configure - * @member autoApproveType the auto approval setting (see enum) - * @member autoApproveMaxAllowed the max number of upkeeps that can be auto approved of this type - */ - struct InitialTriggerConfig { - uint8 triggerType; - AutoApproveType autoApproveType; - uint32 autoApproveMaxAllowed; - } - - struct RegistrarConfig { - IAutomationRegistryMaster AutomationRegistry; - uint96 minLINKJuels; - } - - struct PendingRequest { - address admin; - uint96 balance; - } - - struct RegistrationParams { - string name; - bytes encryptedEmail; - address upkeepContract; - uint32 gasLimit; - address adminAddress; - uint8 triggerType; - bytes checkData; - bytes triggerConfig; - bytes offchainConfig; - uint96 amount; - } - - RegistrarConfig private s_config; - // Only applicable if s_config.configType is ENABLED_SENDER_ALLOWLIST - mapping(address => bool) private s_autoApproveAllowedSenders; - - event RegistrationRequested( - bytes32 indexed hash, - string name, - bytes encryptedEmail, - address indexed upkeepContract, - uint32 gasLimit, - address adminAddress, - uint8 triggerType, - bytes triggerConfig, - bytes offchainConfig, - bytes checkData, - uint96 amount - ); - - event RegistrationApproved(bytes32 indexed hash, string displayName, uint256 indexed upkeepId); - - event RegistrationRejected(bytes32 indexed hash); - - event AutoApproveAllowedSenderSet(address indexed senderAddress, bool allowed); - - event ConfigChanged(address AutomationRegistry, uint96 minLINKJuels); - - event TriggerConfigSet(uint8 triggerType, AutoApproveType autoApproveType, uint32 autoApproveMaxAllowed); - - error InvalidAdminAddress(); - error RequestNotFound(); - error HashMismatch(); - error OnlyAdminOrOwner(); - error InsufficientPayment(); - error RegistrationRequestFailed(); - error OnlyLink(); - error AmountMismatch(); - error SenderMismatch(); - error FunctionNotPermitted(); - error LinkTransferFailed(address to); - error InvalidDataLength(); - - /** - * @param LINKAddress Address of Link token - * @param AutomationRegistry keeper registry address - * @param minLINKJuels minimum LINK that new registrations should fund their upkeep with - * @param triggerConfigs the initial config for individual triggers - */ - constructor( - address LINKAddress, - address AutomationRegistry, - uint96 minLINKJuels, - InitialTriggerConfig[] memory triggerConfigs - ) ConfirmedOwner(msg.sender) { - LINK = LinkTokenInterface(LINKAddress); - setConfig(AutomationRegistry, minLINKJuels); - for (uint256 idx = 0; idx < triggerConfigs.length; idx++) { - setTriggerConfig( - triggerConfigs[idx].triggerType, - triggerConfigs[idx].autoApproveType, - triggerConfigs[idx].autoApproveMaxAllowed - ); - } - } - - //EXTERNAL - - /** - * @notice register can only be called through transferAndCall on LINK contract - * @param name string of the upkeep to be registered - * @param encryptedEmail email address of upkeep contact - * @param upkeepContract address to perform upkeep on - * @param gasLimit amount of gas to provide the target contract when performing upkeep - * @param adminAddress address to cancel upkeep and withdraw remaining funds - * @param triggerType the type of trigger for the upkeep - * @param checkData data passed to the contract when checking for upkeep - * @param triggerConfig the config for the trigger - * @param offchainConfig offchainConfig for upkeep in bytes - * @param amount quantity of LINK upkeep is funded with (specified in Juels) - * @param sender address of the sender making the request - */ - function register( - string memory name, - bytes calldata encryptedEmail, - address upkeepContract, - uint32 gasLimit, - address adminAddress, - uint8 triggerType, - bytes memory checkData, - bytes memory triggerConfig, - bytes memory offchainConfig, - uint96 amount, - address sender - ) external onlyLINK { - _register( - RegistrationParams({ - name: name, - encryptedEmail: encryptedEmail, - upkeepContract: upkeepContract, - gasLimit: gasLimit, - adminAddress: adminAddress, - triggerType: triggerType, - checkData: checkData, - triggerConfig: triggerConfig, - offchainConfig: offchainConfig, - amount: amount - }), - sender - ); - } - - /** - * @notice Allows external users to register upkeeps; assumes amount is approved for transfer by the contract - * @param requestParams struct of all possible registration parameters - */ - function registerUpkeep(RegistrationParams calldata requestParams) external returns (uint256) { - if (requestParams.amount < s_config.minLINKJuels) { - revert InsufficientPayment(); - } - - LINK.transferFrom(msg.sender, address(this), requestParams.amount); - - return _register(requestParams, msg.sender); - } - - /** - * @dev register upkeep on AutomationRegistry contract and emit RegistrationApproved event - */ - function approve( - string memory name, - address upkeepContract, - uint32 gasLimit, - address adminAddress, - uint8 triggerType, - bytes calldata checkData, - bytes memory triggerConfig, - bytes calldata offchainConfig, - bytes32 hash - ) external onlyOwner { - PendingRequest memory request = s_pendingRequests[hash]; - if (request.admin == address(0)) { - revert RequestNotFound(); - } - bytes32 expectedHash = keccak256( - abi.encode(upkeepContract, gasLimit, adminAddress, triggerType, checkData, triggerConfig, offchainConfig) - ); - if (hash != expectedHash) { - revert HashMismatch(); - } - delete s_pendingRequests[hash]; - _approve( - RegistrationParams({ - name: name, - encryptedEmail: "", - upkeepContract: upkeepContract, - gasLimit: gasLimit, - adminAddress: adminAddress, - triggerType: triggerType, - checkData: checkData, - triggerConfig: triggerConfig, - offchainConfig: offchainConfig, - amount: request.balance - }), - expectedHash - ); - } - - /** - * @notice cancel will remove a registration request and return the refunds to the request.admin - * @param hash the request hash - */ - function cancel(bytes32 hash) external { - PendingRequest memory request = s_pendingRequests[hash]; - if (!(msg.sender == request.admin || msg.sender == owner())) { - revert OnlyAdminOrOwner(); - } - if (request.admin == address(0)) { - revert RequestNotFound(); - } - delete s_pendingRequests[hash]; - bool success = LINK.transfer(request.admin, request.balance); - if (!success) { - revert LinkTransferFailed(request.admin); - } - emit RegistrationRejected(hash); - } - - /** - * @notice owner calls this function to set contract config - * @param AutomationRegistry new keeper registry address - * @param minLINKJuels minimum LINK that new registrations should fund their upkeep with - */ - function setConfig(address AutomationRegistry, uint96 minLINKJuels) public onlyOwner { - s_config = RegistrarConfig({ - minLINKJuels: minLINKJuels, - AutomationRegistry: IAutomationRegistryMaster(AutomationRegistry) - }); - emit ConfigChanged(AutomationRegistry, minLINKJuels); - } - - /** - * @notice owner calls to set the config for this upkeep type - * @param triggerType the upkeep type to configure - * @param autoApproveType the auto approval setting (see enum) - * @param autoApproveMaxAllowed the max number of upkeeps that can be auto approved of this type - */ - function setTriggerConfig( - uint8 triggerType, - AutoApproveType autoApproveType, - uint32 autoApproveMaxAllowed - ) public onlyOwner { - s_triggerRegistrations[triggerType].autoApproveType = autoApproveType; - s_triggerRegistrations[triggerType].autoApproveMaxAllowed = autoApproveMaxAllowed; - emit TriggerConfigSet(triggerType, autoApproveType, autoApproveMaxAllowed); - } - - /** - * @notice owner calls this function to set allowlist status for senderAddress - * @param senderAddress senderAddress to set the allowlist status for - * @param allowed true if senderAddress needs to be added to allowlist, false if needs to be removed - */ - function setAutoApproveAllowedSender(address senderAddress, bool allowed) external onlyOwner { - s_autoApproveAllowedSenders[senderAddress] = allowed; - - emit AutoApproveAllowedSenderSet(senderAddress, allowed); - } - - /** - * @notice read the allowlist status of senderAddress - * @param senderAddress address to read the allowlist status for - */ - function getAutoApproveAllowedSender(address senderAddress) external view returns (bool) { - return s_autoApproveAllowedSenders[senderAddress]; - } - - /** - * @notice read the current registration configuration - */ - function getConfig() external view returns (address AutomationRegistry, uint256 minLINKJuels) { - RegistrarConfig memory config = s_config; - return (address(config.AutomationRegistry), config.minLINKJuels); - } - - /** - * @notice read the config for this upkeep type - * @param triggerType upkeep type to read config for - */ - function getTriggerRegistrationDetails(uint8 triggerType) external view returns (TriggerRegistrationStorage memory) { - return s_triggerRegistrations[triggerType]; - } - - /** - * @notice gets the admin address and the current balance of a registration request - */ - function getPendingRequest(bytes32 hash) external view returns (address, uint96) { - PendingRequest memory request = s_pendingRequests[hash]; - return (request.admin, request.balance); - } - - /** - * @notice Called when LINK is sent to the contract via `transferAndCall` - * @param sender Address of the sender transfering LINK - * @param amount Amount of LINK sent (specified in Juels) - * @param data Payload of the transaction - */ - function onTokenTransfer( - address sender, - uint256 amount, - bytes calldata data - ) - external - override - onlyLINK - permittedFunctionsForLINK(data) - isActualAmount(amount, data) - isActualSender(sender, data) - { - if (amount < s_config.minLINKJuels) { - revert InsufficientPayment(); - } - (bool success, ) = address(this).delegatecall(data); - // calls register - if (!success) { - revert RegistrationRequestFailed(); - } - } - - // ================================================================ - // | PRIVATE | - // ================================================================ - - /** - * @dev verify registration request and emit RegistrationRequested event - */ - function _register(RegistrationParams memory params, address sender) private returns (uint256) { - if (params.adminAddress == address(0)) { - revert InvalidAdminAddress(); - } - bytes32 hash = keccak256( - abi.encode( - params.upkeepContract, - params.gasLimit, - params.adminAddress, - params.triggerType, - params.checkData, - params.triggerConfig, - params.offchainConfig - ) - ); - - emit RegistrationRequested( - hash, - params.name, - params.encryptedEmail, - params.upkeepContract, - params.gasLimit, - params.adminAddress, - params.triggerType, - params.triggerConfig, - params.offchainConfig, - params.checkData, - params.amount - ); - - uint256 upkeepId; - if (_shouldAutoApprove(s_triggerRegistrations[params.triggerType], sender)) { - s_triggerRegistrations[params.triggerType].approvedCount++; - upkeepId = _approve(params, hash); - } else { - uint96 newBalance = s_pendingRequests[hash].balance + params.amount; - s_pendingRequests[hash] = PendingRequest({admin: params.adminAddress, balance: newBalance}); - } - - return upkeepId; - } - - /** - * @dev register upkeep on AutomationRegistry contract and emit RegistrationApproved event - */ - function _approve(RegistrationParams memory params, bytes32 hash) private returns (uint256) { - IAutomationRegistryMaster AutomationRegistry = s_config.AutomationRegistry; - uint256 upkeepId = AutomationRegistry.registerUpkeep( - params.upkeepContract, - params.gasLimit, - params.adminAddress, - params.triggerType, - params.checkData, - params.triggerConfig, - params.offchainConfig - ); - bool success = LINK.transferAndCall(address(AutomationRegistry), params.amount, abi.encode(upkeepId)); - if (!success) { - revert LinkTransferFailed(address(AutomationRegistry)); - } - emit RegistrationApproved(hash, params.name, upkeepId); - return upkeepId; - } - - /** - * @dev verify sender allowlist if needed and check max limit - */ - function _shouldAutoApprove(TriggerRegistrationStorage memory config, address sender) private view returns (bool) { - if (config.autoApproveType == AutoApproveType.DISABLED) { - return false; - } - if (config.autoApproveType == AutoApproveType.ENABLED_SENDER_ALLOWLIST && (!s_autoApproveAllowedSenders[sender])) { - return false; - } - if (config.approvedCount < config.autoApproveMaxAllowed) { - return true; - } - return false; - } - - // ================================================================ - // | MODIFIERS | - // ================================================================ - - /** - * @dev Reverts if not sent from the LINK token - */ - modifier onlyLINK() { - if (msg.sender != address(LINK)) { - revert OnlyLink(); - } - _; - } - - /** - * @dev Reverts if the given data does not begin with the `register` function selector - * @param _data The data payload of the request - */ - modifier permittedFunctionsForLINK(bytes memory _data) { - bytes4 funcSelector; - assembly { - // solhint-disable-next-line avoid-low-level-calls - funcSelector := mload(add(_data, 32)) // First 32 bytes contain length of data - } - if (funcSelector != REGISTER_REQUEST_SELECTOR) { - revert FunctionNotPermitted(); - } - _; - } - - /** - * @dev Reverts if the actual amount passed does not match the expected amount - * @param expected amount that should match the actual amount - * @param data bytes - */ - modifier isActualAmount(uint256 expected, bytes calldata data) { - // decode register function arguments to get actual amount - (, , , , , , , , , uint96 amount, ) = abi.decode( - data[4:], - (string, bytes, address, uint32, address, uint8, bytes, bytes, bytes, uint96, address) - ); - if (expected != amount) { - revert AmountMismatch(); - } - _; - } - - /** - * @dev Reverts if the actual sender address does not match the expected sender address - * @param expected address that should match the actual sender address - * @param data bytes - */ - modifier isActualSender(address expected, bytes calldata data) { - // decode register function arguments to get actual sender - (, , , , , , , , , , address sender) = abi.decode( - data[4:], - (string, bytes, address, uint32, address, uint8, bytes, bytes, bytes, uint96, address) - ); - if (expected != sender) { - revert SenderMismatch(); - } - _; - } -} diff --git a/contracts/test/v0.8/automation/AutomationRegistrar2_2.test.ts b/contracts/test/v0.8/automation/AutomationRegistrar2_2.test.ts deleted file mode 100644 index b7585462067..00000000000 --- a/contracts/test/v0.8/automation/AutomationRegistrar2_2.test.ts +++ /dev/null @@ -1,1013 +0,0 @@ -import { ethers } from 'hardhat' -import { ContractFactory, Contract } from 'ethers' -import { assert, expect } from 'chai' -import { evmRevert } from '../../test-helpers/matchers' -import { getUsers, Personas } from '../../test-helpers/setup' -import { BigNumber, Signer } from 'ethers' -import { MockV3Aggregator__factory as MockV3AggregatorFactory } from '../../../typechain/factories/MockV3Aggregator__factory' -import { UpkeepMock__factory as UpkeepMockFactory } from '../../../typechain/factories/UpkeepMock__factory' -import { MockV3Aggregator } from '../../../typechain/MockV3Aggregator' -import { UpkeepMock } from '../../../typechain/UpkeepMock' -import { toWei } from '../../test-helpers/helpers' -import { IKeeperRegistryMaster as IKeeperRegistry } from '../../../typechain/IKeeperRegistryMaster' -import { AutomationRegistrar2_2 as Registrar } from '../../../typechain/AutomationRegistrar2_2' -import { deployRegistry21 } from './helpers' - -// copied from KeeperRegistryBase2_2.sol -enum Trigger { - CONDITION, - LOG, -} - -let linkTokenFactory: ContractFactory -let mockV3AggregatorFactory: MockV3AggregatorFactory -let upkeepMockFactory: UpkeepMockFactory - -let personas: Personas - -before(async () => { - personas = (await getUsers()).personas - - linkTokenFactory = await ethers.getContractFactory( - 'src/v0.4/LinkToken.sol:LinkToken', - ) - mockV3AggregatorFactory = (await ethers.getContractFactory( - 'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator', - )) as unknown as MockV3AggregatorFactory - upkeepMockFactory = await ethers.getContractFactory('UpkeepMock') -}) - -const errorMsgs = { - onlyOwner: 'revert Only callable by owner', - onlyAdmin: 'OnlyAdminOrOwner()', - hashPayload: 'HashMismatch()', - requestNotFound: 'RequestNotFound()', -} - -describe('AutomationRegistrar2_2', () => { - const upkeepName = 'SampleUpkeep' - - const linkEth = BigNumber.from(300000000) - const gasWei = BigNumber.from(100) - const performGas = BigNumber.from(100000) - const paymentPremiumPPB = BigNumber.from(250000000) - const flatFeeMicroLink = BigNumber.from(0) - const maxAllowedAutoApprove = 5 - const trigger = '0xdeadbeef' - const offchainConfig = '0x01234567' - - const emptyBytes = '0x00' - const stalenessSeconds = BigNumber.from(43820) - const gasCeilingMultiplier = BigNumber.from(1) - const checkGasLimit = BigNumber.from(20000000) - const fallbackGasPrice = BigNumber.from(200) - const fallbackLinkPrice = BigNumber.from(200000000) - const maxCheckDataSize = BigNumber.from(10000) - const maxPerformDataSize = BigNumber.from(10000) - const maxRevertDataSize = BigNumber.from(1000) - const maxPerformGas = BigNumber.from(5000000) - const minUpkeepSpend = BigNumber.from('1000000000000000000') - const amount = BigNumber.from('5000000000000000000') - const amount1 = BigNumber.from('6000000000000000000') - const transcoder = ethers.constants.AddressZero - const upkeepManager = ethers.Wallet.createRandom().address - - // Enum values are not auto exported in ABI so have to manually declare - const autoApproveType_DISABLED = 0 - const autoApproveType_ENABLED_SENDER_ALLOWLIST = 1 - const autoApproveType_ENABLED_ALL = 2 - - let owner: Signer - let admin: Signer - let someAddress: Signer - let registrarOwner: Signer - let stranger: Signer - let requestSender: Signer - - let linkToken: Contract - let linkEthFeed: MockV3Aggregator - let gasPriceFeed: MockV3Aggregator - let mock: UpkeepMock - let registry: IKeeperRegistry - let registrar: Registrar - - beforeEach(async () => { - owner = personas.Default - admin = personas.Neil - someAddress = personas.Ned - registrarOwner = personas.Nelly - stranger = personas.Nancy - requestSender = personas.Norbert - - linkToken = await linkTokenFactory.connect(owner).deploy() - gasPriceFeed = await mockV3AggregatorFactory - .connect(owner) - .deploy(0, gasWei) - linkEthFeed = await mockV3AggregatorFactory - .connect(owner) - .deploy(9, linkEth) - - registry = await deployRegistry21( - owner, - 0, - linkToken.address, - linkEthFeed.address, - gasPriceFeed.address, - ) - - mock = await upkeepMockFactory.deploy() - - const registrarFactory = await ethers.getContractFactory( - 'AutomationRegistrar2_2', - ) - registrar = await registrarFactory - .connect(registrarOwner) - .deploy(linkToken.address, registry.address, minUpkeepSpend, [ - { - triggerType: Trigger.CONDITION, - autoApproveType: autoApproveType_DISABLED, - autoApproveMaxAllowed: 0, - }, - { - triggerType: Trigger.LOG, - autoApproveType: autoApproveType_DISABLED, - autoApproveMaxAllowed: 0, - }, - ]) - - await linkToken - .connect(owner) - .transfer(await requestSender.getAddress(), toWei('1000')) - - const keepers = [ - await personas.Carol.getAddress(), - await personas.Nancy.getAddress(), - await personas.Ned.getAddress(), - await personas.Neil.getAddress(), - ] - const onchainConfig = { - paymentPremiumPPB, - flatFeeMicroLink, - checkGasLimit, - stalenessSeconds, - gasCeilingMultiplier, - minUpkeepSpend, - maxCheckDataSize, - maxPerformDataSize, - maxRevertDataSize, - maxPerformGas, - fallbackGasPrice, - fallbackLinkPrice, - transcoder, - registrars: [registrar.address], - upkeepPrivilegeManager: upkeepManager, - } - await registry - .connect(owner) - .setConfigTypeSafe(keepers, keepers, 1, onchainConfig, 1, '0x') - }) - - describe('#typeAndVersion', () => { - it('uses the correct type and version', async () => { - const typeAndVersion = await registrar.typeAndVersion() - assert.equal(typeAndVersion, 'AutomationRegistrar 2.1.0') - }) - }) - - describe('#register', () => { - it('reverts if not called by the LINK token', async () => { - await evmRevert( - registrar - .connect(someAddress) - .register( - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ), - 'OnlyLink()', - ) - }) - - it('reverts if the amount passed in data mismatches actual amount sent', async () => { - await registrar - .connect(registrarOwner) - .setTriggerConfig( - Trigger.CONDITION, - autoApproveType_ENABLED_ALL, - maxAllowedAutoApprove, - ) - - const abiEncodedBytes = registrar.interface.encodeFunctionData( - 'register', - [ - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount1, - await requestSender.getAddress(), - ], - ) - - await evmRevert( - linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes), - 'AmountMismatch()', - ) - }) - - it('reverts if the sender passed in data mismatches actual sender', async () => { - const abiEncodedBytes = registrar.interface.encodeFunctionData( - 'register', - [ - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await admin.getAddress(), // Should have been requestSender.getAddress() - ], - ) - await evmRevert( - linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes), - 'SenderMismatch()', - ) - }) - - it('reverts if the admin address is 0x0000...', async () => { - const abiEncodedBytes = registrar.interface.encodeFunctionData( - 'register', - [ - upkeepName, - emptyBytes, - mock.address, - performGas, - '0x0000000000000000000000000000000000000000', - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ], - ) - - await evmRevert( - linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes), - 'RegistrationRequestFailed()', - ) - }) - - it('Auto Approve ON - registers an upkeep on KeeperRegistry instantly and emits both RegistrationRequested and RegistrationApproved events', async () => { - //set auto approve ON with high threshold limits - await registrar - .connect(registrarOwner) - .setTriggerConfig( - Trigger.CONDITION, - autoApproveType_ENABLED_ALL, - maxAllowedAutoApprove, - ) - - //register with auto approve ON - const abiEncodedBytes = registrar.interface.encodeFunctionData( - 'register', - [ - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ], - ) - const tx = await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - - const [id] = await registry.getActiveUpkeepIDs(0, 1) - - //confirm if a new upkeep has been registered and the details are the same as the one just registered - const newupkeep = await registry.getUpkeep(id) - assert.equal(newupkeep.target, mock.address) - assert.equal(newupkeep.admin, await admin.getAddress()) - assert.equal(newupkeep.checkData, emptyBytes) - assert.equal(newupkeep.balance.toString(), amount.toString()) - assert.equal(newupkeep.performGas, performGas.toNumber()) - assert.equal(newupkeep.offchainConfig, offchainConfig) - - await expect(tx).to.emit(registrar, 'RegistrationRequested') - await expect(tx).to.emit(registrar, 'RegistrationApproved') - }) - - it('Auto Approve OFF - does not registers an upkeep on KeeperRegistry, emits only RegistrationRequested event', async () => { - //get upkeep count before attempting registration - const beforeCount = (await registry.getState()).state.numUpkeeps - - //set auto approve OFF, threshold limits dont matter in this case - await registrar - .connect(registrarOwner) - .setTriggerConfig( - Trigger.CONDITION, - autoApproveType_DISABLED, - maxAllowedAutoApprove, - ) - - //register with auto approve OFF - const abiEncodedBytes = registrar.interface.encodeFunctionData( - 'register', - [ - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ], - ) - const tx = await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - const receipt = await tx.wait() - - //get upkeep count after attempting registration - const afterCount = (await registry.getState()).state.numUpkeeps - //confirm that a new upkeep has NOT been registered and upkeep count is still the same - assert.deepEqual(beforeCount, afterCount) - - //confirm that only RegistrationRequested event is emitted and RegistrationApproved event is not - await expect(tx).to.emit(registrar, 'RegistrationRequested') - await expect(tx).not.to.emit(registrar, 'RegistrationApproved') - - const hash = receipt.logs[2].topics[1] - const pendingRequest = await registrar.getPendingRequest(hash) - assert.equal(await admin.getAddress(), pendingRequest[0]) - assert.ok(amount.eq(pendingRequest[1])) - }) - - it('Auto Approve ON - Throttle max approvals - does not register an upkeep on KeeperRegistry beyond the max limit, emits only RegistrationRequested event after limit is hit', async () => { - assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 0) - - //set auto approve on, with max 1 allowed - await registrar - .connect(registrarOwner) - .setTriggerConfig(Trigger.CONDITION, autoApproveType_ENABLED_ALL, 1) - - //set auto approve on, with max 1 allowed - await registrar - .connect(registrarOwner) - .setTriggerConfig(Trigger.LOG, autoApproveType_ENABLED_ALL, 1) - - // register within threshold, new upkeep should be registered - let abiEncodedBytes = registrar.interface.encodeFunctionData('register', [ - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ]) - await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 1) // 0 -> 1 - - // try registering another one, new upkeep should not be registered - abiEncodedBytes = registrar.interface.encodeFunctionData('register', [ - upkeepName, - emptyBytes, - mock.address, - performGas.toNumber() + 1, // make unique hash - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ]) - await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 1) // Still 1 - - // register a second type of upkeep, different limit - abiEncodedBytes = registrar.interface.encodeFunctionData('register', [ - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - Trigger.LOG, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ]) - await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 2) // 1 -> 2 - - // Now set new max limit to 2. One more upkeep should get auto approved - await registrar - .connect(registrarOwner) - .setTriggerConfig(Trigger.CONDITION, autoApproveType_ENABLED_ALL, 2) - - abiEncodedBytes = registrar.interface.encodeFunctionData('register', [ - upkeepName, - emptyBytes, - mock.address, - performGas.toNumber() + 2, // make unique hash - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ]) - await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 3) // 2 -> 3 - - // One more upkeep should not get registered - abiEncodedBytes = registrar.interface.encodeFunctionData('register', [ - upkeepName, - emptyBytes, - mock.address, - performGas.toNumber() + 3, // make unique hash - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ]) - await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 3) // Still 3 - }) - - it('Auto Approve Sender Allowlist - sender in allowlist - registers an upkeep on KeeperRegistry instantly and emits both RegistrationRequested and RegistrationApproved events', async () => { - const senderAddress = await requestSender.getAddress() - - //set auto approve to ENABLED_SENDER_ALLOWLIST type with high threshold limits - await registrar - .connect(registrarOwner) - .setTriggerConfig( - Trigger.CONDITION, - autoApproveType_ENABLED_SENDER_ALLOWLIST, - maxAllowedAutoApprove, - ) - - // Add sender to allowlist - await registrar - .connect(registrarOwner) - .setAutoApproveAllowedSender(senderAddress, true) - - //register with auto approve ON - const abiEncodedBytes = registrar.interface.encodeFunctionData( - 'register', - [ - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ], - ) - const tx = await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - - const [id] = await registry.getActiveUpkeepIDs(0, 1) - - //confirm if a new upkeep has been registered and the details are the same as the one just registered - const newupkeep = await registry.getUpkeep(id) - assert.equal(newupkeep.target, mock.address) - assert.equal(newupkeep.admin, await admin.getAddress()) - assert.equal(newupkeep.checkData, emptyBytes) - assert.equal(newupkeep.balance.toString(), amount.toString()) - assert.equal(newupkeep.performGas, performGas.toNumber()) - - await expect(tx).to.emit(registrar, 'RegistrationRequested') - await expect(tx).to.emit(registrar, 'RegistrationApproved') - }) - - it('Auto Approve Sender Allowlist - sender NOT in allowlist - does not registers an upkeep on KeeperRegistry, emits only RegistrationRequested event', async () => { - const beforeCount = (await registry.getState()).state.numUpkeeps - const senderAddress = await requestSender.getAddress() - - //set auto approve to ENABLED_SENDER_ALLOWLIST type with high threshold limits - await registrar - .connect(registrarOwner) - .setTriggerConfig( - Trigger.CONDITION, - autoApproveType_ENABLED_SENDER_ALLOWLIST, - maxAllowedAutoApprove, - ) - - // Explicitly remove sender from allowlist - await registrar - .connect(registrarOwner) - .setAutoApproveAllowedSender(senderAddress, false) - - //register. auto approve shouldn't happen - const abiEncodedBytes = registrar.interface.encodeFunctionData( - 'register', - [ - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ], - ) - const tx = await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - const receipt = await tx.wait() - - //get upkeep count after attempting registration - const afterCount = (await registry.getState()).state.numUpkeeps - //confirm that a new upkeep has NOT been registered and upkeep count is still the same - assert.deepEqual(beforeCount, afterCount) - - //confirm that only RegistrationRequested event is emitted and RegistrationApproved event is not - await expect(tx).to.emit(registrar, 'RegistrationRequested') - await expect(tx).not.to.emit(registrar, 'RegistrationApproved') - - const hash = receipt.logs[2].topics[1] - const pendingRequest = await registrar.getPendingRequest(hash) - assert.equal(await admin.getAddress(), pendingRequest[0]) - assert.ok(amount.eq(pendingRequest[1])) - }) - }) - - describe('#registerUpkeep', () => { - it('reverts with empty message if amount sent is not available in LINK allowance', async () => { - await evmRevert( - registrar.connect(someAddress).registerUpkeep({ - name: upkeepName, - upkeepContract: mock.address, - gasLimit: performGas, - adminAddress: await admin.getAddress(), - triggerType: 0, - checkData: emptyBytes, - triggerConfig: trigger, - offchainConfig: emptyBytes, - amount, - encryptedEmail: emptyBytes, - }), - '', - ) - }) - - it('reverts if the amount passed in data is less than configured minimum', async () => { - await registrar - .connect(registrarOwner) - .setTriggerConfig( - Trigger.CONDITION, - autoApproveType_ENABLED_ALL, - maxAllowedAutoApprove, - ) - - // amt is one order of magnitude less than minUpkeepSpend - const amt = BigNumber.from('100000000000000000') - - await evmRevert( - registrar.connect(someAddress).registerUpkeep({ - name: upkeepName, - upkeepContract: mock.address, - gasLimit: performGas, - adminAddress: await admin.getAddress(), - triggerType: 0, - checkData: emptyBytes, - triggerConfig: trigger, - offchainConfig: emptyBytes, - amount: amt, - encryptedEmail: emptyBytes, - }), - 'InsufficientPayment()', - ) - }) - - it('Auto Approve ON - registers an upkeep on KeeperRegistry instantly and emits both RegistrationRequested and RegistrationApproved events', async () => { - //set auto approve ON with high threshold limits - await registrar - .connect(registrarOwner) - .setTriggerConfig( - Trigger.CONDITION, - autoApproveType_ENABLED_ALL, - maxAllowedAutoApprove, - ) - - await linkToken.connect(requestSender).approve(registrar.address, amount) - - const tx = await registrar.connect(requestSender).registerUpkeep({ - name: upkeepName, - upkeepContract: mock.address, - gasLimit: performGas, - adminAddress: await admin.getAddress(), - triggerType: 0, - checkData: emptyBytes, - triggerConfig: trigger, - offchainConfig, - amount, - encryptedEmail: emptyBytes, - }) - assert.equal((await registry.getState()).state.numUpkeeps.toNumber(), 1) // 0 -> 1 - - //confirm if a new upkeep has been registered and the details are the same as the one just registered - const [id] = await registry.getActiveUpkeepIDs(0, 1) - const newupkeep = await registry.getUpkeep(id) - assert.equal(newupkeep.target, mock.address) - assert.equal(newupkeep.admin, await admin.getAddress()) - assert.equal(newupkeep.checkData, emptyBytes) - assert.equal(newupkeep.balance.toString(), amount.toString()) - assert.equal(newupkeep.performGas, performGas.toNumber()) - assert.equal(newupkeep.offchainConfig, offchainConfig) - - await expect(tx).to.emit(registrar, 'RegistrationRequested') - await expect(tx).to.emit(registrar, 'RegistrationApproved') - }) - }) - - describe('#setAutoApproveAllowedSender', () => { - it('reverts if not called by the owner', async () => { - const tx = registrar - .connect(stranger) - .setAutoApproveAllowedSender(await admin.getAddress(), false) - await evmRevert(tx, 'Only callable by owner') - }) - - it('sets the allowed status correctly and emits log', async () => { - const senderAddress = await stranger.getAddress() - let tx = await registrar - .connect(registrarOwner) - .setAutoApproveAllowedSender(senderAddress, true) - await expect(tx) - .to.emit(registrar, 'AutoApproveAllowedSenderSet') - .withArgs(senderAddress, true) - - let senderAllowedStatus = await registrar - .connect(owner) - .getAutoApproveAllowedSender(senderAddress) - assert.isTrue(senderAllowedStatus) - - tx = await registrar - .connect(registrarOwner) - .setAutoApproveAllowedSender(senderAddress, false) - await expect(tx) - .to.emit(registrar, 'AutoApproveAllowedSenderSet') - .withArgs(senderAddress, false) - - senderAllowedStatus = await registrar - .connect(owner) - .getAutoApproveAllowedSender(senderAddress) - assert.isFalse(senderAllowedStatus) - }) - }) - - describe('#setTriggerConfig', () => { - it('reverts if not called by the owner', async () => { - const tx = registrar - .connect(stranger) - .setTriggerConfig(Trigger.LOG, autoApproveType_ENABLED_ALL, 100) - await evmRevert(tx, 'Only callable by owner') - }) - - it('changes the config', async () => { - const tx = await registrar - .connect(registrarOwner) - .setTriggerConfig(Trigger.LOG, autoApproveType_ENABLED_ALL, 100) - await registrar.getTriggerRegistrationDetails(Trigger.LOG) - await expect(tx) - .to.emit(registrar, 'TriggerConfigSet') - .withArgs(Trigger.LOG, autoApproveType_ENABLED_ALL, 100) - }) - }) - - describe('#approve', () => { - let hash: string - - beforeEach(async () => { - await registrar - .connect(registrarOwner) - .setTriggerConfig( - Trigger.CONDITION, - autoApproveType_DISABLED, - maxAllowedAutoApprove, - ) - - //register with auto approve OFF - const abiEncodedBytes = registrar.interface.encodeFunctionData( - 'register', - [ - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ], - ) - - const tx = await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - const receipt = await tx.wait() - hash = receipt.logs[2].topics[1] - }) - - it('reverts if not called by the owner', async () => { - const tx = registrar - .connect(stranger) - .approve( - upkeepName, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - emptyBytes, - hash, - ) - await evmRevert(tx, 'Only callable by owner') - }) - - it('reverts if the hash does not exist', async () => { - const tx = registrar - .connect(registrarOwner) - .approve( - upkeepName, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - emptyBytes, - '0x000000000000000000000000322813fd9a801c5507c9de605d63cea4f2ce6c44', - ) - await evmRevert(tx, errorMsgs.requestNotFound) - }) - - it('reverts if any member of the payload changes', async () => { - let tx = registrar - .connect(registrarOwner) - .approve( - upkeepName, - ethers.Wallet.createRandom().address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - emptyBytes, - hash, - ) - await evmRevert(tx, errorMsgs.hashPayload) - tx = registrar - .connect(registrarOwner) - .approve( - upkeepName, - mock.address, - 10000, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - emptyBytes, - hash, - ) - await evmRevert(tx, errorMsgs.hashPayload) - tx = registrar - .connect(registrarOwner) - .approve( - upkeepName, - mock.address, - performGas, - ethers.Wallet.createRandom().address, - 0, - emptyBytes, - trigger, - emptyBytes, - hash, - ) - await evmRevert(tx, errorMsgs.hashPayload) - tx = registrar - .connect(registrarOwner) - .approve( - upkeepName, - mock.address, - performGas, - await admin.getAddress(), - 0, - '0x1234', - trigger, - emptyBytes, - hash, - ) - await evmRevert(tx, errorMsgs.hashPayload) - }) - - it('approves an existing registration request', async () => { - const tx = await registrar - .connect(registrarOwner) - .approve( - upkeepName, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - hash, - ) - await expect(tx).to.emit(registrar, 'RegistrationApproved') - }) - - it('deletes the request afterwards / reverts if the request DNE', async () => { - await registrar - .connect(registrarOwner) - .approve( - upkeepName, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - hash, - ) - const tx = registrar - .connect(registrarOwner) - .approve( - upkeepName, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - hash, - ) - await evmRevert(tx, errorMsgs.requestNotFound) - }) - }) - - describe('#cancel', () => { - let hash: string - - beforeEach(async () => { - await registrar - .connect(registrarOwner) - .setTriggerConfig( - Trigger.CONDITION, - autoApproveType_DISABLED, - maxAllowedAutoApprove, - ) - - //register with auto approve OFF - const abiEncodedBytes = registrar.interface.encodeFunctionData( - 'register', - [ - upkeepName, - emptyBytes, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - offchainConfig, - amount, - await requestSender.getAddress(), - ], - ) - const tx = await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - const receipt = await tx.wait() - hash = receipt.logs[2].topics[1] - // submit duplicate request (increase balance) - await linkToken - .connect(requestSender) - .transferAndCall(registrar.address, amount, abiEncodedBytes) - }) - - it('reverts if not called by the admin / owner', async () => { - const tx = registrar.connect(stranger).cancel(hash) - await evmRevert(tx, errorMsgs.onlyAdmin) - }) - - it('reverts if the hash does not exist', async () => { - const tx = registrar - .connect(registrarOwner) - .cancel( - '0x000000000000000000000000322813fd9a801c5507c9de605d63cea4f2ce6c44', - ) - await evmRevert(tx, errorMsgs.requestNotFound) - }) - - it('refunds the total request balance to the admin address if owner cancels', async () => { - const before = await linkToken.balanceOf(await admin.getAddress()) - const tx = await registrar.connect(registrarOwner).cancel(hash) - const after = await linkToken.balanceOf(await admin.getAddress()) - assert.isTrue(after.sub(before).eq(amount.mul(BigNumber.from(2)))) - await expect(tx).to.emit(registrar, 'RegistrationRejected') - }) - - it('refunds the total request balance to the admin address if admin cancels', async () => { - const before = await linkToken.balanceOf(await admin.getAddress()) - const tx = await registrar.connect(admin).cancel(hash) - const after = await linkToken.balanceOf(await admin.getAddress()) - assert.isTrue(after.sub(before).eq(amount.mul(BigNumber.from(2)))) - await expect(tx).to.emit(registrar, 'RegistrationRejected') - }) - - it('deletes the request hash', async () => { - await registrar.connect(registrarOwner).cancel(hash) - let tx = registrar.connect(registrarOwner).cancel(hash) - await evmRevert(tx, errorMsgs.requestNotFound) - tx = registrar - .connect(registrarOwner) - .approve( - upkeepName, - mock.address, - performGas, - await admin.getAddress(), - 0, - emptyBytes, - trigger, - emptyBytes, - hash, - ) - await evmRevert(tx, errorMsgs.requestNotFound) - }) - }) -}) diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 6bf2ad1b4b2..187589d8ee0 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -7,7 +7,6 @@ authorized_receiver: ../../contracts/solc/v0.8.19/AuthorizedReceiver/AuthorizedR automation_consumer_benchmark: ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark/AutomationConsumerBenchmark.abi ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark/AutomationConsumerBenchmark.bin f52c76f1aaed4be541d82d97189d70f5aa027fc9838037dd7a7d21910c8c488e automation_forwarder_logic: ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.abi ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.bin 15ae0c367297955fdab4b552dbb10e1f2be80a8fde0efec4a4d398693e9d72b5 automation_registrar_wrapper2_1: ../../contracts/solc/v0.8.16/AutomationRegistrar2_1/AutomationRegistrar2_1.abi ../../contracts/solc/v0.8.16/AutomationRegistrar2_1/AutomationRegistrar2_1.bin eb06d853aab39d3196c593b03e555851cbe8386e0fe54a74c2479f62d14b3c42 -automation_registrar_wrapper2_2: ../../contracts/solc/v0.8.19/AutomationRegistrar2_2/AutomationRegistrar2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistrar2_2/AutomationRegistrar2_2.bin 7c61908c1bb1bfd05a4da22bb73d62c0e2c05240f3f8fb5e06331603ff2246a9 automation_registrar_wrapper2_3: ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.bin 8e18d447009546ac8ad15d0d516ad4d663d0e1ca5f723300acb604b5571b63bf automation_registry_logic_a_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.bin 58d09c16be20a6d3f70be6d06299ed61415b7796c71f176d87ce015e1294e029 automation_registry_logic_a_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.bin 56b9ed9923d0610fcc5c23c7e0d8f013195313138fbd2630b5148aced302582e diff --git a/core/gethwrappers/go_generate.go b/core/gethwrappers/go_generate.go index 2744f14c003..2b903ca9f50 100644 --- a/core/gethwrappers/go_generate.go +++ b/core/gethwrappers/go_generate.go @@ -56,7 +56,6 @@ package gethwrappers //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/KeeperRegistryLogicB2_1/KeeperRegistryLogicB2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistryLogicB2_1/KeeperRegistryLogicB2_1.bin KeeperRegistryLogicB keeper_registry_logic_b_wrapper_2_1 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.abi ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.bin IKeeperRegistryMaster i_keeper_registry_master_wrapper_2_1 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.abi ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.bin AutomationUtils automation_utils_2_1 -//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistrar2_2/AutomationRegistrar2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistrar2_2/AutomationRegistrar2_2.bin AutomationRegistrar automation_registrar_wrapper2_2 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.bin AutomationRegistry automation_registry_wrapper_2_2 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.bin AutomationRegistryLogicA automation_registry_logic_a_wrapper_2_2 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.bin AutomationRegistryLogicB automation_registry_logic_b_wrapper_2_2 From a19af50cadb448efd20c8c1b323de7ae991d25e8 Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Thu, 7 Mar 2024 01:41:56 -0500 Subject: [PATCH 30/34] move registry 2.2 and chain modules out of dev (#12327) * remove unused registrar 2_2 * move registry 2.2 and chain modules out of dev * fix foundry test path * fix foundry test --- .../generate-automation-master-interface.ts | 2 +- .../native_solc_compile_all_automation | 22 +++++++++---------- .../{dev => }/chains/ArbitrumModule.sol | 4 ++-- .../{dev => }/chains/ChainModuleBase.sol | 0 .../{dev => }/chains/OptimismModule.sol | 2 +- .../{dev => }/chains/ScrollModule.sol | 2 +- .../dev/test/AutomationRegistry2_3.t.sol | 2 +- .../dev/v2_3/AutomationRegistryBase2_3.sol | 2 +- .../dev/v2_3/AutomationRegistryLogicB2_3.sol | 2 +- .../{dev => }/interfaces/IChainModule.sol | 0 .../v2_2/IAutomationRegistryMaster.sol | 0 .../test/AutomationRegistry2_2.t.sol | 2 +- .../{dev => }/v2_2/AutomationRegistry2_2.sol | 10 ++++----- .../v2_2/AutomationRegistryBase2_2.sol | 20 ++++++++--------- .../v2_2/AutomationRegistryLogicA2_2.sol | 14 ++++++------ .../v2_2/AutomationRegistryLogicB2_2.sol | 8 +++---- .../{dev => }/v2_2/AutomationUtils2_2.sol | 2 +- .../v0.8/automation/{dev => }/v2_2/LICENSE | 0 .../v0.8/automation/{dev => }/v2_2/README.md | 0 19 files changed, 47 insertions(+), 47 deletions(-) rename contracts/src/v0.8/automation/{dev => }/chains/ArbitrumModule.sol (90%) rename contracts/src/v0.8/automation/{dev => }/chains/ChainModuleBase.sol (100%) rename contracts/src/v0.8/automation/{dev => }/chains/OptimismModule.sol (93%) rename contracts/src/v0.8/automation/{dev => }/chains/ScrollModule.sol (94%) rename contracts/src/v0.8/automation/{dev => }/interfaces/IChainModule.sol (100%) rename contracts/src/v0.8/automation/{dev => }/interfaces/v2_2/IAutomationRegistryMaster.sol (100%) rename contracts/src/v0.8/automation/{dev => }/test/AutomationRegistry2_2.t.sol (98%) rename contracts/src/v0.8/automation/{dev => }/v2_2/AutomationRegistry2_2.sol (97%) rename contracts/src/v0.8/automation/{dev => }/v2_2/AutomationRegistryBase2_2.sol (97%) rename contracts/src/v0.8/automation/{dev => }/v2_2/AutomationRegistryLogicA2_2.sol (96%) rename contracts/src/v0.8/automation/{dev => }/v2_2/AutomationRegistryLogicB2_2.sol (98%) rename contracts/src/v0.8/automation/{dev => }/v2_2/AutomationUtils2_2.sol (95%) rename contracts/src/v0.8/automation/{dev => }/v2_2/LICENSE (100%) rename contracts/src/v0.8/automation/{dev => }/v2_2/README.md (100%) diff --git a/contracts/scripts/generate-automation-master-interface.ts b/contracts/scripts/generate-automation-master-interface.ts index 78c09cf2836..18866b2e695 100644 --- a/contracts/scripts/generate-automation-master-interface.ts +++ b/contracts/scripts/generate-automation-master-interface.ts @@ -9,7 +9,7 @@ import { utils } from 'ethers' import fs from 'fs' import { exec } from 'child_process' -const dest = 'src/v0.8/automation/dev/interfaces/v2_2' +const dest = 'src/v0.8/automation/interfaces/v2_2' const srcDest = `${dest}/IAutomationRegistryMaster.sol` const tmpDest = `${dest}/tmp.txt` diff --git a/contracts/scripts/native_solc_compile_all_automation b/contracts/scripts/native_solc_compile_all_automation index cbb78a2cb40..fda0bc90fc1 100755 --- a/contracts/scripts/native_solc_compile_all_automation +++ b/contracts/scripts/native_solc_compile_all_automation @@ -86,17 +86,17 @@ solc-select use $SOLC_VERSION export SOLC_VERSION=$SOLC_VERSION # v0.8.19 -compileContract automation/dev/v2_2/AutomationRegistry2_2.sol -compileContract automation/dev/v2_2/AutomationRegistryLogicA2_2.sol -compileContract automation/dev/v2_2/AutomationRegistryLogicB2_2.sol -compileContract automation/dev/v2_2/AutomationUtils2_2.sol -compileContract automation/dev/interfaces/v2_2/IAutomationRegistryMaster.sol -compileContract automation/dev/chains/ArbitrumModule.sol -compileContract automation/dev/chains/ChainModuleBase.sol -compileContract automation/dev/chains/OptimismModule.sol -compileContract automation/dev/chains/ScrollModule.sol - -compileContract automation/dev/interfaces/IChainModule.sol +compileContract automation/v2_2/AutomationRegistry2_2.sol +compileContract automation/v2_2/AutomationRegistryLogicA2_2.sol +compileContract automation/v2_2/AutomationRegistryLogicB2_2.sol +compileContract automation/v2_2/AutomationUtils2_2.sol +compileContract automation/interfaces/v2_2/IAutomationRegistryMaster.sol +compileContract automation/chains/ArbitrumModule.sol +compileContract automation/chains/ChainModuleBase.sol +compileContract automation/chains/OptimismModule.sol +compileContract automation/chains/ScrollModule.sol +compileContract automation/interfaces/IChainModule.sol + compileContract automation/dev/v2_3/AutomationRegistrar2_3.sol compileContract automation/dev/v2_3/AutomationRegistry2_3.sol compileContract automation/dev/v2_3/AutomationRegistryLogicA2_3.sol diff --git a/contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol b/contracts/src/v0.8/automation/chains/ArbitrumModule.sol similarity index 90% rename from contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol rename to contracts/src/v0.8/automation/chains/ArbitrumModule.sol index fad7e459c63..e27a0809b7e 100644 --- a/contracts/src/v0.8/automation/dev/chains/ArbitrumModule.sol +++ b/contracts/src/v0.8/automation/chains/ArbitrumModule.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {ArbSys} from "../../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; -import {ArbGasInfo} from "../../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol"; +import {ArbSys} from "../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; +import {ArbGasInfo} from "../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol"; import {ChainModuleBase} from "./ChainModuleBase.sol"; contract ArbitrumModule is ChainModuleBase { diff --git a/contracts/src/v0.8/automation/dev/chains/ChainModuleBase.sol b/contracts/src/v0.8/automation/chains/ChainModuleBase.sol similarity index 100% rename from contracts/src/v0.8/automation/dev/chains/ChainModuleBase.sol rename to contracts/src/v0.8/automation/chains/ChainModuleBase.sol diff --git a/contracts/src/v0.8/automation/dev/chains/OptimismModule.sol b/contracts/src/v0.8/automation/chains/OptimismModule.sol similarity index 93% rename from contracts/src/v0.8/automation/dev/chains/OptimismModule.sol rename to contracts/src/v0.8/automation/chains/OptimismModule.sol index 1c5a3f33d1f..91c1c0ed968 100644 --- a/contracts/src/v0.8/automation/dev/chains/OptimismModule.sol +++ b/contracts/src/v0.8/automation/chains/OptimismModule.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {OVM_GasPriceOracle} from "../../../vendor/@eth-optimism/contracts/v0.8.9/contracts/L2/predeploys/OVM_GasPriceOracle.sol"; +import {OVM_GasPriceOracle} from "../../vendor/@eth-optimism/contracts/v0.8.9/contracts/L2/predeploys/OVM_GasPriceOracle.sol"; import {ChainModuleBase} from "./ChainModuleBase.sol"; contract OptimismModule is ChainModuleBase { diff --git a/contracts/src/v0.8/automation/dev/chains/ScrollModule.sol b/contracts/src/v0.8/automation/chains/ScrollModule.sol similarity index 94% rename from contracts/src/v0.8/automation/dev/chains/ScrollModule.sol rename to contracts/src/v0.8/automation/chains/ScrollModule.sol index f01a2b537c3..1e41ed3805f 100644 --- a/contracts/src/v0.8/automation/dev/chains/ScrollModule.sol +++ b/contracts/src/v0.8/automation/chains/ScrollModule.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {IScrollL1GasPriceOracle} from "../../../vendor/@scroll-tech/contracts/src/L2/predeploys/IScrollL1GasPriceOracle.sol"; +import {IScrollL1GasPriceOracle} from "../../vendor/@scroll-tech/contracts/src/L2/predeploys/IScrollL1GasPriceOracle.sol"; import {ChainModuleBase} from "./ChainModuleBase.sol"; contract ScrollModule is ChainModuleBase { diff --git a/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol b/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol index 89bea70af86..99d9202b5e8 100644 --- a/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol +++ b/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol @@ -8,7 +8,7 @@ import {AutomationRegistryBase2_3} from "../v2_3/AutomationRegistryBase2_3.sol"; import {AutomationRegistryLogicA2_3} from "../v2_3/AutomationRegistryLogicA2_3.sol"; import {AutomationRegistryLogicB2_3} from "../v2_3/AutomationRegistryLogicB2_3.sol"; import {IAutomationRegistryMaster} from "../interfaces/v2_3/IAutomationRegistryMaster2_3.sol"; -import {ChainModuleBase} from "../chains/ChainModuleBase.sol"; +import {ChainModuleBase} from "../../chains/ChainModuleBase.sol"; contract AutomationRegistry2_3_SetUp is BaseTest { address internal constant LINK_ETH_FEED = 0x1111111111111111111111111111111111111110; diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol index 4874bbcb948..764eb5eac09 100644 --- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol @@ -11,7 +11,7 @@ import {AggregatorV3Interface} from "../../../shared/interfaces/AggregatorV3Inte import {LinkTokenInterface} from "../../../shared/interfaces/LinkTokenInterface.sol"; import {KeeperCompatibleInterface} from "../../interfaces/KeeperCompatibleInterface.sol"; import {UpkeepFormat} from "../../interfaces/UpkeepTranscoderInterface.sol"; -import {IChainModule} from "../interfaces/IChainModule.sol"; +import {IChainModule} from "../../interfaces/IChainModule.sol"; /** * @notice Base Keeper Registry contract, contains shared logic between diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicB2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicB2_3.sol index 1f8655967cf..b0a1aa27fd6 100644 --- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicB2_3.sol +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicB2_3.sol @@ -6,7 +6,7 @@ import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contra import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; import {UpkeepFormat} from "../../interfaces/UpkeepTranscoderInterface.sol"; import {IAutomationForwarder} from "../../interfaces/IAutomationForwarder.sol"; -import {IChainModule} from "../interfaces/IChainModule.sol"; +import {IChainModule} from "../../interfaces/IChainModule.sol"; contract AutomationRegistryLogicB2_3 is AutomationRegistryBase2_3 { using Address for address; diff --git a/contracts/src/v0.8/automation/dev/interfaces/IChainModule.sol b/contracts/src/v0.8/automation/interfaces/IChainModule.sol similarity index 100% rename from contracts/src/v0.8/automation/dev/interfaces/IChainModule.sol rename to contracts/src/v0.8/automation/interfaces/IChainModule.sol diff --git a/contracts/src/v0.8/automation/dev/interfaces/v2_2/IAutomationRegistryMaster.sol b/contracts/src/v0.8/automation/interfaces/v2_2/IAutomationRegistryMaster.sol similarity index 100% rename from contracts/src/v0.8/automation/dev/interfaces/v2_2/IAutomationRegistryMaster.sol rename to contracts/src/v0.8/automation/interfaces/v2_2/IAutomationRegistryMaster.sol diff --git a/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_2.t.sol b/contracts/src/v0.8/automation/test/AutomationRegistry2_2.t.sol similarity index 98% rename from contracts/src/v0.8/automation/dev/test/AutomationRegistry2_2.t.sol rename to contracts/src/v0.8/automation/test/AutomationRegistry2_2.t.sol index 6b05e4f6465..f3eafc0d9a5 100644 --- a/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_2.t.sol +++ b/contracts/src/v0.8/automation/test/AutomationRegistry2_2.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {AutomationForwarderLogic} from "../../AutomationForwarderLogic.sol"; +import {AutomationForwarderLogic} from "../AutomationForwarderLogic.sol"; import {BaseTest} from "./BaseTest.t.sol"; import {AutomationRegistry2_2} from "../v2_2/AutomationRegistry2_2.sol"; import {AutomationRegistryBase2_2} from "../v2_2/AutomationRegistryBase2_2.sol"; diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistry2_2.sol b/contracts/src/v0.8/automation/v2_2/AutomationRegistry2_2.sol similarity index 97% rename from contracts/src/v0.8/automation/dev/v2_2/AutomationRegistry2_2.sol rename to contracts/src/v0.8/automation/v2_2/AutomationRegistry2_2.sol index 7b37a5eba2c..8add9568d26 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistry2_2.sol +++ b/contracts/src/v0.8/automation/v2_2/AutomationRegistry2_2.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; -import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {Address} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; import {AutomationRegistryBase2_2} from "./AutomationRegistryBase2_2.sol"; import {AutomationRegistryLogicB2_2} from "./AutomationRegistryLogicB2_2.sol"; -import {Chainable} from "../../Chainable.sol"; -import {IERC677Receiver} from "../../../shared/interfaces/IERC677Receiver.sol"; -import {OCR2Abstract} from "../../../shared/ocr2/OCR2Abstract.sol"; +import {Chainable} from "../Chainable.sol"; +import {IERC677Receiver} from "../../shared/interfaces/IERC677Receiver.sol"; +import {OCR2Abstract} from "../../shared/ocr2/OCR2Abstract.sol"; /** * @notice Registry for adding work for Chainlink nodes to perform on client diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryBase2_2.sol b/contracts/src/v0.8/automation/v2_2/AutomationRegistryBase2_2.sol similarity index 97% rename from contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryBase2_2.sol rename to contracts/src/v0.8/automation/v2_2/AutomationRegistryBase2_2.sol index d415e0e3e1f..546b6e34a91 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryBase2_2.sol +++ b/contracts/src/v0.8/automation/v2_2/AutomationRegistryBase2_2.sol @@ -1,16 +1,16 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; -import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; -import {StreamsLookupCompatibleInterface} from "../../interfaces/StreamsLookupCompatibleInterface.sol"; -import {ILogAutomation, Log} from "../../interfaces/ILogAutomation.sol"; -import {IAutomationForwarder} from "../../interfaces/IAutomationForwarder.sol"; -import {ConfirmedOwner} from "../../../shared/access/ConfirmedOwner.sol"; -import {AggregatorV3Interface} from "../../../shared/interfaces/AggregatorV3Interface.sol"; -import {LinkTokenInterface} from "../../../shared/interfaces/LinkTokenInterface.sol"; -import {KeeperCompatibleInterface} from "../../interfaces/KeeperCompatibleInterface.sol"; -import {UpkeepFormat} from "../../interfaces/UpkeepTranscoderInterface.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {Address} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; +import {StreamsLookupCompatibleInterface} from "../interfaces/StreamsLookupCompatibleInterface.sol"; +import {ILogAutomation, Log} from "../interfaces/ILogAutomation.sol"; +import {IAutomationForwarder} from "../interfaces/IAutomationForwarder.sol"; +import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol"; +import {AggregatorV3Interface} from "../../shared/interfaces/AggregatorV3Interface.sol"; +import {LinkTokenInterface} from "../../shared/interfaces/LinkTokenInterface.sol"; +import {KeeperCompatibleInterface} from "../interfaces/KeeperCompatibleInterface.sol"; +import {UpkeepFormat} from "../interfaces/UpkeepTranscoderInterface.sol"; import {IChainModule} from "../interfaces/IChainModule.sol"; /** diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicA2_2.sol b/contracts/src/v0.8/automation/v2_2/AutomationRegistryLogicA2_2.sol similarity index 96% rename from contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicA2_2.sol rename to contracts/src/v0.8/automation/v2_2/AutomationRegistryLogicA2_2.sol index b5269fcb63a..dfe78c9db6f 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicA2_2.sol +++ b/contracts/src/v0.8/automation/v2_2/AutomationRegistryLogicA2_2.sol @@ -1,15 +1,15 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; -import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {Address} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; import {AutomationRegistryBase2_2} from "./AutomationRegistryBase2_2.sol"; import {AutomationRegistryLogicB2_2} from "./AutomationRegistryLogicB2_2.sol"; -import {Chainable} from "../../Chainable.sol"; -import {AutomationForwarder} from "../../AutomationForwarder.sol"; -import {IAutomationForwarder} from "../../interfaces/IAutomationForwarder.sol"; -import {UpkeepTranscoderInterfaceV2} from "../../interfaces/UpkeepTranscoderInterfaceV2.sol"; -import {MigratableKeeperRegistryInterfaceV2} from "../../interfaces/MigratableKeeperRegistryInterfaceV2.sol"; +import {Chainable} from "../Chainable.sol"; +import {AutomationForwarder} from "../AutomationForwarder.sol"; +import {IAutomationForwarder} from "../interfaces/IAutomationForwarder.sol"; +import {UpkeepTranscoderInterfaceV2} from "../interfaces/UpkeepTranscoderInterfaceV2.sol"; +import {MigratableKeeperRegistryInterfaceV2} from "../interfaces/MigratableKeeperRegistryInterfaceV2.sol"; /** * @notice Logic contract, works in tandem with AutomationRegistry as a proxy diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicB2_2.sol b/contracts/src/v0.8/automation/v2_2/AutomationRegistryLogicB2_2.sol similarity index 98% rename from contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicB2_2.sol rename to contracts/src/v0.8/automation/v2_2/AutomationRegistryLogicB2_2.sol index 6ce56577819..3b5354c7be4 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationRegistryLogicB2_2.sol +++ b/contracts/src/v0.8/automation/v2_2/AutomationRegistryLogicB2_2.sol @@ -2,10 +2,10 @@ pragma solidity 0.8.19; import {AutomationRegistryBase2_2} from "./AutomationRegistryBase2_2.sol"; -import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; -import {Address} from "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; -import {UpkeepFormat} from "../../interfaces/UpkeepTranscoderInterface.sol"; -import {IAutomationForwarder} from "../../interfaces/IAutomationForwarder.sol"; +import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; +import {Address} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; +import {UpkeepFormat} from "../interfaces/UpkeepTranscoderInterface.sol"; +import {IAutomationForwarder} from "../interfaces/IAutomationForwarder.sol"; import {IChainModule} from "../interfaces/IChainModule.sol"; contract AutomationRegistryLogicB2_2 is AutomationRegistryBase2_2 { diff --git a/contracts/src/v0.8/automation/dev/v2_2/AutomationUtils2_2.sol b/contracts/src/v0.8/automation/v2_2/AutomationUtils2_2.sol similarity index 95% rename from contracts/src/v0.8/automation/dev/v2_2/AutomationUtils2_2.sol rename to contracts/src/v0.8/automation/v2_2/AutomationUtils2_2.sol index 2558937233a..bcd61ab9510 100644 --- a/contracts/src/v0.8/automation/dev/v2_2/AutomationUtils2_2.sol +++ b/contracts/src/v0.8/automation/v2_2/AutomationUtils2_2.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.19; import {AutomationRegistryBase2_2} from "./AutomationRegistryBase2_2.sol"; -import {Log} from "../../interfaces/ILogAutomation.sol"; +import {Log} from "../interfaces/ILogAutomation.sol"; /** * @notice this file exposes structs that are otherwise internal to the automation registry diff --git a/contracts/src/v0.8/automation/dev/v2_2/LICENSE b/contracts/src/v0.8/automation/v2_2/LICENSE similarity index 100% rename from contracts/src/v0.8/automation/dev/v2_2/LICENSE rename to contracts/src/v0.8/automation/v2_2/LICENSE diff --git a/contracts/src/v0.8/automation/dev/v2_2/README.md b/contracts/src/v0.8/automation/v2_2/README.md similarity index 100% rename from contracts/src/v0.8/automation/dev/v2_2/README.md rename to contracts/src/v0.8/automation/v2_2/README.md From f2f0d7ffd262427f992711d35673712f24a6f736 Mon Sep 17 00:00:00 2001 From: Damjan Smickovski <32773226+smickovskid@users.noreply.github.com> Date: Thu, 7 Mar 2024 10:24:23 +0100 Subject: [PATCH 31/34] Adding wildcard to overrides toml (#12329) --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index e56774fbefc..e10b07b9106 100644 --- a/.gitignore +++ b/.gitignore @@ -91,7 +91,7 @@ tools/flakeytests/coverage.txt **/testdata/fuzz/* # Runtime test configuration that might contain secrets -overrides.toml +override*.toml # Pythin venv .venv/ From e7f5e832787213e03006d931b9d38d8260638b45 Mon Sep 17 00:00:00 2001 From: Roman Kashitsyn Date: Thu, 7 Mar 2024 10:43:56 +0100 Subject: [PATCH 32/34] feat(relay): allow specifying queueing topics (#12238) * feat(relay): allow specifying queueing topics This change makes it possible to specify custom topic when calling newOnChainContractTransmitter. The use case is to be able to specify one topic per chain in CCIP. * use opts to pass the subjectID --- core/services/relay/evm/evm.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index 94d971b61e0..3797e6633a6 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" + "github.com/google/uuid" "github.com/jmoiron/sqlx" pkgerrors "github.com/pkg/errors" "golang.org/x/exp/maps" @@ -454,10 +455,13 @@ func (c *configWatcher) ContractConfigTracker() ocrtypes.ContractConfigTracker { } type configTransmitterOpts struct { - // override the gas limit default provided in the config watcher + // pluginGasLimit overrides the gas limit default provided in the config watcher. pluginGasLimit *uint32 + // subjectID overrides the queueing subject id (the job external id will be used by default). + subjectID *uuid.UUID } +// newOnChainContractTransmitter creates a new contract transmitter. func newOnChainContractTransmitter(ctx context.Context, lggr logger.Logger, rargs commontypes.RelayArgs, transmitterID string, ethKeystore keystore.Eth, configWatcher *configWatcher, opts configTransmitterOpts, transmissionContractABI abi.ABI) (*contractTransmitter, error) { var relayConfig types.RelayConfig if err := json.Unmarshal(rargs.RelayConfig, &relayConfig); err != nil { @@ -487,8 +491,12 @@ func newOnChainContractTransmitter(ctx context.Context, lggr logger.Logger, rarg fromAddresses = append(fromAddresses, common.HexToAddress(s)) } + subject := rargs.ExternalJobID + if opts.subjectID != nil { + subject = *opts.subjectID + } scoped := configWatcher.chain.Config() - strategy := txmgrcommon.NewQueueingTxStrategy(rargs.ExternalJobID, scoped.OCR2().DefaultTransactionQueueDepth(), scoped.Database().DefaultQueryTimeout()) + strategy := txmgrcommon.NewQueueingTxStrategy(subject, scoped.OCR2().DefaultTransactionQueueDepth(), scoped.Database().DefaultQueryTimeout()) var checker txm.TransmitCheckerSpec if configWatcher.chain.Config().OCR2().SimulateTransactions() { From daf251dcfc01a905ebfd47e14dffbb012a4e399e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Friedemann=20F=C3=BCrst?= <59653747+friedemannf@users.noreply.github.com> Date: Thu, 7 Mar 2024 11:33:11 +0100 Subject: [PATCH 33/34] zkSync - increase default gasLimit to 100M (SHIP-1227) (#12324) * zkSync - increase default gasLimit to 100M * regenerate CONFIG.md --- core/chains/evm/config/toml/defaults/zkSync_Goerli.toml | 2 +- core/chains/evm/config/toml/defaults/zkSync_Mainnet.toml | 2 +- docs/CONFIG.md | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/chains/evm/config/toml/defaults/zkSync_Goerli.toml b/core/chains/evm/config/toml/defaults/zkSync_Goerli.toml index 04529a41b81..be3bc22b812 100644 --- a/core/chains/evm/config/toml/defaults/zkSync_Goerli.toml +++ b/core/chains/evm/config/toml/defaults/zkSync_Goerli.toml @@ -6,7 +6,7 @@ MinIncomingConfirmations = 1 NoNewHeadsThreshold = '1m' [GasEstimator] -LimitDefault = 3_500_000 +LimitDefault = 100_000_000 PriceMax = 18446744073709551615 PriceMin = 0 diff --git a/core/chains/evm/config/toml/defaults/zkSync_Mainnet.toml b/core/chains/evm/config/toml/defaults/zkSync_Mainnet.toml index d7808edd15f..84ddac91db3 100644 --- a/core/chains/evm/config/toml/defaults/zkSync_Mainnet.toml +++ b/core/chains/evm/config/toml/defaults/zkSync_Mainnet.toml @@ -6,7 +6,7 @@ MinIncomingConfirmations = 1 NoNewHeadsThreshold = '1m' [GasEstimator] -LimitDefault = 3_500_000 +LimitDefault = 100_000_000 PriceMax = 18446744073709551615 PriceMin = 0 diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 938c3de66b1..97e356e7959 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -3058,7 +3058,7 @@ Mode = 'BlockHistory' PriceDefault = '20 gwei' PriceMax = '18.446744073709551615 ether' PriceMin = '0' -LimitDefault = 3500000 +LimitDefault = 100000000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 @@ -3142,7 +3142,7 @@ Mode = 'BlockHistory' PriceDefault = '20 gwei' PriceMax = '18.446744073709551615 ether' PriceMin = '0' -LimitDefault = 3500000 +LimitDefault = 100000000 LimitMax = 500000 LimitMultiplier = '1' LimitTransfer = 21000 From d907ceab584c3d4f2ca9894f93f0b1630281734b Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Thu, 7 Mar 2024 08:49:12 -0300 Subject: [PATCH 34/34] apply changes to readme.md, which previously escaped my attention (#12331) --- integration-tests/README.md | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/integration-tests/README.md b/integration-tests/README.md index 1ea3609f11e..80154a6dd13 100644 --- a/integration-tests/README.md +++ b/integration-tests/README.md @@ -14,9 +14,9 @@ If you have previously run these smoke tests using GitHub Actions or some sort o ## Configure -We have finished first pass at moving the configuration from env vars to TOML files. Currently all product-related configuration is already in TOML files, but env vars still are used to control things like log level, Slack notifications and Kubernetes-related settings. See the [example.env](./example.env) file for environment variables. +We have finished the first pass at moving all test configuration from env vars to TOML files. All product-related configuration is already in TOML files, but env vars are still used to control the log level, Slack notifications, and Kubernetes-related settings. See the [example.env](./example.env) file for how to set these environment variables. -We have added what we think are sensible defaults for all products, you can find them in `./testconfig//.toml` files. Each product folder contains also an `example.toml` file with all possible TOML keys and some description. Detailed description of TOML configuration can be found in [README.md](./testconfig/README.md), but if you want to run some tests using default value all you need to do is provide Chainlink image and version: +We have defined some sensible defaults for all products, you can find them in `./testconfig//.toml` files. Each product folder contains an `example.toml` file that describes all options. If you wish to override these values, you can do so by creating a `./testconfig/overrides.toml`. A detailed description of TOML configuration can be found in the [testconfig README](./testconfig/README.md), but if you want to run some tests using default values all you need to do is provide the Chainlink image and version you want to run tests on: ```toml # ./testconfig/overrides.toml @@ -25,15 +25,7 @@ image = "your image name" version = "your tag" ``` -You could also think about that config this way: -```toml -# ./testconfig/overrides.toml -[ChainlinkImage] -image = "${CHAINLINK_IMAGE}" -version = "${CHAINLINK_VERSION}" -``` - -Of course above just and example, in real world no substitution will take place unless you use some templating tool, but it should give you an idea on how to move from env vars to TOML files. **Remember** your runtime configuration needs to be placed in `./testconfig/overrides.toml` file **that should never be committed**. +The `./testconfig/overrides.toml` file **should never be committed** and has been added to the [.gitignore](../.gitignore) file as it can often contain secrets like private keys and RPC URLs. ## Build @@ -47,7 +39,7 @@ e.g. ## Run -Make sure you have `./testconfig/overrides.toml` file with your Chainlink image and version. +Ensure you have created a `./testconfig/overrides.toml` file with your desired Chainlink image and version. `go test ./smoke/_test.go`