diff --git a/.changeset/big-camels-report.md b/.changeset/big-camels-report.md new file mode 100644 index 00000000000..f81f66b9138 --- /dev/null +++ b/.changeset/big-camels-report.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#bugfix fix non-idempotent loopp registry.Register diff --git a/.changeset/fuzzy-yaks-deny.md b/.changeset/fuzzy-yaks-deny.md new file mode 100644 index 00000000000..6de0c8d096c --- /dev/null +++ b/.changeset/fuzzy-yaks-deny.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#added Lens Sepolia config diff --git a/.changeset/giant-eels-jump.md b/.changeset/giant-eels-jump.md new file mode 100644 index 00000000000..5ab8ca875ca --- /dev/null +++ b/.changeset/giant-eels-jump.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Add error handling for Arbitrum RPC server timeouts. #added diff --git a/.changeset/many-crews-wave.md b/.changeset/many-crews-wave.md new file mode 100644 index 00000000000..328a00e2f48 --- /dev/null +++ b/.changeset/many-crews-wave.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal refactor update nodes changeset to support mcms diff --git a/.changeset/six-coins-mix.md b/.changeset/six-coins-mix.md new file mode 100644 index 00000000000..2877aa3012a --- /dev/null +++ b/.changeset/six-coins-mix.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#bugfix fix: duplicate chain id in chain config dialog diff --git a/.changeset/spotty-seals-give.md b/.changeset/spotty-seals-give.md new file mode 100644 index 00000000000..1e3874a783f --- /dev/null +++ b/.changeset/spotty-seals-give.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Switching CCIP to observed ChainReader for HomeChainReader #internal diff --git a/.changeset/tiny-kangaroos-switch.md b/.changeset/tiny-kangaroos-switch.md new file mode 100644 index 00000000000..000f5b6bde5 --- /dev/null +++ b/.changeset/tiny-kangaroos-switch.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Added new fatal error cases for transactions to the Solana TXM. #added diff --git a/.github/actions/setup-ci-core-tests/action.yml b/.github/actions/setup-ci-core-tests/action.yml new file mode 100644 index 00000000000..a2cf3f4103c --- /dev/null +++ b/.github/actions/setup-ci-core-tests/action.yml @@ -0,0 +1,61 @@ +name: Setup CI Core Tests +description: | + Shared setup steps for ci-core. + Note: Other actions should not be called from this action. There is + weird behavior when nesting reusable actions. +inputs: + + go-mod-download-directory: + description: | + The directory to run go mod download in. If not provided, it will not run go mod download. + required: false + default: "" + + db-url: + description: | + The expected database URL + required: true + +runs: + using: composite + steps: + - name: Touching core/web/assets/index.html + shell: bash + run: mkdir -p core/web/assets && touch core/web/assets/index.html + + - name: Download Go vendor packages + shell: bash + run: go mod download + + - name: Go Mod Download (optional) + if: ${{ inputs.go-mod-download-directory != '' }} + shell: bash + working-directory: ${{ inputs.go-mod-download-directory }} + run: go mod download + + - name: Build binary + shell: bash + run: go build -o chainlink.test . + + - name: Setup DB + shell: bash + run: ./chainlink.test local db preparetest + env: + CL_DATABASE_URL: ${{ inputs.db-url }} + + - name: Install LOOP Plugins + shell: bash + run: | + pushd $(go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-feeds) + go install ./cmd/chainlink-feeds + popd + pushd $(go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-data-streams) + go install ./mercury/cmd/chainlink-mercury + popd + pushd $(go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-solana) + go install ./pkg/solana/cmd/chainlink-solana + popd + pushd $(go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-starknet/relayer) + go install ./pkg/chainlink/cmd/chainlink-starknet + popd + diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index d40d375f860..1bf55a64418 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -10,7 +10,7 @@ runner-test-matrix: # START: OCR tests # Example of 1 runner for all tests in integration-tests/smoke/ocr_test.go - - id: smoke/ocr_test.go:* + - id: smoke/ocr_test.go:* path: integration-tests/smoke/ocr_test.go test_env_type: docker runs_on: ubuntu-latest @@ -27,7 +27,7 @@ runner-test-matrix: runs_on: ubuntu-latest test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRv1Soak$ -test.parallel=1 -timeout 900h -count=1 -json test_cmd_opts: 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false - test_secrets_required: true + test_secrets_required: true test_env_vars: TEST_SUITE: soak @@ -60,7 +60,7 @@ runner-test-matrix: test_config_override_path: integration-tests/testconfig/ocr2/overrides/base_sepolia_quick_smoke_test.toml test_secrets_required: true test_env_vars: - TEST_SUITE: soak + TEST_SUITE: soak - id: soak/ocr_test.go:TestForwarderOCRv1Soak path: integration-tests/soak/ocr_test.go @@ -79,7 +79,7 @@ runner-test-matrix: test_secrets_required: true test_env_vars: TEST_SUITE: soak - + - id: soak/ocr_test.go:TestOCRSoak_GethReorgBelowFinality_FinalityTagDisabled path: integration-tests/soak/ocr_test.go test_env_type: k8s-remote-runner @@ -87,7 +87,7 @@ runner-test-matrix: test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run TestOCRSoak_GethReorgBelowFinality_FinalityTagDisabled -test.parallel=1 -timeout 900h -count=1 -json test_secrets_required: true test_env_vars: - TEST_SUITE: soak + TEST_SUITE: soak - id: soak/ocr_test.go:TestOCRSoak_GethReorgBelowFinality_FinalityTagEnabled path: integration-tests/soak/ocr_test.go @@ -96,7 +96,7 @@ runner-test-matrix: test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_GethReorgBelowFinality_FinalityTagEnabled$ -test.parallel=1 -timeout 900h -count=1 -json test_secrets_required: true test_env_vars: - TEST_SUITE: soak + TEST_SUITE: soak - id: soak/ocr_test.go:TestOCRSoak_GasSpike path: integration-tests/soak/ocr_test.go @@ -105,7 +105,7 @@ runner-test-matrix: test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_GasSpike$ -test.parallel=1 -timeout 900h -count=1 -json test_secrets_required: true test_env_vars: - TEST_SUITE: soak + TEST_SUITE: soak - id: soak/ocr_test.go:TestOCRSoak_ChangeBlockGasLimit path: integration-tests/soak/ocr_test.go @@ -114,7 +114,7 @@ runner-test-matrix: test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_ChangeBlockGasLimit$ -test.parallel=1 -timeout 900h -count=1 -json test_secrets_required: true test_env_vars: - TEST_SUITE: soak + TEST_SUITE: soak - id: soak/ocr_test.go:TestOCRSoak_RPCDownForAllCLNodes path: integration-tests/soak/ocr_test.go @@ -123,7 +123,7 @@ runner-test-matrix: test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_RPCDownForAllCLNodes$ -test.parallel=1 -timeout 900h -count=1 -json test_secrets_required: true test_env_vars: - TEST_SUITE: soak + TEST_SUITE: soak - id: soak/ocr_test.go:TestOCRSoak_RPCDownForHalfCLNodes path: integration-tests/soak/ocr_test.go @@ -132,7 +132,7 @@ runner-test-matrix: test_cmd: cd integration-tests/ && go test soak/ocr_test.go -v -test.run ^TestOCRSoak_RPCDownForHalfCLNodes$ -test.parallel=1 -timeout 900h -count=1 -json test_secrets_required: true test_env_vars: - TEST_SUITE: soak + TEST_SUITE: soak - id: smoke/forwarder_ocr_test.go:* path: integration-tests/smoke/forwarder_ocr_test.go @@ -168,7 +168,7 @@ runner-test-matrix: pyroscope_env: ci-smoke-ocr2-evm-simulated test_env_vars: E2E_TEST_CHAINLINK_VERSION: '{{ env.DEFAULT_CHAINLINK_PLUGINS_VERSION }}' # This is the chainlink version that has the plugins - + - id: smoke/ocr2_test.go:*-plugins path: integration-tests/smoke/ocr2_test.go test_env_type: docker @@ -197,7 +197,7 @@ runner-test-matrix: # END: OCR tests # START: Automation tests - + - id: smoke/automation_test.go:^TestAutomationBasic/registry_2_0|TestAutomationBasic/registry_2_1_conditional|TestAutomationBasic/registry_2_1_logtrigger$ path: integration-tests/smoke/automation_test.go test_env_type: docker @@ -273,7 +273,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run "^TestAutomationBasic/registry_2_3_with_mercury_v03_link|TestAutomationBasic/registry_2_3_with_logtrigger_and_mercury_v02_link$" -test.parallel=2 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-automation-evm-simulated + pyroscope_env: ci-smoke-automation-evm-simulated - id: smoke/automation_test.go:^TestSetUpkeepTriggerConfig$ path: integration-tests/smoke/automation_test.go @@ -284,7 +284,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestSetUpkeepTriggerConfig$ -test.parallel=2 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-automation-evm-simulated + pyroscope_env: ci-smoke-automation-evm-simulated - id: smoke/automation_test.go:^TestAutomationAddFunds$ path: integration-tests/smoke/automation_test.go @@ -295,7 +295,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationAddFunds$ -test.parallel=3 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-automation-evm-simulated + pyroscope_env: ci-smoke-automation-evm-simulated - id: smoke/automation_test.go:^TestAutomationPauseUnPause$ path: integration-tests/smoke/automation_test.go @@ -306,7 +306,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationPauseUnPause$ -test.parallel=3 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-automation-evm-simulated + pyroscope_env: ci-smoke-automation-evm-simulated - id: smoke/automation_test.go:^TestAutomationRegisterUpkeep$ path: integration-tests/smoke/automation_test.go @@ -317,7 +317,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationRegisterUpkeep$ -test.parallel=3 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-automation-evm-simulated + pyroscope_env: ci-smoke-automation-evm-simulated - id: smoke/automation_test.go:^TestAutomationPauseRegistry$ path: integration-tests/smoke/automation_test.go @@ -328,7 +328,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationPauseRegistry$ -test.parallel=3 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-automation-evm-simulated + pyroscope_env: ci-smoke-automation-evm-simulated - id: smoke/automation_test.go:^TestAutomationKeeperNodesDown$ path: integration-tests/smoke/automation_test.go @@ -339,7 +339,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationKeeperNodesDown$ -test.parallel=3 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-automation-evm-simulated + pyroscope_env: ci-smoke-automation-evm-simulated - id: smoke/automation_test.go:^TestAutomationPerformSimulation$ path: integration-tests/smoke/automation_test.go @@ -350,7 +350,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationPerformSimulation$ -test.parallel=3 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-automation-evm-simulated + pyroscope_env: ci-smoke-automation-evm-simulated - id: smoke/automation_test.go:^TestAutomationCheckPerformGasLimit$ path: integration-tests/smoke/automation_test.go @@ -361,7 +361,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationCheckPerformGasLimit$ -test.parallel=3 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-automation-evm-simulated + pyroscope_env: ci-smoke-automation-evm-simulated - id: smoke/automation_test.go:^TestUpdateCheckData$ path: integration-tests/smoke/automation_test.go @@ -372,7 +372,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestUpdateCheckData$ -test.parallel=3 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-automation-evm-simulated + pyroscope_env: ci-smoke-automation-evm-simulated - id: smoke/automation_test.go:^TestSetOffchainConfigWithMaxGasPrice$ path: integration-tests/smoke/automation_test.go @@ -383,7 +383,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestSetOffchainConfigWithMaxGasPrice$ -test.parallel=2 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-automation-evm-simulated + pyroscope_env: ci-smoke-automation-evm-simulated - id: smoke/keeper_test.go:^TestKeeperBasicSmoke$ path: integration-tests/smoke/keeper_test.go @@ -393,7 +393,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperBasicSmoke$ -test.parallel=3 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-keeper-evm-simulated + pyroscope_env: ci-smoke-keeper-evm-simulated - id: smoke/keeper_test.go:^TestKeeperBlockCountPerTurn$ path: integration-tests/smoke/keeper_test.go @@ -403,7 +403,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperBlockCountPerTurn$ -test.parallel=3 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-keeper-evm-simulated + pyroscope_env: ci-smoke-keeper-evm-simulated - id: smoke/keeper_test.go:^TestKeeperSimulation$ path: integration-tests/smoke/keeper_test.go @@ -413,7 +413,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperSimulation$ -test.parallel=2 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-keeper-evm-simulated + pyroscope_env: ci-smoke-keeper-evm-simulated - id: smoke/keeper_test.go:^TestKeeperCheckPerformGasLimit$ path: integration-tests/smoke/keeper_test.go @@ -423,7 +423,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperCheckPerformGasLimit$ -test.parallel=2 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-keeper-evm-simulated + pyroscope_env: ci-smoke-keeper-evm-simulated - id: smoke/keeper_test.go:^TestKeeperRegisterUpkeep$ path: integration-tests/smoke/keeper_test.go @@ -433,7 +433,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperRegisterUpkeep$ -test.parallel=3 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-keeper-evm-simulated + pyroscope_env: ci-smoke-keeper-evm-simulated - id: smoke/keeper_test.go:^TestKeeperAddFunds$ path: integration-tests/smoke/keeper_test.go @@ -443,7 +443,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperAddFunds$ -test.parallel=3 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-keeper-evm-simulated + pyroscope_env: ci-smoke-keeper-evm-simulated - id: smoke/keeper_test.go:^TestKeeperRemove$ path: integration-tests/smoke/keeper_test.go @@ -453,8 +453,8 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperRemove$ -test.parallel=3 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-keeper-evm-simulated - + pyroscope_env: ci-smoke-keeper-evm-simulated + - id: smoke/keeper_test.go:^TestKeeperPauseRegistry$ path: integration-tests/smoke/keeper_test.go test_env_type: docker @@ -463,7 +463,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperPauseRegistry$ -test.parallel=2 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-keeper-evm-simulated + pyroscope_env: ci-smoke-keeper-evm-simulated - id: smoke/keeper_test.go:^TestKeeperMigrateRegistry$ path: integration-tests/smoke/keeper_test.go @@ -473,7 +473,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperMigrateRegistry$ -test.parallel=1 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-keeper-evm-simulated + pyroscope_env: ci-smoke-keeper-evm-simulated - id: smoke/keeper_test.go:^TestKeeperNodeDown$ path: integration-tests/smoke/keeper_test.go @@ -483,7 +483,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperNodeDown$ -test.parallel=3 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-keeper-evm-simulated + pyroscope_env: ci-smoke-keeper-evm-simulated - id: smoke/keeper_test.go:^TestKeeperPauseUnPauseUpkeep$ path: integration-tests/smoke/keeper_test.go @@ -493,7 +493,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperPauseUnPauseUpkeep$ -test.parallel=1 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-keeper-evm-simulated + pyroscope_env: ci-smoke-keeper-evm-simulated - id: smoke/keeper_test.go:^TestKeeperUpdateCheckData$ path: integration-tests/smoke/keeper_test.go @@ -503,7 +503,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperUpdateCheckData$ -test.parallel=1 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-keeper-evm-simulated + pyroscope_env: ci-smoke-keeper-evm-simulated - id: smoke/keeper_test.go:^TestKeeperJobReplacement$ path: integration-tests/smoke/keeper_test.go @@ -513,7 +513,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestKeeperJobReplacement$ -test.parallel=1 -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-keeper-evm-simulated + pyroscope_env: ci-smoke-keeper-evm-simulated - id: load/automationv2_1/automationv2_1_test.go:TestLogTrigger path: integration-tests/load/automationv2_1/automationv2_1_test.go @@ -546,7 +546,7 @@ runner-test-matrix: test_env_type: docker runs_on: ubuntu22.04-8cores-32GB triggers: - - Automation Nightly Tests + - Automation Nightly Tests test_cmd: cd integration-tests/smoke && go test -test.run ^TestAutomationNodeUpgrade/registry_2_1 -test.parallel=5 -timeout 60m -count=1 -json test_env_vars: E2E_TEST_CHAINLINK_IMAGE: public.ecr.aws/chainlink/chainlink @@ -676,7 +676,7 @@ runner-test-matrix: test_env_vars: TEST_TYPE: Smoke triggers: - - On Demand VRFV2 Plus Performance Test + - On Demand VRFV2 Plus Performance Test - id: load/vrfv2plus/vrfv2plus_test.go:^TestVRFV2PlusBHSPerformance$Smoke path: integration-tests/load/vrfv2plus/vrfv2plus_test.go @@ -688,7 +688,7 @@ runner-test-matrix: test_env_vars: TEST_TYPE: Smoke triggers: - - On Demand VRFV2 Plus Performance Test + - On Demand VRFV2 Plus Performance Test - id: load/vrfv2/vrfv2_test.go:^TestVRFV2Performance$Smoke path: integration-tests/load/vrfv2/vrfv2_test.go @@ -698,9 +698,9 @@ runner-test-matrix: test_config_override_required: true test_secrets_required: true test_env_vars: - TEST_TYPE: Smoke + TEST_TYPE: Smoke triggers: - - On Demand VRFV2 Performance Test + - On Demand VRFV2 Performance Test - id: load/vrfv2/vrfv2_test.go:^TestVRFV2PlusBHSPerformance$Smoke path: integration-tests/load/vrfv2/vrfv2_test.go @@ -892,7 +892,7 @@ runner-test-matrix: - Merge Queue E2E Core Tests - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/flux_test.go -timeout 30m -count=1 -json - pyroscope_env: ci-smoke-flux-evm-simulated + pyroscope_env: ci-smoke-flux-evm-simulated - id: smoke/reorg_above_finality_test.go:* path: integration-tests/smoke/reorg_above_finality_test.go @@ -904,7 +904,7 @@ runner-test-matrix: - Nightly E2E Tests test_cmd: cd integration-tests/ && go test smoke/reorg_above_finality_test.go -timeout 30m -count=1 -json pyroscope_env: ci-smoke-reorg-above-finality-evm-simulated - + - id: migration/upgrade_version_test.go:* path: integration-tests/migration/upgrade_version_test.go test_env_type: docker @@ -935,32 +935,6 @@ runner-test-matrix: # START: CCIPv1.6 tests - - id: smoke/ccip/ccip_test.go:* - path: integration-tests/smoke/ccip/ccip_test.go - test_env_type: docker - runs_on: ubuntu-latest - triggers: - - PR E2E Core Tests - - Nightly E2E Tests - test_cmd: cd integration-tests/smoke/ccip && go test ccip_test.go -timeout 25m -test.parallel=2 -count=1 -json - pyroscope_env: ci-smoke-ccipv1_6-evm-simulated - test_env_vars: - E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 - E2E_JD_VERSION: 0.6.0 - - - id: smoke/ccip/ccip_message_limitations_test.go:* - path: integration-tests/smoke/ccip/ccip_message_limitations_test.go - test_env_type: docker - runs_on: ubuntu-latest - triggers: - - PR E2E Core Tests - - Nightly E2E Tests - test_cmd: cd integration-tests/smoke/ccip && go test -run '^Test_CCIPMessageLimitations' -timeout 18m -test.parallel=1 -count=1 -json ./... - pyroscope_env: ci-smoke-ccipv1_6-evm-simulated - test_env_vars: - E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 - E2E_JD_VERSION: 0.6.0 - - id: smoke/ccip/ccip_token_price_updates_test.go:* path: integration-tests/smoke/ccip/ccip_token_price_updates_test.go test_env_type: docker @@ -973,6 +947,7 @@ runner-test-matrix: test_env_vars: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 E2E_JD_VERSION: 0.6.0 + CCIP_V16_TEST_ENV: docker - id: smoke/ccip/ccip_gas_price_updates_test.go:* path: integration-tests/smoke/ccip/ccip_gas_price_updates_test.go @@ -986,6 +961,7 @@ runner-test-matrix: test_env_vars: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 E2E_JD_VERSION: 0.6.0 + CCIP_V16_TEST_ENV: docker - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_TwoMessagesOnTwoLanesIncludingBatching$ path: integration-tests/smoke/ccip/ccip_rmn_test.go @@ -1001,6 +977,7 @@ runner-test-matrix: E2E_JD_VERSION: 0.6.0 E2E_RMN_RAGEPROXY_VERSION: master-f461a9e E2E_RMN_AFN2PROXY_VERSION: master-f461a9e + CCIP_V16_TEST_ENV: docker - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_MultipleMessagesOnOneLaneNoWaitForExec$ path: integration-tests/smoke/ccip/ccip_rmn_test.go @@ -1016,6 +993,7 @@ runner-test-matrix: E2E_JD_VERSION: 0.6.0 E2E_RMN_RAGEPROXY_VERSION: master-f461a9e E2E_RMN_AFN2PROXY_VERSION: master-f461a9e + CCIP_V16_TEST_ENV: docker - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_NotEnoughObservers$ path: integration-tests/smoke/ccip/ccip_rmn_test.go @@ -1031,6 +1009,7 @@ runner-test-matrix: E2E_JD_VERSION: 0.6.0 E2E_RMN_RAGEPROXY_VERSION: master-f461a9e E2E_RMN_AFN2PROXY_VERSION: master-f461a9e + CCIP_V16_TEST_ENV: docker - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_DifferentSigners$ path: integration-tests/smoke/ccip/ccip_rmn_test.go @@ -1046,6 +1025,7 @@ runner-test-matrix: E2E_JD_VERSION: 0.6.0 E2E_RMN_RAGEPROXY_VERSION: master-f461a9e E2E_RMN_AFN2PROXY_VERSION: master-f461a9e + CCIP_V16_TEST_ENV: docker - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_NotEnoughSigners$ path: integration-tests/smoke/ccip/ccip_rmn_test.go @@ -1061,6 +1041,7 @@ runner-test-matrix: E2E_JD_VERSION: 0.6.0 E2E_RMN_RAGEPROXY_VERSION: master-f461a9e E2E_RMN_AFN2PROXY_VERSION: master-f461a9e + CCIP_V16_TEST_ENV: docker - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_DifferentRmnNodesForDifferentChains$ path: integration-tests/smoke/ccip/ccip_rmn_test.go @@ -1076,6 +1057,7 @@ runner-test-matrix: E2E_JD_VERSION: 0.6.0 E2E_RMN_RAGEPROXY_VERSION: master-f461a9e E2E_RMN_AFN2PROXY_VERSION: master-f461a9e + CCIP_V16_TEST_ENV: docker - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_TwoMessagesOneSourceChainCursed$ path: integration-tests/smoke/ccip/ccip_rmn_test.go @@ -1091,6 +1073,7 @@ runner-test-matrix: E2E_JD_VERSION: 0.6.0 E2E_RMN_RAGEPROXY_VERSION: master-f461a9e E2E_RMN_AFN2PROXY_VERSION: master-f461a9e + CCIP_V16_TEST_ENV: docker - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_GlobalCurseTwoMessagesOnTwoLanes$ path: integration-tests/smoke/ccip/ccip_rmn_test.go @@ -1106,6 +1089,7 @@ runner-test-matrix: E2E_JD_VERSION: 0.6.0 E2E_RMN_RAGEPROXY_VERSION: master-f461a9e E2E_RMN_AFN2PROXY_VERSION: master-f461a9e + CCIP_V16_TEST_ENV: docker # END: CCIPv1.6 tests @@ -1122,7 +1106,8 @@ runner-test-matrix: test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPForBidirectionalLane$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 - + CHAINLINK_USER_TEAM: CCIP + - id: ccip-smoke-usdc path: integration-tests/ccip-tests/smoke/ccip_test.go test_env_type: docker @@ -1134,6 +1119,7 @@ runner-test-matrix: test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPForBidirectionalLane$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + CHAINLINK_USER_TEAM: CCIP test_config_override_path: integration-tests/ccip-tests/testconfig/tomls/usdc_mock_deployment.toml - id: ccip-smoke-db-compatibility @@ -1147,6 +1133,7 @@ runner-test-matrix: test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPForBidirectionalLane$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + CHAINLINK_USER_TEAM: CCIP test_config_override_path: integration-tests/ccip-tests/testconfig/tomls/db-compatibility.toml - id: ccip-smoke-leader-lane @@ -1173,6 +1160,7 @@ runner-test-matrix: test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPTokenPoolRateLimits$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + CHAINLINK_USER_TEAM: CCIP - id: ccip-tests/smoke/ccip_test.go:^TestSmokeCCIPMulticall$ path: integration-tests/ccip-tests/smoke/ccip_test.go @@ -1185,6 +1173,7 @@ runner-test-matrix: test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPMulticall$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + CHAINLINK_USER_TEAM: CCIP - id: ccip-tests/smoke/ccip_test.go:^TestSmokeCCIPManuallyExecuteAfterExecutionFailingDueToInsufficientGas$ path: integration-tests/ccip-tests/smoke/ccip_test.go @@ -1197,6 +1186,7 @@ runner-test-matrix: test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPManuallyExecuteAfterExecutionFailingDueToInsufficientGas$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + CHAINLINK_USER_TEAM: CCIP - id: ccip-tests/smoke/ccip_test.go:^TestSmokeCCIPOnRampLimits$ path: integration-tests/ccip-tests/smoke/ccip_test.go @@ -1209,6 +1199,7 @@ runner-test-matrix: test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPOnRampLimits$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + CHAINLINK_USER_TEAM: CCIP - id: ccip-tests/smoke/ccip_test.go:^TestSmokeCCIPOffRampCapacityLimit$ path: integration-tests/ccip-tests/smoke/ccip_test.go @@ -1218,7 +1209,8 @@ runner-test-matrix: - Nightly E2E Tests test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPOffRampCapacityLimit$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: - E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + CHAINLINK_USER_TEAM: CCIP - id: ccip-tests/smoke/ccip_test.go:^TestSmokeCCIPOffRampAggRateLimit$ path: integration-tests/ccip-tests/smoke/ccip_test.go @@ -1229,6 +1221,7 @@ runner-test-matrix: test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPOffRampAggRateLimit$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + CHAINLINK_USER_TEAM: CCIP - id: ccip-tests/smoke/ccip_test.go:^TestSmokeCCIPReorgBelowFinality$ path: integration-tests/ccip-tests/smoke/ccip_test.go @@ -1241,6 +1234,7 @@ runner-test-matrix: test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPReorgBelowFinality$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + CHAINLINK_USER_TEAM: CCIP test_config_override_path: integration-tests/ccip-tests/testconfig/tomls/ccip-reorg.toml - id: ccip-tests/smoke/ccip_test.go:^TestSmokeCCIPReorgAboveFinalityAtDestination$ @@ -1254,6 +1248,7 @@ runner-test-matrix: test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPReorgAboveFinalityAtDestination$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + CHAINLINK_USER_TEAM: CCIP test_config_override_path: integration-tests/ccip-tests/testconfig/tomls/ccip-reorg.toml - id: ccip-tests/smoke/ccip_test.go:^TestSmokeCCIPReorgAboveFinalityAtSource$ @@ -1267,6 +1262,7 @@ runner-test-matrix: test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPReorgAboveFinalityAtSource$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 + CHAINLINK_USER_TEAM: CCIP test_config_override_path: integration-tests/ccip-tests/testconfig/tomls/ccip-reorg.toml - id: integration-tests/ccip-tests/load/ccip_test.go:TestLoadCCIPStableRPS @@ -1278,8 +1274,8 @@ runner-test-matrix: TEST_SUITE: ccip-load E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/6vjVx-1V8/ccip-long-running-tests" triggers: - - E2E CCIP Load Tests - test_artifacts_on_failure: + - E2E CCIP Load Tests + test_artifacts_on_failure: - ./integration-tests/load/logs/payload_ccip.json # Enable when CCIP-2277 is resolved @@ -1293,8 +1289,8 @@ runner-test-matrix: # test_env_vars: # E2E_TEST_GRAFANA_DASHBOARD_URL: "/d/6vjVx-1V8/ccip-long-running-tests" # triggers: - # - E2E CCIP Load Tests - # test_artifacts_on_failure: + # - E2E CCIP Load Tests + # test_artifacts_on_failure: # - ./integration-tests/load/logs/payload_ccip.json - id: ccip-tests/chaos/ccip_test.go @@ -1322,5 +1318,5 @@ runner-test-matrix: TEST_TRIGGERED_BY: ccip-cron-chaos-eth TEST_LOG_LEVEL: debug E2E_TEST_GRAFANA_DASHBOARD_URL: /d/6vjVx-1V8/ccip-long-running-tests - + # END: CCIP tests diff --git a/.github/integration-in-memory-tests.yml b/.github/integration-in-memory-tests.yml index b7522274d85..9550d74f21f 100644 --- a/.github/integration-in-memory-tests.yml +++ b/.github/integration-in-memory-tests.yml @@ -23,6 +23,14 @@ runner-test-matrix: triggers: - PR Integration CCIP Tests test_cmd: cd integration-tests/smoke/ccip && go test ccip_messaging_test.go -timeout 12m -test.parallel=2 -count=1 -json + + - id: smoke/ccip/ccip_message_limitations_test.go:* + path: integration-tests/smoke/ccip/ccip_message_limitations_test.go + test_env_type: in-memory + runs_on: ubuntu-latest + triggers: + - PR Integration CCIP Tests + test_cmd: cd integration-tests/smoke/ccip && go test -run "Test_CCIPMessageLimitations" -timeout 12m -test.parallel=2 -count=1 -json - id: smoke/ccip/ccip_fee_boosting_test.go:* path: integration-tests/smoke/ccip/ccip_fee_boosting_test.go diff --git a/.github/workflows/ci-core-partial.yml b/.github/workflows/ci-core-partial.yml new file mode 100644 index 00000000000..c9752d4e1e4 --- /dev/null +++ b/.github/workflows/ci-core-partial.yml @@ -0,0 +1,287 @@ +name: Core Unit Tests + +on: + push: + branches: + - develop + # - "release/*" + # merge_group: + pull_request: + schedule: + - cron: "0 1 * * *" + +env: + # We explicitly have this env var not be "CL_DATABASE_URL" to avoid having it be used by core related tests + # when they should not be using it, while still allowing us to DRY up the setup + DB_URL: postgresql://postgres:postgres@localhost:5432/chainlink_test?sslmode=disable + +jobs: + filter: + name: Detect Changes + permissions: + pull-requests: read + outputs: + should-run-all-tests: ${{ steps.match-some.outputs.test-data == 'true' }} + should-collect-coverage: ${{ github.event_name == 'schedule' }} + runs-on: ubuntu-latest + steps: + - name: Checkout the repo + uses: actions/checkout@v4.2.1 + with: + repository: smartcontractkit/chainlink + - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 + id: match-some + with: + # "if any changed file matches one or more of the conditions" (https://github.com/dorny/paths-filter/issues/225) + predicate-quantifier: some + # test-data - any changes to any testdata files/paths + filters: | + test-data: + - '**/testdata/**' + + run-unit-tests: + name: Tests (${{ matrix.type.test-suite }}) + needs: filter + runs-on: ubuntu22.04-32cores-128GB + permissions: + id-token: write + contents: write + strategy: + fail-fast: false + matrix: + type: + - test-suite: "core" + module-directory: "./" + build-flags: "-tags=integration" + - test-suite: "ccip-deployment" + module-directory: "./deployment" + steps: + - name: Checkout the repo + uses: actions/checkout@v4.2.1 + + - name: Setup NodeJS + uses: ./.github/actions/setup-nodejs + with: + prod: "true" + + - name: Setup Go + uses: ./.github/actions/setup-go + with: + build-cache-version: ${{ matrix.type.test-suite }} + restore-build-cache-only: "false" + + - name: Setup Solana + uses: ./.github/actions/setup-solana + + - name: Setup wasmd + uses: ./.github/actions/setup-wasmd + + - name: Setup Postgres + uses: ./.github/actions/setup-postgres + + - name: Setup CI Core Environment + uses: ./.github/actions/setup-ci-core-tests + with: + db-url: ${{ env.DB_URL }} + go-mod-download-directory: ${{ matrix.type.test-suite == 'ccip-deployment' && matrix.type.module-directory || '' }} + + - name: Build Tests + uses: smartcontractkit/.github/apps/go-conditional-tests@37882e110590e636627a26371bdbd56ddfcce821 # go-conditional-tests@0.1.0 + timeout-minutes: 10 + with: + pipeline-step: "build" + build-concurrency: "32" + collect-coverage: ${{ needs.filter.outputs.should-collect-coverage }} + test-suite: ${{ matrix.type.test-suite }} + module-directory: ${{ matrix.type.module-directory }} + github-token: ${{ secrets.GITHUB_TOKEN }} + build-flags: ${{ matrix.type.build-flags }} + + - name: Run Tests + uses: smartcontractkit/.github/apps/go-conditional-tests@37882e110590e636627a26371bdbd56ddfcce821 # go-conditional-tests@0.1.0 + timeout-minutes: 15 + env: + CL_DATABASE_URL: ${{ env.DB_URL }} + with: + pipeline-step: "run" + run-concurrency: "16" + run-all-tests: ${{ needs.filter.outputs.should-run-all-tests }} + collect-coverage: ${{ needs.filter.outputs.should-collect-coverage }} + test-suite: ${{ matrix.type.test-suite }} + module-directory: ${{ matrix.type.module-directory }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Update Test Index + uses: smartcontractkit/.github/apps/go-conditional-tests@37882e110590e636627a26371bdbd56ddfcce821 # go-conditional-tests@0.1.0 + with: + pipeline-step: "update" + collect-coverage: ${{ needs.filter.outputs.should-collect-coverage }} + test-suite: ${{ matrix.type.test-suite }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Print postgres logs + if: ${{ always() }} + run: docker compose logs postgres | tee ../../../postgres_logs.txt + working-directory: ./.github/actions/setup-postgres + + scan: + name: SonarQube Scan + needs: [run-unit-tests, filter] + if: ${{ needs.filter.outputs.should-collect-coverage == 'true' }} + runs-on: ubuntu-latest + steps: + - name: Checkout the repo + uses: actions/checkout@v4.2.1 + with: + # fetches all history for all tags and branches to provide more metadata for sonar reports + fetch-depth: 0 + + - name: Download all workflow run artifacts + uses: actions/download-artifact@v4.1.8 + with: + path: coverage + pattern: coverage-* + merge-multiple: true + + - name: Check and Set SonarQube Report Paths + shell: bash + run: | + ARGS="" + sonarqube_coverage_report_paths=$(find ./coverage -name '*.cover.out' | paste -sd "," -) + + # TODO uncomment when linting in enabled + # Check and assign paths for lint reports + # if [ -d "golangci-lint-report" ]; then + # sonarqube_lint_report_paths=$(find golangci-lint-report -name 'golangci-lint-report.xml' | paste -sd "," -) + # else + # sonarqube_lint_report_paths="" + # fi + # if [[ -z "$sonarqube_lint_report_paths" ]]; then + # echo "::warning::No lint report paths found, will not pass to sonarqube" + # else + # echo "Found lint report paths: $sonarqube_lint_report_paths" + # ARGS="$ARGS -Dsonar.go.golangci-lint.reportPaths=$sonarqube_lint_report_paths" + # fi + + if [[ -z "$sonarqube_coverage_report_paths" ]]; then + echo "::warning::No coverage report paths found, will not pass to sonarqube" + else + echo "Found coverage report paths: $sonarqube_coverage_report_paths" + ARGS="$ARGS -Dsonar.go.coverage.reportPaths=$sonarqube_coverage_report_paths" + fi + + echo "Final SONARQUBE_ARGS: $ARGS" + echo "SONARQUBE_ARGS=$ARGS" >> $GITHUB_ENV + + - name: SonarQube Scan + if: ${{ env.SONARQUBE_ARGS != '' }} + uses: sonarsource/sonarqube-scan-action@aecaf43ae57e412bd97d70ef9ce6076e672fe0a9 # v2.3.0 + with: + args: ${{ env.SONARQUBE_ARGS }} + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + SONAR_SCANNER_OPTS: "-Xms6g -Xmx8g" + + run-fuzz-tests: + name: Tests (fuzz) + runs-on: ubuntu22.04-32cores-128GB + if: ${{ github.event_name == 'schedule' }} + steps: + - name: Checkout the repo + uses: actions/checkout@v4.2.1 + + - name: Setup Go + uses: ./.github/actions/setup-go + with: + build-cache-version: "fuzz" + restore-build-cache-only: "true" + + - name: Setup Solana + uses: ./.github/actions/setup-solana + + - name: Setup wasmd + uses: ./.github/actions/setup-wasmd + + - name: Setup Postgres + uses: ./.github/actions/setup-postgres + + - name: Setup CI Core Environment + uses: ./.github/actions/setup-ci-core-tests + with: + db-url: ${{ env.DB_URL }} + + - name: Increase Timeouts + if: ${{ github.event_name == 'schedule'}} + run: | + echo "FUZZ_TIMEOUT_MINUTES=10">> $GITHUB_ENV + + - name: Run Fuzz Tests + env: + OUTPUT_FILE: ./output.txt + CL_DATABASE_URL: ${{ env.DB_URL }} + run: ./tools/bin/go_core_fuzz ./... + + - name: Print postgres logs + if: ${{ always() }} + run: docker compose logs postgres | tee ../../../postgres_logs.txt + working-directory: ./.github/actions/setup-postgres + + run-race-tests: + name: Tests (race) + runs-on: ubuntu22.04-32cores-128GB + if: ${{ github.event_name == 'schedule' }} + steps: + - name: Checkout the repo + uses: actions/checkout@v4.2.1 + + - name: Setup Go + uses: ./.github/actions/setup-go + with: + build-cache-version: "race" + restore-build-cache-only: "true" + + - name: Setup Solana + uses: ./.github/actions/setup-solana + + - name: Setup wasmd + uses: ./.github/actions/setup-wasmd + + - name: Setup Postgres + uses: ./.github/actions/setup-postgres + + - name: Setup CI Core Environment + uses: ./.github/actions/setup-ci-core-tests + with: + db-url: ${{ env.DB_URL }} + + - name: Increase Timeouts + if: ${{ github.event_name == 'schedule'}} + run: | + echo "TIMEOUT=10m" >> $GITHUB_ENV + echo "COUNT=50" >> $GITHUB_ENV + + - name: Run Race Tests + env: + OUTPUT_FILE: ./output.txt + CL_DATABASE_URL: ${{ env.DB_URL }} + run: ./tools/bin/go_core_race_tests ./... + + - name: Print Races + id: print-races + if: ${{ failure() }} + run: | + find race.* | xargs cat > race.txt + if [[ -s race.txt ]]; then + cat race.txt + echo "post_to_slack=true" >> $GITHUB_OUTPUT + else + echo "post_to_slack=false" >> $GITHUB_OUTPUT + fi + echo "github.event_name: ${{ github.event_name }}" + echo "github.ref: ${{ github.ref }}" + + - name: Print postgres logs + if: ${{ always() }} + run: docker compose logs postgres | tee ../../../postgres_logs.txt + working-directory: ./.github/actions/setup-postgres diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index c38ecd918ae..9134a8c9b56 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -466,6 +466,7 @@ jobs: extraArgs: '{ "skipped_tests": "TestChainComponents", "run_with_race": "true", "print_failed_tests": "true", "test_repeat_count": "3", "min_pass_ratio": "0.01" }' secrets: SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} trigger-flaky-test-detection-for-deployment-project: name: Flakeguard Deployment Project @@ -484,6 +485,7 @@ jobs: extraArgs: '{ "skipped_tests": "TestAddLane", "run_with_race": "true", "print_failed_tests": "true", "test_repeat_count": "3", "min_pass_ratio": "0.01" }' secrets: SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} clean: name: Clean Go Tidy & Generate diff --git a/.github/workflows/client-compatibility-tests.yml b/.github/workflows/client-compatibility-tests.yml index 03c5b893cca..5f986ccf16c 100644 --- a/.github/workflows/client-compatibility-tests.yml +++ b/.github/workflows/client-compatibility-tests.yml @@ -668,9 +668,6 @@ jobs: E2E_TEST_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} E2E_TEST_PYROSCOPE_ENVIRONMENT: ci-client-compatability-${{ matrix.eth_client }}-testnet E2E_TEST_PYROSCOPE_ENABLED: "true" - E2E_TEST_LOGGING_RUN_ID: ${{ github.run_id }} - E2E_TEST_LOG_COLLECT: ${{ vars.TEST_LOG_COLLECT }} - E2E_TEST_LOG_STREAM_LOG_TARGETS: ${{ vars.LOGSTREAM_LOG_TARGETS }} E2E_TEST_PRIVATE_ETHEREUM_EXECUTION_LAYER: ${{ matrix.evm_node.eth_implementation || 'geth' }} E2E_TEST_PRIVATE_ETHEREUM_ETHEREUM_VERSION: auto_fill # Auto fill the version based on the docker image E2E_TEST_PRIVATE_ETHEREUM_CUSTOM_DOCKER_IMAGE: ${{ matrix.evm_node.docker_image }} diff --git a/.github/workflows/flakeguard-nightly.yml b/.github/workflows/flakeguard-nightly.yml index 37c00fa0a8f..178d43d809a 100644 --- a/.github/workflows/flakeguard-nightly.yml +++ b/.github/workflows/flakeguard-nightly.yml @@ -20,3 +20,5 @@ jobs: slackNotificationAfterTestsChannelId: 'C07TRF65CNS' #flaky-test-detector-notifications secrets: SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + diff --git a/.github/workflows/flakeguard-on-demand.yml b/.github/workflows/flakeguard-on-demand.yml index fe972894594..0ba84c5ab58 100644 --- a/.github/workflows/flakeguard-on-demand.yml +++ b/.github/workflows/flakeguard-on-demand.yml @@ -69,4 +69,5 @@ jobs: extraArgs: ${{ inputs.extraArgs }} secrets: SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/flakeguard.yml b/.github/workflows/flakeguard.yml index ecc56e2f291..4c1aa695c62 100644 --- a/.github/workflows/flakeguard.yml +++ b/.github/workflows/flakeguard.yml @@ -52,20 +52,21 @@ on: secrets: SLACK_BOT_TOKEN: required: false + GH_TOKEN: + required: true env: GIT_HEAD_REF: ${{ inputs.headRef || github.ref }} - SKIPPED_TESTS: ${{ fromJson(inputs.extraArgs)['skipped_tests'] || '' }} # Comma separated list of test names to skip running in the flaky detector. Related issue: TT-1823 - DEFAULT_MAX_RUNNER_COUNT: ${{ fromJson(inputs.extraArgs)['default_max_runner_count'] || '8' }} # The default maximum number of GitHub runners to use for parallel test execution. - ALL_TESTS_RUNNER_COUNT: ${{ fromJson(inputs.extraArgs)['all_tests_runner_count'] || '2' }} # The number of GitHub runners to use when running all tests `runAllTests=true`. - TEST_REPEAT_COUNT: ${{ fromJson(inputs.extraArgs)['test_repeat_count'] || '5' }} # The number of times each runner should run a test to detect flaky tests. - RUN_WITH_RACE: ${{ fromJson(inputs.extraArgs)['run_with_race'] || 'true' }} # Whether to run tests with -race flag. - RUN_WITH_SHUFFLE: ${{ fromJson(inputs.extraArgs)['run_with_shuffle'] || 'false' }} # Whether to run tests with -shuffle flag. - SHUFFLE_SEED: ${{ fromJson(inputs.extraArgs)['shuffle_seed'] || '999' }} # The seed to use when -shuffle flag is enabled. Requires RUN_WITH_SHUFFLE to be true. - ALL_TESTS_RUNNER: ${{ fromJson(inputs.extraArgs)['all_tests_runner'] || 'ubuntu22.04-32cores-128GB' }} # The runner to use for running all tests. + SKIPPED_TESTS: ${{ fromJSON(inputs.extraArgs)['skipped_tests'] || '' }} # Comma separated list of test names to skip running in the flaky detector. Related issue: TT-1823 + DEFAULT_MAX_RUNNER_COUNT: ${{ fromJSON(inputs.extraArgs)['default_max_runner_count'] || '8' }} # The default maximum number of GitHub runners to use for parallel test execution. + ALL_TESTS_RUNNER_COUNT: ${{ fromJSON(inputs.extraArgs)['all_tests_runner_count'] || '2' }} # The number of GitHub runners to use when running all tests `runAllTests=true`. + TEST_REPEAT_COUNT: ${{ fromJSON(inputs.extraArgs)['test_repeat_count'] || '5' }} # The number of times each runner should run a test to detect flaky tests. + RUN_WITH_RACE: ${{ fromJSON(inputs.extraArgs)['run_with_race'] || 'true' }} # Whether to run tests with -race flag. + RUN_WITH_SHUFFLE: ${{ fromJSON(inputs.extraArgs)['run_with_shuffle'] || 'false' }} # Whether to run tests with -shuffle flag. + SHUFFLE_SEED: ${{ fromJSON(inputs.extraArgs)['shuffle_seed'] || '999' }} # The seed to use when -shuffle flag is enabled. Requires RUN_WITH_SHUFFLE to be true. + ALL_TESTS_RUNNER: ${{ fromJSON(inputs.extraArgs)['all_tests_runner'] || 'ubuntu22.04-32cores-128GB' }} # The runner to use for running all tests. DEFAULT_RUNNER: 'ubuntu-latest' # The default runner to use for running tests. - UPLOAD_ALL_TEST_RESULTS: ${{ fromJson(inputs.extraArgs)['upload_all_test_results'] || 'false' }} # Whether to upload all test results as artifacts. - PRINT_FAILED_TESTS: ${{ fromJson(inputs.extraArgs)['print_failed_tests'] || 'false' }} # Whether to print failed tests in the GitHub console. + UPLOAD_ALL_TEST_RESULTS: ${{ fromJSON(inputs.extraArgs)['upload_all_test_results'] || 'false' }} # Whether to upload all test results as artifacts. jobs: @@ -101,7 +102,7 @@ jobs: - name: Install flakeguard shell: bash - run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@9e40f2765df01f20b3bf53f0fb3ead920e3a1f4a # flakguard@0.1.0 + run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@404e04e1e2e2dd5a384b09bd05b8d80409b6609a # flakguard@0.1.0 - name: Find new or updated test packages if: ${{ inputs.runAllTests == false }} @@ -196,11 +197,11 @@ jobs: needs: get-tests runs-on: ${{ matrix.runs_on }} if: ${{ needs.get-tests.outputs.matrix != '' && needs.get-tests.outputs.matrix != '[]' }} - timeout-minutes: 90 + timeout-minutes: 180 strategy: fail-fast: false matrix: - include: ${{ fromJson(needs.get-tests.outputs.matrix) }} + include: ${{ fromJSON(needs.get-tests.outputs.matrix) }} env: DB_URL: postgresql://postgres:postgres@localhost:5432/chainlink_test?sslmode=disable steps: @@ -260,11 +261,11 @@ jobs: - name: Install flakeguard shell: bash - run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@9e40f2765df01f20b3bf53f0fb3ead920e3a1f4a # flakguard@0.1.0 + run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@404e04e1e2e2dd5a384b09bd05b8d80409b6609a # flakguard@0.1.0 - name: Run tests with flakeguard shell: bash - run: flakeguard run --project-path=${{ inputs.projectPath }} --test-packages=${{ matrix.testPackages }} --run-count=${{ env.TEST_REPEAT_COUNT }} --max-pass-ratio=${{ inputs.maxPassRatio }} --race=${{ env.RUN_WITH_RACE }} --shuffle=${{ env.RUN_WITH_SHUFFLE }} --shuffle-seed=${{ env.SHUFFLE_SEED }} --skip-tests=${{ env.SKIPPED_TESTS }} --print-failed-tests=${{ env.PRINT_FAILED_TESTS }} --output-json=test-result.json + run: flakeguard run --project-path=${{ inputs.projectPath }} --test-packages=${{ matrix.testPackages }} --run-count=${{ env.TEST_REPEAT_COUNT }} --max-pass-ratio=${{ inputs.maxPassRatio }} --race=${{ env.RUN_WITH_RACE }} --shuffle=${{ env.RUN_WITH_SHUFFLE }} --shuffle-seed=${{ env.SHUFFLE_SEED }} --skip-tests=${{ env.SKIPPED_TESTS }} --output-json=test-result.json env: CL_DATABASE_URL: ${{ env.DB_URL }} @@ -280,9 +281,9 @@ jobs: needs: [get-tests, run-tests] if: always() name: Report - runs-on: ubuntu-latest + runs-on: ubuntu-24.04-8cores-32GB-ARM # Use a runner with more resources to avoid OOM errors when aggregating test results. outputs: - test_results: ${{ steps.set_test_results.outputs.results }} + test_results: ${{ steps.results.outputs.results }} steps: - name: Checkout repository uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 @@ -307,136 +308,127 @@ jobs: - name: Install flakeguard shell: bash - run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@9e40f2765df01f20b3bf53f0fb3ead920e3a1f4a # flakguard@0.1.0 + run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@404e04e1e2e2dd5a384b09bd05b8d80409b6609a # flakguard@0.1.0 - - name: Set combined test results - id: set_test_results + - name: Aggregate Flakeguard Results + id: results shell: bash run: | set -e # Exit immediately if a command exits with a non-zero status. - - if [ -d "ci_test_results" ]; then - cd ci_test_results - ls -R . - - # Fix flakeguard binary path - PATH=$PATH:$(go env GOPATH)/bin - export PATH - - # Use flakeguard to aggregate all test results - flakeguard aggregate-results --results-path . --output-results ../all_tests.json --project-path=${{ github.workspace }}/${{ inputs.projectPath }} --codeowners-path=${{ github.workspace }}/.github/CODEOWNERS - - # Count all tests - ALL_TESTS_COUNT=$(jq '.Results | length' ../all_tests.json) - echo "All tests count: $ALL_TESTS_COUNT" - echo "all_tests_count=$ALL_TESTS_COUNT" >> "$GITHUB_OUTPUT" - - # Use flakeguard to filter and output failed tests based on MaxPassRatio - flakeguard aggregate-results --filter-failed=true --max-pass-ratio=${{ inputs.maxPassRatio }} --results-path . --output-results ../failed_tests.json --output-logs ../failed_test_logs.json --project-path=${{ github.workspace }}/${{ inputs.projectPath }} --codeowners-path=${{ github.workspace }}/.github/CODEOWNERS - - # Count failed tests - if [ -f "../failed_tests.json" ]; then - FAILED_TESTS_COUNT=$(jq '.Results | length' ../failed_tests.json) - else - FAILED_TESTS_COUNT=0 - fi - echo "Failed tests count: $FAILED_TESTS_COUNT" - echo "failed_tests_count=$FAILED_TESTS_COUNT" >> "$GITHUB_OUTPUT" - - # Calculate failed ratio (failed / non-failed tests ratio in %) - if [ "$ALL_TESTS_COUNT" -gt 0 ]; then - NON_FAILED_COUNT=$((ALL_TESTS_COUNT - FAILED_TESTS_COUNT)) - - if [ "$NON_FAILED_COUNT" -gt 0 ]; then - FAILED_RATIO=$(awk "BEGIN {printf \"%.2f\", ($FAILED_TESTS_COUNT / $NON_FAILED_COUNT) * 100}") - else - FAILED_RATIO=0 - fi - else - NON_FAILED_COUNT=0 - FAILED_RATIO=0 - fi - echo "Failed tests ratio: $FAILED_RATIO%" - echo "failed_ratio=$FAILED_RATIO" >> "$GITHUB_OUTPUT" - else - echo "No test results directory found." - echo "all_tests_count=0" >> "$GITHUB_OUTPUT" - echo "failed_tests_count=0" >> "$GITHUB_OUTPUT" - echo "failed_ratio=0" >> "$GITHUB_OUTPUT" - fi - - - name: Tests Summary - if: ${{ fromJson(steps.set_test_results.outputs.all_tests_count) > 0 }} - run: | - FILE_SIZE=$(wc -c < all_tests.md) - echo "File size: $FILE_SIZE bytes" - SIZE_LIMIT=$((1024 * 1024)) - - if [ "$FILE_SIZE" -le "$SIZE_LIMIT" ]; then - cat all_tests.md >> $GITHUB_STEP_SUMMARY - else - echo "**We found flaky tests, so many flaky tests that the summary is too large for github actions step summaries!**" >> $GITHUB_STEP_SUMMARY - echo "**Please see logs, or the attached `all-summary.md` artifact**" >> $GITHUB_STEP_SUMMARY - cat all_tests.md - fi - - - name: Upload All Tests Summary as Artifact - if: ${{ fromJson(steps.set_test_results.outputs.all_tests_count) > 0 }} - uses: actions/upload-artifact@v4.4.3 - with: - path: all_tests.md - name: all-summary.md - retention-days: 90 + + # Create test results folder if it doesn't exist + mkdir -p ci_test_results + + # Fix flakeguard binary path + PATH=$PATH:$(go env GOPATH)/bin + export PATH + + # Aggregate Flakeguard test results + flakeguard aggregate-results \ + --results-path ./ci_test_results \ + --output-path ./flakeguard-report \ + --repo-path "${{ github.workspace }}" \ + --codeowners-path "${{ github.workspace }}/.github/CODEOWNERS" \ + --max-pass-ratio "${{ inputs.maxPassRatio }}" + + # Print out the summary file + echo -e "\nFlakeguard Summary:" + jq . ./flakeguard-report/all-test-summary.json + + # Read the summary from the generated report + summary=$(jq -c '.' ./flakeguard-report/all-test-summary.json) + echo "summary=$summary" >> $GITHUB_OUTPUT - name: Upload All Test Results as Artifact - if: ${{ fromJson(steps.set_test_results.outputs.all_tests_count) > 0 }} + if: ${{ fromJSON(steps.results.outputs.summary).total_tests > 0 }} uses: actions/upload-artifact@v4.4.3 with: - path: all_tests.json + path: ./flakeguard-report/all-test-results.json name: all-test-results.json retention-days: 90 - - name: Upload Failed Tests Summary as Artifact - if: ${{ fromJson(steps.set_test_results.outputs.all_tests_count) > 0 }} - uses: actions/upload-artifact@v4.4.3 - with: - path: failed_tests.md - name: failed-summary.md - retention-days: 90 - - name: Upload Failed Test Results as Artifact - if: ${{ fromJson(steps.set_test_results.outputs.failed_tests_count) > 0 }} + if: ${{ fromJSON(steps.results.outputs.summary).failed_runs > 0 }} uses: actions/upload-artifact@v4.4.3 with: - path: failed_tests.json + path: ./flakeguard-report/failed-test-results.json name: failed-test-results.json - retention-days: 90 - - - name: Upload Failed Test Logs as Artifact - if: ${{ fromJson(steps.set_test_results.outputs.failed_tests_count) > 0 }} - uses: actions/upload-artifact@v4.4.3 - with: - path: failed_test_logs.json - name: failed-test-logs.json - retention-days: 90 - - - name: Upload All Test Results as Artifact - if: ${{ fromJson(steps.set_test_results.outputs.all_tests_count) > 0 && env.UPLOAD_ALL_TEST_RESULTS == 'true' }} + retention-days: 90 + + - name: Upload Failed Test Results With Logs as Artifact + if: ${{ fromJSON(steps.results.outputs.summary).failed_runs > 0 }} uses: actions/upload-artifact@v4.4.3 with: - path: all_tests.json - name: all-test-results.json + path: ./flakeguard-report/failed-test-results-with-logs.json + name: failed-test-results-with-logs.json retention-days: 90 + - name: Generate Flakeguard Reports + shell: bash + env: + GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + run: | + set -e # Exit immediately if a command exits with a non-zero status. + + # Fix flakeguard binary path + PATH=$PATH:$(go env GOPATH)/bin + export PATH + + # Check if the event is a pull request + if [ "${{ github.event_name }}" = "pull_request" ]; then + flakeguard generate-report \ + --aggregated-results-path ./flakeguard-report/all-test-results.json \ + --summary-path ./flakeguard-report/all-test-summary.json \ + --output-path ./flakeguard-report \ + --github-repository "${{ github.repository }}" \ + --github-run-id "${{ github.run_id }}" \ + --failed-tests-artifact-name "failed-test-results-with-logs.json" \ + --generate-pr-comment \ + --base-branch "${{ github.event.pull_request.base.ref }}" \ + --current-branch "${{ github.head_ref }}" \ + --current-commit-sha "${{ github.event.pull_request.head.sha }}" \ + --repo-url "https://github.com/${{ github.repository }}" \ + --action-run-id "${{ github.run_id }}" \ + --max-pass-ratio "${{ inputs.maxPassRatio }}" + else + flakeguard generate-report \ + --aggregated-results-path ./flakeguard-report/all-test-results.json \ + --summary-path ./flakeguard-report/all-test-summary.json \ + --output-path ./flakeguard-report \ + --github-repository "${{ github.repository }}" \ + --github-run-id "${{ github.run_id }}" \ + --failed-tests-artifact-name "failed-test-results-with-logs.json" \ + --base-branch "${{ github.event.pull_request.base.ref }}" \ + --current-branch "${{ github.head_ref }}" \ + --current-commit-sha "${{ github.event.pull_request.head.sha }}" \ + --repo-url "https://github.com/${{ github.repository }}" \ + --action-run-id "${{ github.run_id }}" \ + --max-pass-ratio "${{ inputs.maxPassRatio }}" + fi + + - name: Add Github Summary + run: | + FILE_SIZE=$(wc -c < ./flakeguard-report/all-test-summary.md) + echo "File size: $FILE_SIZE bytes" + SIZE_LIMIT=$((1024 * 1024)) + + if [ "$FILE_SIZE" -le "$SIZE_LIMIT" ]; then + cat ./flakeguard-report/all-test-summary.md >> $GITHUB_STEP_SUMMARY + else + echo "**We found flaky tests, so many flaky tests that the summary is too large for github actions step summaries!**" >> $GITHUB_STEP_SUMMARY + echo "**Please see logs, or the attached `all-test-summary.md` artifact**" >> $GITHUB_STEP_SUMMARY + cat ./flakeguard-report/all-test-summary.md + fi + - name: Post comment on PR if flaky tests found - if: ${{ fromJson(steps.set_test_results.outputs.failed_tests_count) > 0 && github.event_name == 'pull_request' }} + if: ${{ fromJSON(steps.results.outputs.summary).flaky_tests > 0 && github.event_name == 'pull_request' }} uses: actions/github-script@v7 continue-on-error: true with: script: | const fs = require('fs'); const prNumber = context.payload.pull_request.number; - const commentBody = fs.readFileSync('all_tests.md', 'utf8'); + const commentBody = fs.readFileSync('./flakeguard-report/all-test-pr-comment.md', 'utf8'); await github.rest.issues.createComment({ owner: context.repo.owner, @@ -446,7 +438,7 @@ jobs: }); - name: Send Slack message for failed tests - if: ${{ inputs.slackNotificationAfterTestsChannelId != '' && fromJson(steps.set_test_results.outputs.failed_tests_count) > 0 }} + if: ${{ inputs.slackNotificationAfterTestsChannelId != '' && fromJSON(steps.results.outputs.summary).flaky_tests > 0 }} uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} @@ -477,11 +469,11 @@ jobs: "fields": [ { "type": "mrkdwn", - "text": "Total Failed Tests: ${{ steps.set_test_results.outputs.failed_tests_count }}" + "text": "Total Flaky Tests: ${{ fromJSON(steps.results.outputs.summary).flaky_tests }}" }, { "type": "mrkdwn", - "text": "Failed to Non-Failed Ratio: ${{ steps.set_test_results.outputs.failed_ratio }}%" + "text": "Flaky Tests Ratio: ${{ fromJSON(steps.results.outputs.summary).flaky_test_ratio }}" } ] }, @@ -499,7 +491,7 @@ jobs: - name: Send general Slack message uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 - if: ${{ inputs.slackNotificationAfterTestsChannelId != '' && fromJson(steps.set_test_results.outputs.failed_tests_count) == 0 && fromJson(steps.set_test_results.outputs.all_tests_count) > 0 }} + if: ${{ inputs.slackNotificationAfterTestsChannelId != '' && fromJSON(steps.results.outputs.summary).flaky_tests == 0 && fromJSON(steps.results.outputs.summary).total_tests > 0 }} id: slack env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} diff --git a/.github/workflows/integration-in-memory-tests.yml b/.github/workflows/integration-in-memory-tests.yml index 8d777b41ea1..341d66f641e 100644 --- a/.github/workflows/integration-in-memory-tests.yml +++ b/.github/workflows/integration-in-memory-tests.yml @@ -73,7 +73,7 @@ jobs: contents: read needs: changes if: github.event_name == 'pull_request' && ( needs.changes.outputs.ccip_changes == 'true' || needs.changes.outputs.core_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true') - uses: smartcontractkit/.github/.github/workflows/run-integration-tests.yml@57112554b9e5cfae79e795a8b1c36acf7e9dead7 + uses: smartcontractkit/.github/.github/workflows/run-integration-tests.yml@0632b5652dd5eb03bfa87e23a2b3e2911484fe59 with: workflow_name: Run CCIP Integration Tests For PR test_path: .github/integration-in-memory-tests.yml @@ -95,7 +95,7 @@ jobs: contents: read needs: changes if: github.event_name == 'merge_group' && ( needs.changes.outputs.ccip_changes == 'true' || needs.changes.outputs.core_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true') - uses: smartcontractkit/.github/.github/workflows/run-integration-tests.yml@57112554b9e5cfae79e795a8b1c36acf7e9dead7 + uses: smartcontractkit/.github/.github/workflows/run-integration-tests.yml@0632b5652dd5eb03bfa87e23a2b3e2911484fe59 with: workflow_name: Run CCIP Integration Tests For Merge Queue test_path: .github/integration-in-memory-tests.yml diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index bac453eb044..27bdfa52243 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -210,7 +210,7 @@ jobs: contents: read needs: [build-chainlink, changes] if: github.event_name == 'pull_request' && ( needs.changes.outputs.core_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true') - uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@27467f0073162e0ca77d33ce26f649b3d0f4c188 #ctf-run-tests@0.2.0 + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@0632b5652dd5eb03bfa87e23a2b3e2911484fe59 with: workflow_name: Run Core E2E Tests For PR chainlink_version: ${{ inputs.evm-ref || github.sha }} @@ -251,7 +251,7 @@ jobs: contents: read needs: [build-chainlink, changes] if: github.event_name == 'merge_group' && ( needs.changes.outputs.core_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true') - uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@27467f0073162e0ca77d33ce26f649b3d0f4c188 #ctf-run-tests@1.0.0 + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@0632b5652dd5eb03bfa87e23a2b3e2911484fe59 with: workflow_name: Run Core E2E Tests For Merge Queue chainlink_version: ${{ inputs.evm-ref || github.sha }} @@ -296,7 +296,7 @@ jobs: contents: read needs: [build-chainlink, changes] if: github.event_name == 'pull_request' && (needs.changes.outputs.ccip_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true') - uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@0d4a2b2b009c87b5c366d0b97f7a8d7de2f60760 + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@0632b5652dd5eb03bfa87e23a2b3e2911484fe59 with: workflow_name: Run CCIP E2E Tests For PR chainlink_version: ${{ inputs.evm-ref || github.sha }} @@ -338,7 +338,7 @@ jobs: contents: read needs: [build-chainlink, changes] if: github.event_name == 'merge_group' && (needs.changes.outputs.ccip_changes == 'true' || needs.changes.outputs.github_ci_changes == 'true') - uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@0d4a2b2b009c87b5c366d0b97f7a8d7de2f60760 + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@0632b5652dd5eb03bfa87e23a2b3e2911484fe59 with: workflow_name: Run CCIP E2E Tests For Merge Queue chainlink_version: ${{ inputs.evm-ref || github.sha }} @@ -382,7 +382,7 @@ jobs: results='${{ needs.run-core-e2e-tests-for-pr.outputs.test_results }}' echo "Core test results:" echo "$results" | jq . - + node_migration_tests_failed=$(echo $results | jq '[.[] | select(.id == "integration-tests/migration/upgrade_version_test.go:*" ) | select(.result != "success")] | length > 0') echo "node_migration_tests_failed=$node_migration_tests_failed" >> $GITHUB_OUTPUT @@ -730,6 +730,7 @@ jobs: env: E2E_TEST_CHAINLINK_IMAGE: ${{ env.CHAINLINK_IMAGE }} E2E_TEST_SOLANA_SECRET: thisisatestingonlysecret + CHAINLINK_USER_TEAM: "BIX" - name: Upload Coverage Data uses: actions/upload-artifact@v4.4.3 diff --git a/.github/workflows/on-demand-vrfv2-performance-test.yml b/.github/workflows/on-demand-vrfv2-performance-test.yml index aadef377718..f9aeaa0fa1f 100644 --- a/.github/workflows/on-demand-vrfv2-performance-test.yml +++ b/.github/workflows/on-demand-vrfv2-performance-test.yml @@ -67,7 +67,7 @@ jobs: run-e2e-tests-workflow: name: Run E2E Tests needs: set-tests-to-run - uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@5412507526722a7b1c5d719fa686eed5a1bc4035 # ctf-run-tests@0.2.0 + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@0632b5652dd5eb03bfa87e23a2b3e2911484fe59 with: custom_test_list_json: ${{ needs.set-tests-to-run.outputs.test_list }} chainlink_version: ${{ inputs.chainlink_version }} diff --git a/.github/workflows/on-demand-vrfv2-smoke-tests.yml b/.github/workflows/on-demand-vrfv2-smoke-tests.yml index 4ebc38a8081..ad616dea744 100644 --- a/.github/workflows/on-demand-vrfv2-smoke-tests.yml +++ b/.github/workflows/on-demand-vrfv2-smoke-tests.yml @@ -70,7 +70,7 @@ jobs: run-e2e-tests-workflow: name: Run E2E Tests needs: set-tests-to-run - uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@5412507526722a7b1c5d719fa686eed5a1bc4035 # ctf-run-tests@0.2.0 + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@0632b5652dd5eb03bfa87e23a2b3e2911484fe59 with: custom_test_list_json: ${{ needs.set-tests-to-run.outputs.test_list }} chainlink_version: ${{ inputs.chainlink_version }} diff --git a/.github/workflows/on-demand-vrfv2plus-performance-test.yml b/.github/workflows/on-demand-vrfv2plus-performance-test.yml index f6d120ac178..b3a820e25a0 100644 --- a/.github/workflows/on-demand-vrfv2plus-performance-test.yml +++ b/.github/workflows/on-demand-vrfv2plus-performance-test.yml @@ -67,7 +67,7 @@ jobs: run-e2e-tests-workflow: name: Run E2E Tests needs: set-tests-to-run - uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@5412507526722a7b1c5d719fa686eed5a1bc4035 # ctf-run-tests@0.2.0 + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@0632b5652dd5eb03bfa87e23a2b3e2911484fe59 with: custom_test_list_json: ${{ needs.set-tests-to-run.outputs.test_list }} chainlink_version: ${{ inputs.chainlink_version }} diff --git a/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml b/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml index af26c527988..8561034b103 100644 --- a/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml +++ b/.github/workflows/on-demand-vrfv2plus-smoke-tests.yml @@ -70,7 +70,7 @@ jobs: run-e2e-tests-workflow: name: Run E2E Tests needs: set-tests-to-run - uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@5412507526722a7b1c5d719fa686eed5a1bc4035 # ctf-run-tests@0.2.0 + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@0632b5652dd5eb03bfa87e23a2b3e2911484fe59 with: custom_test_list_json: ${{ needs.set-tests-to-run.outputs.test_list }} chainlink_version: ${{ inputs.chainlink_version }} diff --git a/.github/workflows/run-nightly-e2e-tests.yml b/.github/workflows/run-nightly-e2e-tests.yml index eba1108f89f..712fb088181 100644 --- a/.github/workflows/run-nightly-e2e-tests.yml +++ b/.github/workflows/run-nightly-e2e-tests.yml @@ -20,7 +20,7 @@ on: jobs: call-run-e2e-tests-workflow: name: Run E2E Tests - uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@5412507526722a7b1c5d719fa686eed5a1bc4035 # ctf-run-tests@0.2.0 + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@0632b5652dd5eb03bfa87e23a2b3e2911484fe59 with: chainlink_version: ${{ inputs.chainlink_version || 'develop' }} test_path: .github/e2e-tests.yml diff --git a/.github/workflows/run-selected-e2e-tests.yml b/.github/workflows/run-selected-e2e-tests.yml index 0e7c97c67fc..e95ce1cef19 100644 --- a/.github/workflows/run-selected-e2e-tests.yml +++ b/.github/workflows/run-selected-e2e-tests.yml @@ -35,7 +35,7 @@ run-name: ${{ inputs.workflow_run_name }} jobs: call-run-e2e-tests-workflow: name: Run E2E Tests - uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@5412507526722a7b1c5d719fa686eed5a1bc4035 # ctf-run-tests@0.2.0 + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@0632b5652dd5eb03bfa87e23a2b3e2911484fe59 with: chainlink_version: ${{ github.event.inputs.chainlink_version }} test_path: .github/e2e-tests.yml diff --git a/.github/workflows/solidity-foundry.yml b/.github/workflows/solidity-foundry.yml index b94c0236155..f94ef29a3b8 100644 --- a/.github/workflows/solidity-foundry.yml +++ b/.github/workflows/solidity-foundry.yml @@ -33,8 +33,8 @@ jobs: { "name": "ccip", "setup": { "run-coverage": true, "min-coverage": 98.8, "extra-coverage-params": "--no-match-path='*End2End*'", "run-gas-snapshot": true, "run-forge-fmt": true }}, { "name": "functions", "setup": { "run-coverage": false, "min-coverage": 98.5, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "keystone", "setup": { "run-coverage": true, "min-coverage": 72.8, "run-gas-snapshot": false, "run-forge-fmt": false }}, - { "name": "l2ep", "setup": { "run-coverage": true, "min-coverage": 61.0, "run-gas-snapshot": true, "run-forge-fmt": false }}, - { "name": "liquiditymanager", "setup": { "run-coverage": true, "min-coverage": 44, "run-gas-snapshot": true, "run-forge-fmt": false }}, + { "name": "l2ep", "setup": { "run-coverage": true, "min-coverage": 65.0, "run-gas-snapshot": true, "run-forge-fmt": false }}, + { "name": "liquiditymanager", "setup": { "run-coverage": true, "min-coverage": 40, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "llo-feeds", "setup": { "run-coverage": true, "min-coverage": 49.3, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "operatorforwarder", "setup": { "run-coverage": true, "min-coverage": 55.7, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "shared", "setup": { "run-coverage": true, "extra-coverage-params": "--no-match-path='*CallWithExactGas*' --ir-minimum", "min-coverage": 32.6, "run-gas-snapshot": true, "run-forge-fmt": false }}, diff --git a/.mockery.yaml b/.mockery.yaml index dd9024cc066..5777ca1da92 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -583,12 +583,6 @@ packages: github.com/smartcontractkit/chainlink/v2/core/services/workflows/syncer: interfaces: ORM: - ContractReader: - config: - mockname: "Mock{{ .InterfaceName }}" - filename: contract_reader_mock.go - inpackage: true - dir: "{{ .InterfaceDir }}" Handler: config: mockname: "Mock{{ .InterfaceName }}" diff --git a/GNUmakefile b/GNUmakefile index 592183923e2..336efd326a7 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -144,6 +144,12 @@ presubmit: ## Format go files and imports. gomods: ## Install gomods go install github.com/jmank88/gomods@v0.1.4 +.PHONY: gomodslocalupdate +gomodslocalupdate: gomods ## Run gomod-local-update + go install ./tools/gomod-local-update/cmd/gomod-local-update + gomods -w gomod-local-update + gomods tidy + .PHONY: mockery mockery: $(mockery) ## Install mockery. go install github.com/vektra/mockery/v2@v2.46.3 diff --git a/ccip/config/evm/Lens_Sepolia.toml b/ccip/config/evm/Lens_Sepolia.toml new file mode 100644 index 00000000000..3f41f2eeeae --- /dev/null +++ b/ccip/config/evm/Lens_Sepolia.toml @@ -0,0 +1,34 @@ +ChainID = "37111" +ChainType = "zksync" +# finality depth for this chain is very inconsistent due to low network traffic. in testing blocks every ~1-2minutes were seen +# confirmed this value with product +FinalityDepth = 40 +FinalityTagEnabled = false +# block rate is dynamic, have seen block times as low as 1s +LogPollInterval = "5s" +# sufficient time for RPC to be labelled out of sync +NoNewHeadsThreshold = "10m" + +[GasEstimator] +EIP1559DynamicFees = false +# limit default set for zk based chains +LimitDefault = 2_500_000_000 +# value given by ds&a +FeeCapDefault = "2000 gwei" +# estimators typically estimated with min of 75 with median of 86 +PriceDefault = "70 gwei" +PriceMax = "2000 gwei" +PriceMin = "70 gwei" +# bump gas aggressively to avoid high amounts of transmit errors +BumpThreshold = 1 +BumpPercent = 40 + +[GasEstimator.DAOracle] +OracleType = 'zksync' + +[Transactions] +ResendAfterThreshold = '7m0s' + +[HeadTracker] +# l1 batching is done every 8hrs with low network activity setting this value to a rough calculation of ~1tx / 2min * 8hrs +HistoryDepth = 250 \ No newline at end of file diff --git a/contracts/.changeset/small-countries-flow.md b/contracts/.changeset/small-countries-flow.md new file mode 100644 index 00000000000..953102874bc --- /dev/null +++ b/contracts/.changeset/small-countries-flow.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +Modify TokenPool.sol function setChainRateLimiterConfig to now accept an array of configs and set sequentially. Requested by front-end. PR issue CCIP-4329 #bugfix diff --git a/contracts/.changeset/thirty-rules-rule.md b/contracts/.changeset/thirty-rules-rule.md new file mode 100644 index 00000000000..1c69192981c --- /dev/null +++ b/contracts/.changeset/thirty-rules-rule.md @@ -0,0 +1,10 @@ +--- +'@chainlink/contracts': patch +--- + +[L2EP] Refactor tests and fix file exclusion for coverage + + +PR issue: SHIP-3521 + +Solidity Review issue: SHIP-4050 \ No newline at end of file diff --git a/contracts/.changeset/yellow-mugs-explode.md b/contracts/.changeset/yellow-mugs-explode.md new file mode 100644 index 00000000000..bd488e559ef --- /dev/null +++ b/contracts/.changeset/yellow-mugs-explode.md @@ -0,0 +1,9 @@ +--- +'@chainlink/contracts': minor +--- + +#internal make gas for call exact check immutable + +PR issue: CCIP-4477 + +Solidity Review issue: CCIP-3966 \ No newline at end of file diff --git a/contracts/.changeset/young-bats-rhyme.md b/contracts/.changeset/young-bats-rhyme.md new file mode 100644 index 00000000000..e68a646b78e --- /dev/null +++ b/contracts/.changeset/young-bats-rhyme.md @@ -0,0 +1,10 @@ +--- +'@chainlink/contracts': patch +--- + +add getChainConfig to ccipHome + + +PR issue: CCIP-4517 + +Solidity Review issue: CCIP-3966 \ No newline at end of file diff --git a/contracts/GNUmakefile b/contracts/GNUmakefile index 4066c76037e..673198bb1e2 100644 --- a/contracts/GNUmakefile +++ b/contracts/GNUmakefile @@ -43,7 +43,7 @@ mockery: $(mockery) ## Install mockery. .PHONY: foundry foundry: ## Install foundry. - foundryup --version nightly-fb5f0e1c4d9b9b0861be3e3bd07963524c5ac08e + foundryup --version nightly-aa69ed1e46dd61fbf9d73399396a4db4dd527431 .PHONY: foundry-refresh foundry-refresh: foundry diff --git a/contracts/README.md b/contracts/README.md index 182891ceef7..f87f196e5dc 100644 --- a/contracts/README.md +++ b/contracts/README.md @@ -24,7 +24,7 @@ $ npm install @chainlink/contracts --save The solidity smart contracts themselves can be imported via the `src` directory of `@chainlink/contracts`: ```solidity -import '@chainlink/contracts/src/v0.8/AutomationCompatibleInterface.sol'; +import {AutomationCompatibleInterface} from '@chainlink/contracts/src/v0.8/AutomationCompatibleInterface.sol'; ``` ## Local Development @@ -42,7 +42,7 @@ $ pnpm test ## Contributing -Please try to adhere to [Solidity Style Guide](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/STYLE.md). +Please adhere to the [Solidity Style Guide](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/STYLE.md). Contributions are welcome! Please refer to [Chainlink's contributing guidelines](https://github.com/smartcontractkit/chainlink/blob/develop/docs/CONTRIBUTING.md) for detailed @@ -70,6 +70,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Most of the contracts are licensed under the [MIT](https://choosealicense.com/licenses/mit/) license. An exception to this is the ccip folder, which defaults to be licensed under the [BUSL-1.1](./src/v0.8/ccip/LICENSE.md) license, however, there are a few exceptions -- `src/v0.8/ccip/applications/*` is licensed under the [MIT](./src/v0.8/ccip/LICENSE-MIT.md) license -- `src/v0.8/ccip/interfaces/*` is licensed under the [MIT](./src/v0.8/ccip/LICENSE-MIT.md) license -- `src/v0.8/ccip/libraries/{Client.sol, Internal.sol}` is licensed under the [MIT](./src/v0.8/ccip/LICENSE-MIT.md) license \ No newline at end of file +- `src/v0.8/ccip/applications/*` is licensed under the [MIT](https://choosealicense.com/licenses/mit/) license +- `src/v0.8/ccip/interfaces/*` is licensed under the [MIT](https://choosealicense.com/licenses/mit/) license +- `src/v0.8/ccip/libraries/{Client.sol, Internal.sol}` is licensed under the [MIT](https://choosealicense.com/licenses/mit/) license \ No newline at end of file diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index fa768c40bb5..147783b52cb 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -38,37 +38,37 @@ CCIPHome__validateConfig:test__validateConfig_Success() (gas: 299797) CCIPHome__validateConfig:test__validateConfig_TooManySigners_Reverts() (gas: 773105) CCIPHome__validateConfig:test__validateConfig_ZeroP2PId_Reverts() (gas: 293455) CCIPHome__validateConfig:test__validateConfig_ZeroSignerKey_Reverts() (gas: 293503) -CCIPHome_applyChainConfigUpdates:test__applyChainConfigUpdates_FChainNotPositive_Reverts() (gas: 187738) -CCIPHome_applyChainConfigUpdates:test_applyChainConfigUpdates_addChainConfigs_Success() (gas: 349623) -CCIPHome_applyChainConfigUpdates:test_applyChainConfigUpdates_nodeNotInRegistry_Reverts() (gas: 18065) -CCIPHome_applyChainConfigUpdates:test_applyChainConfigUpdates_removeChainConfigs_Success() (gas: 272742) -CCIPHome_applyChainConfigUpdates:test_applyChainConfigUpdates_selectorNotFound_Reverts() (gas: 14952) -CCIPHome_applyChainConfigUpdates:test_getPaginatedCCIPHomes_Success() (gas: 372561) +CCIPHome_applyChainConfigUpdates:test__applyChainConfigUpdates_FChainNotPositive_Reverts() (gas: 187822) +CCIPHome_applyChainConfigUpdates:test_applyChainConfigUpdates_addChainConfigs_Success() (gas: 350051) +CCIPHome_applyChainConfigUpdates:test_applyChainConfigUpdates_nodeNotInRegistry_Reverts() (gas: 18089) +CCIPHome_applyChainConfigUpdates:test_applyChainConfigUpdates_removeChainConfigs_Success() (gas: 282212) +CCIPHome_applyChainConfigUpdates:test_applyChainConfigUpdates_selectorNotFound_Reverts() (gas: 14976) +CCIPHome_applyChainConfigUpdates:test_getPaginatedCCIPHomes_Success() (gas: 373475) CCIPHome_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_DONIdMismatch_reverts() (gas: 38098) -CCIPHome_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_InnerCallReverts_reverts() (gas: 11827) +CCIPHome_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_InnerCallReverts_reverts() (gas: 11783) CCIPHome_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_InvalidSelector_reverts() (gas: 11015) CCIPHome_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_OnlyCapabilitiesRegistryCanCall_reverts() (gas: 37072) -CCIPHome_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_success() (gas: 1455716) -CCIPHome_constructor:test_constructor_CapabilitiesRegistryAddressZero_reverts() (gas: 63767) -CCIPHome_constructor:test_constructor_success() (gas: 3455841) -CCIPHome_getAllConfigs:test_getAllConfigs_success() (gas: 2773000) -CCIPHome_getCapabilityConfiguration:test_getCapabilityConfiguration_success() (gas: 9138) -CCIPHome_getConfigDigests:test_getConfigDigests_success() (gas: 2547397) -CCIPHome_promoteCandidateAndRevokeActive:test_promoteCandidateAndRevokeActive_CanOnlySelfCall_reverts() (gas: 9087) -CCIPHome_promoteCandidateAndRevokeActive:test_promoteCandidateAndRevokeActive_ConfigDigestMismatch_reverts() (gas: 23005) -CCIPHome_promoteCandidateAndRevokeActive:test_promoteCandidateAndRevokeActive_NoOpStateTransitionNotAllowed_reverts() (gas: 8817) -CCIPHome_promoteCandidateAndRevokeActive:test_promoteCandidateAndRevokeActive_multiplePlugins_success() (gas: 5113570) -CCIPHome_revokeCandidate:test_revokeCandidate_CanOnlySelfCall_reverts() (gas: 9068) -CCIPHome_revokeCandidate:test_revokeCandidate_ConfigDigestMismatch_reverts() (gas: 19105) -CCIPHome_revokeCandidate:test_revokeCandidate_RevokingZeroDigestNotAllowed_reverts() (gas: 8817) -CCIPHome_revokeCandidate:test_revokeCandidate_success() (gas: 30674) +CCIPHome_beforeCapabilityConfigSet:test_beforeCapabilityConfigSet_success() (gas: 1455674) +CCIPHome_constructor:test_constructor_CapabilitiesRegistryAddressZero_reverts() (gas: 63865) +CCIPHome_constructor:test_constructor_success() (gas: 3531036) +CCIPHome_getAllConfigs:test_getAllConfigs_success() (gas: 2773023) +CCIPHome_getCapabilityConfiguration:test_getCapabilityConfiguration_success() (gas: 9116) +CCIPHome_getConfigDigests:test_getConfigDigests_success() (gas: 2547513) +CCIPHome_promoteCandidateAndRevokeActive:test_promoteCandidateAndRevokeActive_CanOnlySelfCall_reverts() (gas: 9110) +CCIPHome_promoteCandidateAndRevokeActive:test_promoteCandidateAndRevokeActive_ConfigDigestMismatch_reverts() (gas: 23074) +CCIPHome_promoteCandidateAndRevokeActive:test_promoteCandidateAndRevokeActive_NoOpStateTransitionNotAllowed_reverts() (gas: 8840) +CCIPHome_promoteCandidateAndRevokeActive:test_promoteCandidateAndRevokeActive_multiplePlugins_success() (gas: 5113754) +CCIPHome_revokeCandidate:test_revokeCandidate_CanOnlySelfCall_reverts() (gas: 9024) +CCIPHome_revokeCandidate:test_revokeCandidate_ConfigDigestMismatch_reverts() (gas: 19084) +CCIPHome_revokeCandidate:test_revokeCandidate_RevokingZeroDigestNotAllowed_reverts() (gas: 8773) +CCIPHome_revokeCandidate:test_revokeCandidate_success() (gas: 30676) CCIPHome_setCandidate:test_setCandidate_CanOnlySelfCall_reverts() (gas: 29383) CCIPHome_setCandidate:test_setCandidate_ConfigDigestMismatch_reverts() (gas: 1395154) CCIPHome_setCandidate:test_setCandidate_success() (gas: 1365439) CCIPHome_supportsInterface:test_supportsInterface_success() (gas: 9885) DefensiveExampleTest:test_HappyPath_Success() (gas: 200540) DefensiveExampleTest:test_Recovery() (gas: 425013) -E2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1512127) +E2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1512391) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_fallbackToWethTransfer() (gas: 96980) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_happyPath() (gas: 49812) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_wrongToken() (gas: 17479) @@ -226,29 +226,29 @@ FeeQuoter_validateDestFamilyAddress:test_InvalidEVMAddressPrecompiles_Revert() ( FeeQuoter_validateDestFamilyAddress:test_InvalidEVMAddress_Revert() (gas: 10906) FeeQuoter_validateDestFamilyAddress:test_ValidEVMAddress_Success() (gas: 6841) FeeQuoter_validateDestFamilyAddress:test_ValidNonEVMAddress_Success() (gas: 6567) -HybridLockReleaseUSDCTokenPool_TransferLiquidity:test_cannotTransferLiquidityDuringPendingMigration_Revert() (gas: 176837) -HybridLockReleaseUSDCTokenPool_TransferLiquidity:test_transferLiquidity_Success() (gas: 166986) -HybridLockReleaseUSDCTokenPool_lockOrBurn:test_PrimaryMechanism_Success() (gas: 135860) -HybridLockReleaseUSDCTokenPool_lockOrBurn:test_WhileMigrationPause_Revert() (gas: 109696) -HybridLockReleaseUSDCTokenPool_lockOrBurn:test_onLockReleaseMechanism_Success() (gas: 146915) -HybridLockReleaseUSDCTokenPool_lockOrBurn:test_onLockReleaseMechanism_thenSwitchToPrimary_Success() (gas: 209124) +HybridLockReleaseUSDCTokenPool_TransferLiquidity:test_cannotTransferLiquidityDuringPendingMigration_Revert() (gas: 176859) +HybridLockReleaseUSDCTokenPool_TransferLiquidity:test_transferLiquidity_Success() (gas: 167004) +HybridLockReleaseUSDCTokenPool_lockOrBurn:test_PrimaryMechanism_Success() (gas: 135878) +HybridLockReleaseUSDCTokenPool_lockOrBurn:test_WhileMigrationPause_Revert() (gas: 109718) +HybridLockReleaseUSDCTokenPool_lockOrBurn:test_onLockReleaseMechanism_Success() (gas: 146937) +HybridLockReleaseUSDCTokenPool_lockOrBurn:test_onLockReleaseMechanism_thenSwitchToPrimary_Success() (gas: 209160) HybridLockReleaseUSDCTokenPool_releaseOrMint:test_OnLockReleaseMechanism_Success() (gas: 213127) HybridLockReleaseUSDCTokenPool_releaseOrMint:test_WhileMigrationPause_Revert() (gas: 109646) HybridLockReleaseUSDCTokenPool_releaseOrMint:test_incomingMessageWithPrimaryMechanism() (gas: 265910) -LockReleaseTokenPool_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3099863) +LockReleaseTokenPool_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3209936) LockReleaseTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 29734) LockReleaseTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Success() (gas: 80625) LockReleaseTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 59227) -LockReleaseTokenPool_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3096192) +LockReleaseTokenPool_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3206264) LockReleaseTokenPool_provideLiquidity:test_Unauthorized_Revert() (gas: 11511) LockReleaseTokenPool_releaseOrMint:test_ChainNotAllowed_Revert() (gas: 74100) LockReleaseTokenPool_releaseOrMint:test_PoolMintNotHealthy_Revert() (gas: 54745) LockReleaseTokenPool_releaseOrMint:test_ReleaseOrMint_Success() (gas: 223256) -LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Revert() (gas: 10936) -LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Success() (gas: 18115) +LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Revert() (gas: 11003) +LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Success() (gas: 18182) LockReleaseTokenPool_supportsInterface:test_SupportsInterface_Success() (gas: 10250) -LockReleaseTokenPool_transferLiquidity:test_transferLiquidity_Success() (gas: 83283) -LockReleaseTokenPool_transferLiquidity:test_transferLiquidity_transferTooMuch_Revert() (gas: 56056) +LockReleaseTokenPool_transferLiquidity:test_transferLiquidity_Success() (gas: 83328) +LockReleaseTokenPool_transferLiquidity:test_transferLiquidity_transferTooMuch_Revert() (gas: 56101) LockReleaseTokenPool_withdrawalLiquidity:test_InsufficientLiquidity_Revert() (gas: 60188) LockReleaseTokenPool_withdrawalLiquidity:test_Unauthorized_Revert() (gas: 11464) MerkleMultiProofTest:test_CVE_2023_34459() (gas: 5456) @@ -347,29 +347,25 @@ MultiOCR3Base_transmit:test_UnAuthorizedTransmitter_Revert() (gas: 24193) MultiOCR3Base_transmit:test_UnauthorizedSigner_Revert() (gas: 60994) MultiOCR3Base_transmit:test_UnconfiguredPlugin_Revert() (gas: 39824) MultiOCR3Base_transmit:test_ZeroSignatures_Revert() (gas: 32920) -NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas: 37956) -NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23706) -NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38778) -NonceManager_NonceIncrementation:test_incrementNoncesInboundAndOutbound_Success() (gas: 71901) -NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 185810) -NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 189263) -NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 252318) -NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 220605) -NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 60497) -NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 152975) -NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 166167) -NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 195938) -NonceManager_OnRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 139164) -NonceManager_OnRampUpgrade:test_Upgrade_Success() (gas: 105212) -NonceManager_applyPreviousRampsUpdates:test_MultipleRampsUpdates_success() (gas: 123604) -NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOffRamp_Revert() (gas: 43403) -NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOnRampAndOffRamp_Revert() (gas: 64752) -NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySetOnRamp_Revert() (gas: 43245) -NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySet_overrideAllowed_success() (gas: 45941) +NonceManager_applyPreviousRampsUpdates:test_MultipleRampsUpdates() (gas: 123604) +NonceManager_applyPreviousRampsUpdates:test_PreviousRampAlreadySet_overrideAllowed() (gas: 45986) NonceManager_applyPreviousRampsUpdates:test_SingleRampUpdate_success() (gas: 66889) -NonceManager_applyPreviousRampsUpdates:test_ZeroInput_success() (gas: 12213) -NonceManager_typeAndVersion:test_typeAndVersion() (gas: 9705) -OffRamp_afterOC3ConfigSet:test_afterOCR3ConfigSet_SignatureVerificationDisabled_Revert() (gas: 5872422) +NonceManager_applyPreviousRampsUpdates:test_ZeroInput() (gas: 12169) +NonceManager_getInboundNonce:test_getInboundNonce_NoPrevOffRampForChain() (gas: 185821) +NonceManager_getInboundNonce:test_getInboundNonce_Upgraded() (gas: 152976) +NonceManager_getInboundNonce:test_getInboundNonce_UpgradedNonceNewSenderStartsAtZero() (gas: 189296) +NonceManager_getInboundNonce:test_getInboundNonce_UpgradedNonceStartsAtV1Nonce() (gas: 252384) +NonceManager_getInboundNonce:test_getInboundNonce_UpgradedOffRampNonceSkipsIfMsgInFlight() (gas: 220672) +NonceManager_getInboundNonce:test_getInboundNonce_UpgradedSenderNoncesReadsPreviousRamp() (gas: 60520) +NonceManager_getIncrementedOutboundNonce:test_getIncrementedOutboundNonce() (gas: 37979) +NonceManager_getIncrementedOutboundNonce:test_incrementInboundNonce() (gas: 38756) +NonceManager_getIncrementedOutboundNonce:test_incrementInboundNonce_SkippedIncorrectNonce() (gas: 23759) +NonceManager_getIncrementedOutboundNonce:test_incrementNoncesInboundAndOutbound() (gas: 71901) +NonceManager_getOutboundNonce:test_getOutboundNonce_Upgrade() (gas: 105300) +NonceManager_getOutboundNonce:test_getOutboundNonce_UpgradeNonceNewSenderStartsAtZero() (gas: 166146) +NonceManager_getOutboundNonce:test_getOutboundNonce_UpgradeNonceStartsAtV1Nonce() (gas: 195937) +NonceManager_getOutboundNonce:test_getOutboundNonce_UpgradeSenderNoncesReadsPreviousRamp() (gas: 140158) +OffRamp_afterOC3ConfigSet:test_afterOCR3ConfigSet_SignatureVerificationDisabled_Revert() (gas: 5903354) OffRamp_applySourceChainConfigUpdates:test_AddMultipleChains_Success() (gas: 626094) OffRamp_applySourceChainConfigUpdates:test_AddNewChain_Success() (gas: 166505) OffRamp_applySourceChainConfigUpdates:test_ApplyZeroUpdates_Success() (gas: 16719) @@ -386,15 +382,15 @@ OffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 276839) OffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 168529) OffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 188173) OffRamp_batchExecute:test_SingleReport_Success() (gas: 156527) -OffRamp_batchExecute:test_Unhealthy_Success() (gas: 545255) +OffRamp_batchExecute:test_Unhealthy_Success() (gas: 545431) OffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10643) OffRamp_commit:test_CommitOnRampMismatch_Revert() (gas: 92450) OffRamp_commit:test_FailedRMNVerification_Reverts() (gas: 63117) OffRamp_commit:test_InvalidIntervalMinLargerThanMax_Revert() (gas: 69655) OffRamp_commit:test_InvalidInterval_Revert() (gas: 65803) OffRamp_commit:test_InvalidRootRevert() (gas: 64898) -OffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6633259) -OffRamp_commit:test_NoConfig_Revert() (gas: 6216677) +OffRamp_commit:test_NoConfigWithOtherConfigPresent_Revert() (gas: 6664144) +OffRamp_commit:test_NoConfig_Revert() (gas: 6247562) OffRamp_commit:test_OnlyGasPriceUpdates_Success() (gas: 112728) OffRamp_commit:test_OnlyPriceUpdateStaleReport_Revert() (gas: 120561) OffRamp_commit:test_OnlyTokenPriceUpdates_Success() (gas: 112660) @@ -409,32 +405,32 @@ OffRamp_commit:test_UnauthorizedTransmitter_Revert() (gas: 125027) OffRamp_commit:test_Unhealthy_Revert() (gas: 60177) OffRamp_commit:test_ValidPriceUpdateThenStaleReportWithRoot_Success() (gas: 206221) OffRamp_commit:test_ZeroEpochAndRound_Revert() (gas: 53305) -OffRamp_constructor:test_Constructor_Success() (gas: 6179080) -OffRamp_constructor:test_SourceChainSelector_Revert() (gas: 136555) -OffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103592) -OffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101441) -OffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 162036) -OffRamp_constructor:test_ZeroRMNRemote_Revert() (gas: 101358) -OffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101362) +OffRamp_constructor:test_Constructor_Success() (gas: 6210339) +OffRamp_constructor:test_SourceChainSelector_Revert() (gas: 137118) +OffRamp_constructor:test_ZeroChainSelector_Revert() (gas: 103828) +OffRamp_constructor:test_ZeroNonceManager_Revert() (gas: 101677) +OffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 162599) +OffRamp_constructor:test_ZeroRMNRemote_Revert() (gas: 101597) +OffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101598) OffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17532) OffRamp_execute:test_LargeBatch_Success() (gas: 3378447) OffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 371209) OffRamp_execute:test_MultipleReports_Success() (gas: 298806) -OffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 7041684) -OffRamp_execute:test_NoConfig_Revert() (gas: 6266154) +OffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 7072622) +OffRamp_execute:test_NoConfig_Revert() (gas: 6297092) OffRamp_execute:test_NonArray_Revert() (gas: 27572) OffRamp_execute:test_SingleReport_Success() (gas: 175631) OffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 147790) -OffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6933352) +OffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6964290) OffRamp_execute:test_ZeroReports_Revert() (gas: 17248) OffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens() (gas: 56213) OffRamp_executeSingleMessage:test_executeSingleMessage_NonContract() (gas: 20508) -OffRamp_executeSingleMessage:test_executeSingleMessage_NonContractWithTokens() (gas: 238042) +OffRamp_executeSingleMessage:test_executeSingleMessage_NonContractWithTokens() (gas: 238130) OffRamp_executeSingleMessage:test_executeSingleMessage_WithMessageInterceptor() (gas: 91994) -OffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens() (gas: 268135) +OffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens() (gas: 268223) OffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 28659) OffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 15530) -OffRamp_executeSingleReport:test_InvalidSourcePoolAddress() (gas: 474650) +OffRamp_executeSingleReport:test_InvalidSourcePoolAddress() (gas: 474738) OffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 48296) OffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 34101) OffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 28824) @@ -447,15 +443,15 @@ OffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: OffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 212456) OffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 243699) OffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 141510) -OffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 402534) +OffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 402622) OffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 58242) OffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 73812) -OffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 574160) -OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 522711) +OffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 574336) +OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 522887) OffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 26795) -OffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 540787) -OffRamp_executeSingleReport:test_Unhealthy_Success() (gas: 540734) -OffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 451824) +OffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 540963) +OffRamp_executeSingleReport:test_Unhealthy_Success() (gas: 540910) +OffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 452000) OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 135231) OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 164892) OffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3905742) @@ -482,20 +478,20 @@ OffRamp_releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: OffRamp_releaseOrMintSingleToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 36790) OffRamp_releaseOrMintSingleToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 91430) OffRamp_releaseOrMintSingleToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 83518) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens() (gas: 168784) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens() (gas: 168872) OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_RevertWhenInvalidDataLengthReturnData() (gas: 62822) OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_RevertWhenPoolDoesNotSupportDest() (gas: 78426) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_WithGasOverride() (gas: 170654) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals() (gas: 181893) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_WithGasOverride() (gas: 170742) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals() (gas: 181981) OffRamp_setDynamicConfig:test_FeeQuoterZeroAddress_Revert() (gas: 11465) OffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 13975) OffRamp_setDynamicConfig:test_SetDynamicConfigWithInterceptor_Success() (gas: 47491) OffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 25464) -OffRamp_trialExecute:test_trialExecute() (gas: 271771) -OffRamp_trialExecute:test_trialExecute_RateLimitError() (gas: 127457) -OffRamp_trialExecute:test_trialExecute_TokenHandlingErrorIsCaught() (gas: 138767) -OffRamp_trialExecute:test_trialExecute_TokenPoolIsNotAContract() (gas: 289412) -OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 251706) +OffRamp_trialExecute:test_trialExecute() (gas: 271859) +OffRamp_trialExecute:test_trialExecute_RateLimitError() (gas: 127545) +OffRamp_trialExecute:test_trialExecute_TokenHandlingErrorIsCaught() (gas: 138855) +OffRamp_trialExecute:test_trialExecute_TokenPoolIsNotAContract() (gas: 289500) +OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 251641) OnRamp_applyAllowlistUpdates:test_applyAllowlistUpdates_InvalidAllowListRequestDisabledAllowListWithAdds() (gas: 17227) OnRamp_applyAllowlistUpdates:test_applyAllowlistUpdates_Revert() (gas: 67101) OnRamp_applyAllowlistUpdates:test_applyAllowlistUpdates_Success() (gas: 325983) @@ -525,7 +521,7 @@ OnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: OnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 213144) OnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 147070) OnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 161303) -OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3963792) +OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 4073863) OnRamp_forwardFromRouter:test_UnAllowedOriginalSender_Revert() (gas: 24015) OnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 75854) OnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 38588) @@ -614,10 +610,8 @@ RegistryModuleOwnerCustom_registerAdminViaGetCCIPAdmin:test_registerAdminViaGetC RegistryModuleOwnerCustom_registerAdminViaGetCCIPAdmin:test_registerAdminViaGetCCIPAdmin_Success() (gas: 130126) RegistryModuleOwnerCustom_registerAdminViaOwner:test_registerAdminViaOwner_Revert() (gas: 19602) RegistryModuleOwnerCustom_registerAdminViaOwner:test_registerAdminViaOwner_Success() (gas: 129930) -Router_applyRampUpdates:test_OffRampMismatch_Revert() (gas: 89591) -Router_applyRampUpdates:test_OffRampUpdatesWithRouting() (gas: 10750087) -Router_applyRampUpdates:test_OnRampDisable() (gas: 56445) -Router_applyRampUpdates:test_OnlyOwner_Revert() (gas: 12414) +Router_applyRampUpdates:test_applyRampUpdates_OffRampUpdatesWithRouting() (gas: 10749731) +Router_applyRampUpdates:test_applyRampUpdates_OnRampDisable() (gas: 56422) Router_ccipSend:test_CCIPSendLinkFeeNoTokenSuccess_gas() (gas: 131447) Router_ccipSend:test_CCIPSendLinkFeeOneTokenSuccess_gas() (gas: 221710) Router_ccipSend:test_FeeTokenAmountTooLow_Revert() (gas: 71858) @@ -671,14 +665,14 @@ TokenAdminRegistry_setPool:test_setPool_ZeroAddressRemovesPool_Success() (gas: 3 TokenAdminRegistry_transferAdminRole:test_transferAdminRole_OnlyAdministrator_Revert() (gas: 18202) TokenAdminRegistry_transferAdminRole:test_transferAdminRole_Success() (gas: 49592) TokenPoolFactory_constructor:test_constructor_Revert() (gas: 1121653) -TokenPoolFactory_createTokenPool:test_createTokenPoolLockRelease_ExistingToken_predict_Success() (gas: 12386310) -TokenPoolFactory_createTokenPool:test_createTokenPool_BurnFromMintTokenPool_Success() (gas: 6364709) -TokenPoolFactory_createTokenPool:test_createTokenPool_ExistingRemoteToken_AndPredictPool_Success() (gas: 13167390) -TokenPoolFactory_createTokenPool:test_createTokenPool_RemoteTokenHasDifferentDecimals_Success() (gas: 13174692) -TokenPoolFactory_createTokenPool:test_createTokenPool_WithNoExistingRemoteContracts_predict_Success() (gas: 13504109) -TokenPoolFactory_createTokenPool:test_createTokenPool_WithNoExistingTokenOnRemoteChain_Success() (gas: 6150583) -TokenPoolFactory_createTokenPool:test_createTokenPool_WithRemoteTokenAndRemotePool_Success() (gas: 6361166) -TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 2717776) +TokenPoolFactory_createTokenPool:test_createTokenPoolLockRelease_ExistingToken_predict_Success() (gas: 12612969) +TokenPoolFactory_createTokenPool:test_createTokenPool_BurnFromMintTokenPool_Success() (gas: 6513874) +TokenPoolFactory_createTokenPool:test_createTokenPool_ExistingRemoteToken_AndPredictPool_Success() (gas: 13434268) +TokenPoolFactory_createTokenPool:test_createTokenPool_RemoteTokenHasDifferentDecimals_Success() (gas: 13441570) +TokenPoolFactory_createTokenPool:test_createTokenPool_WithNoExistingRemoteContracts_predict_Success() (gas: 13771048) +TokenPoolFactory_createTokenPool:test_createTokenPool_WithNoExistingTokenOnRemoteChain_Success() (gas: 6301066) +TokenPoolFactory_createTokenPool:test_createTokenPool_WithRemoteTokenAndRemotePool_Success() (gas: 6510314) +TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 2827849) TokenPoolWithAllowList_applyAllowListUpdates:test_OnlyOwner_Revert() (gas: 12119) TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowListSkipsZero_Success() (gas: 23567) TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowList_Success() (gas: 178398) @@ -699,7 +693,7 @@ TokenPool_applyChainUpdates:test_applyChainUpdates_UpdatesRemotePoolHashes() (ga TokenPool_applyChainUpdates:test_applyChainUpdates_ZeroAddressNotAllowed_Revert() (gas: 226472) TokenPool_calculateLocalAmount:test_calculateLocalAmount() (gas: 93680) TokenPool_constructor:test_constructor() (gas: 21930) -TokenPool_constructor:test_constructor_DecimalCallFails() (gas: 2714089) +TokenPool_constructor:test_constructor_DecimalCallFails() (gas: 2824157) TokenPool_getRemotePool:test_getRemotePools() (gas: 330500) TokenPool_onlyOffRamp:test_CallerIsNotARampOnRouter_Revert() (gas: 21504) TokenPool_onlyOffRamp:test_ChainNotAllowed_Revert() (gas: 240435) @@ -714,44 +708,47 @@ TokenPool_removeRemotePool:test_NonExistentChain_Revert() (gas: 14344) TokenPool_removeRemotePool:test_removeRemotePool_Success() (gas: 188387) TokenPool_setChainRateLimiterConfig:test_NonExistentChain_Revert() (gas: 17214) TokenPool_setChainRateLimiterConfig:test_OnlyOwnerOrRateLimitAdmin_Revert() (gas: 15307) +TokenPool_setChainRateLimiterConfigs:test_MismatchedArrayLengths_Revert() (gas: 23960) +TokenPool_setChainRateLimiterConfigs:test_NonExistentChain_Revert() (gas: 19424) +TokenPool_setChainRateLimiterConfigs:test_OnlyOwnerOrRateLimitAdmin_Revert() (gas: 16511) TokenPool_setRateLimitAdmin:test_SetRateLimitAdmin_Revert() (gas: 11002) TokenPool_setRateLimitAdmin:test_SetRateLimitAdmin_Success() (gas: 37606) -USDCBridgeMigrator_BurnLockedUSDC:test_PrimaryMechanism_Success() (gas: 135869) -USDCBridgeMigrator_BurnLockedUSDC:test_WhileMigrationPause_Revert() (gas: 109729) +USDCBridgeMigrator_BurnLockedUSDC:test_PrimaryMechanism_Success() (gas: 135887) +USDCBridgeMigrator_BurnLockedUSDC:test_WhileMigrationPause_Revert() (gas: 109751) USDCBridgeMigrator_BurnLockedUSDC:test_invalidPermissions_Revert() (gas: 39493) -USDCBridgeMigrator_BurnLockedUSDC:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 309798) -USDCBridgeMigrator_BurnLockedUSDC:test_onLockReleaseMechanism_Success() (gas: 146939) -USDCBridgeMigrator_BurnLockedUSDC:test_onLockReleaseMechanism_thenSwitchToPrimary_Success() (gas: 209089) +USDCBridgeMigrator_BurnLockedUSDC:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 309833) +USDCBridgeMigrator_BurnLockedUSDC:test_onLockReleaseMechanism_Success() (gas: 146961) +USDCBridgeMigrator_BurnLockedUSDC:test_onLockReleaseMechanism_thenSwitchToPrimary_Success() (gas: 209124) USDCBridgeMigrator_cancelMigrationProposal:test_cancelExistingCCTPMigrationProposal_Success() (gas: 56155) USDCBridgeMigrator_cancelMigrationProposal:test_cannotCancelANonExistentMigrationProposal_Revert() (gas: 12669) USDCBridgeMigrator_excludeTokensFromBurn:test_excludeTokensWhenNoMigrationProposalPending_Revert() (gas: 13579) USDCBridgeMigrator_proposeMigration:test_ChainNotUsingLockRelease_Revert() (gas: 15765) -USDCBridgeMigrator_provideLiquidity:test_PrimaryMechanism_Success() (gas: 135986) -USDCBridgeMigrator_provideLiquidity:test_WhileMigrationPause_Revert() (gas: 109871) +USDCBridgeMigrator_provideLiquidity:test_PrimaryMechanism_Success() (gas: 136004) +USDCBridgeMigrator_provideLiquidity:test_WhileMigrationPause_Revert() (gas: 109893) USDCBridgeMigrator_provideLiquidity:test_cannotModifyLiquidityWithoutPermissions_Revert() (gas: 13390) USDCBridgeMigrator_provideLiquidity:test_cannotProvideLiquidityWhenMigrationProposalPending_Revert() (gas: 67428) -USDCBridgeMigrator_provideLiquidity:test_cannotProvideLiquidity_AfterMigration_Revert() (gas: 313898) +USDCBridgeMigrator_provideLiquidity:test_cannotProvideLiquidity_AfterMigration_Revert() (gas: 313933) USDCBridgeMigrator_provideLiquidity:test_invalidPermissions_Revert() (gas: 39493) -USDCBridgeMigrator_provideLiquidity:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 310057) -USDCBridgeMigrator_provideLiquidity:test_onLockReleaseMechanism_Success() (gas: 147080) -USDCBridgeMigrator_provideLiquidity:test_onLockReleaseMechanism_thenSwitchToPrimary_Success() (gas: 209395) +USDCBridgeMigrator_provideLiquidity:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 310092) +USDCBridgeMigrator_provideLiquidity:test_onLockReleaseMechanism_Success() (gas: 147102) +USDCBridgeMigrator_provideLiquidity:test_onLockReleaseMechanism_thenSwitchToPrimary_Success() (gas: 209430) USDCBridgeMigrator_releaseOrMint:test_OnLockReleaseMechanism_Success() (gas: 213160) USDCBridgeMigrator_releaseOrMint:test_WhileMigrationPause_Revert() (gas: 109679) USDCBridgeMigrator_releaseOrMint:test_incomingMessageWithPrimaryMechanism() (gas: 265963) USDCBridgeMigrator_releaseOrMint:test_unstickManualTxAfterMigration_destChain_Success() (gas: 150538) USDCBridgeMigrator_releaseOrMint:test_unstickManualTxAfterMigration_homeChain_Success() (gas: 511783) -USDCBridgeMigrator_updateChainSelectorMechanism:test_PrimaryMechanism_Success() (gas: 136004) -USDCBridgeMigrator_updateChainSelectorMechanism:test_WhileMigrationPause_Revert() (gas: 109849) -USDCBridgeMigrator_updateChainSelectorMechanism:test_cannotRevertChainMechanism_afterMigration_Revert() (gas: 313496) +USDCBridgeMigrator_updateChainSelectorMechanism:test_PrimaryMechanism_Success() (gas: 136021) +USDCBridgeMigrator_updateChainSelectorMechanism:test_WhileMigrationPause_Revert() (gas: 109871) +USDCBridgeMigrator_updateChainSelectorMechanism:test_cannotRevertChainMechanism_afterMigration_Revert() (gas: 313532) USDCBridgeMigrator_updateChainSelectorMechanism:test_invalidPermissions_Revert() (gas: 39471) -USDCBridgeMigrator_updateChainSelectorMechanism:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 310057) -USDCBridgeMigrator_updateChainSelectorMechanism:test_onLockReleaseMechanism_Success() (gas: 147035) -USDCBridgeMigrator_updateChainSelectorMechanism:test_onLockReleaseMechanism_thenSwitchToPrimary_Success() (gas: 209448) +USDCBridgeMigrator_updateChainSelectorMechanism:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 310092) +USDCBridgeMigrator_updateChainSelectorMechanism:test_onLockReleaseMechanism_Success() (gas: 147057) +USDCBridgeMigrator_updateChainSelectorMechanism:test_onLockReleaseMechanism_thenSwitchToPrimary_Success() (gas: 209483) USDCTokenPool__validateMessage:test_ValidateInvalidMessage_Revert() (gas: 26049) -USDCTokenPool_lockOrBurn:test_CallerIsNotARampOnRouter_Revert() (gas: 35297) -USDCTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 29875) -USDCTokenPool_lockOrBurn:test_LockOrBurn_Success() (gas: 133408) -USDCTokenPool_lockOrBurn:test_UnknownDomain_Revert() (gas: 433408) +USDCTokenPool_lockOrBurn:test_CallerIsNotARampOnRouter_Revert() (gas: 35319) +USDCTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 29897) +USDCTokenPool_lockOrBurn:test_LockOrBurn_Success() (gas: 133426) +USDCTokenPool_lockOrBurn:test_UnknownDomain_Revert() (gas: 433430) USDCTokenPool_releaseOrMint:test_ReleaseOrMintRealTx_Success() (gas: 265695) USDCTokenPool_releaseOrMint:test_TokenMaxCapacityExceeded_Revert() (gas: 47231) USDCTokenPool_releaseOrMint:test_UnlockingUSDCFailed_Revert() (gas: 95262) diff --git a/contracts/gas-snapshots/l2ep.gas-snapshot b/contracts/gas-snapshots/l2ep.gas-snapshot index 643127b6212..7caca346f48 100644 --- a/contracts/gas-snapshots/l2ep.gas-snapshot +++ b/contracts/gas-snapshots/l2ep.gas-snapshot @@ -34,6 +34,18 @@ ArbitrumSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerA ArbitrumSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 114527) ArbitrumSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 114610) ArbitrumValidator_Validate:test_PostSequencerOffline() (gas: 69009) +BaseSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface_ReturnsValidData() (gas: 69197) +BaseSequencerUptimeFeed_AggregatorV3Interface:test_getAnswer_ReturnsValidAnswer() (gas: 57300) +BaseSequencerUptimeFeed_AggregatorV3Interface:test_getTimestamp_ReturnsValidTimestamp() (gas: 57151) +BaseSequencerUptimeFeed_Constructor:test_Constructor_InitialState() (gas: 22050) +BaseSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_ProtectReads_AllowWhen_Whitelisted() (gas: 589517) +BaseSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_ProtectReads_DisallowWhen_NotWhitelisted() (gas: 562342) +BaseSequencerUptimeFeed_UpdateStatus:test_updateStatus_IgnoreOutOfOrderUpdates() (gas: 69490) +BaseSequencerUptimeFeed_UpdateStatus:test_updateStatus_UpdateWhen_NoStatusChangeSameTimestamp() (gas: 77166) +BaseSequencerUptimeFeed_UpdateStatus:test_updateStatus_UpdateWhen_StatusChangeAndNoTimeChange() (gas: 96021) +BaseSequencerUptimeFeed_UpdateStatus:test_updateStatus_UpdateWhen_StatusChangeAndTimeChange() (gas: 96100) +BaseSequencerUptimeFeed_transferL1Sender:test_transferL1Sender_CorrectlyTransfersL1Sender() (gas: 1479310) +BaseValidator_GetAndSetGasLimit:test_GetAndSetGasLimit_CorrectlyHandlesGasLimit() (gas: 20119) OptimismCrossDomainForwarder_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47110) OptimismCrossDomainForwarder_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 22135) OptimismCrossDomainForwarder_Constructor:test_InitialState() (gas: 21947) @@ -60,23 +72,10 @@ OptimismCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 4 OptimismCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28733) OptimismCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16456) OptimismCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11044) -OptimismSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 72286) -OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17639) -OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17875) -OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17628) -OptimismSequencerUptimeFeed_Constructor:test_InitialState() (gas: 22002) -OptimismSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 589475) -OptimismSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 562336) -OptimismSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 67804) -OptimismSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13109) -OptimismSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddrAndNotL1SenderAddr() (gas: 23523) -OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 77205) -OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 96089) -OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 96172) -OptimismValidator_SetGasLimit:test_CorrectlyUpdatesTheGasLimit() (gas: 18636) -OptimismValidator_Validate:test_PostSequencerOffline() (gas: 74764) -OptimismValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 74798) -OptimismValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15556) +OptimismSequencerUptimeFeed_Constructor:test_Constructor_InitialState() (gas: 1530881) +OptimismSequencerUptimeFeed_ValidateSender:test_ValidateSender_UpdateStatusWhen_StatusChangeAndNoTimeChange() (gas: 17874) +OptimismValidator_Validate:test_Validate_PostSequencerOffline() (gas: 74773) +OptimismValidator_Validate:test_Validate_PostSequencerStatus_NoStatusChange() (gas: 74788) ScrollCrossDomainForwarder_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47196) ScrollCrossDomainForwarder_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 22185) ScrollCrossDomainForwarder_Constructor:test_InitialState() (gas: 21623) @@ -103,40 +102,12 @@ ScrollCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 489 ScrollCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28791) ScrollCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16456) ScrollCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11044) -ScrollSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 72309) -ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17639) -ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17875) -ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17628) -ScrollSequencerUptimeFeed_Constructor:test_InitialState() (gas: 174353) -ScrollSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 589475) -ScrollSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 562336) -ScrollSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 67850) -ScrollSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13109) -ScrollSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddrAndNotL1SenderAddr() (gas: 23523) -ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 77251) -ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 96135) -ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 96218) -ScrollValidator_SetGasLimit:test_CorrectlyUpdatesTheGasLimit() (gas: 18770) -ScrollValidator_Validate:test_PostSequencerOffline() (gas: 78299) -ScrollValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 78339) -ScrollValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15556) -ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 67090) -ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17639) -ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17875) -ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17628) -ZKSyncSequencerUptimeFeed_Constructor:test_InitialState() (gas: 22006) -ZKSyncSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 589495) -ZKSyncSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 562342) -ZKSyncSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 61883) -ZKSyncSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13055) -ZKSyncSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 71321) -ZKSyncSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 90176) -ZKSyncSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 90259) -ZKSyncValidator_Constructor:test_ConstructingRevertedWithInvalidChainId() (gas: 104069) -ZKSyncValidator_Constructor:test_ConstructingRevertedWithZeroL1BridgeAddress() (gas: 81784) -ZKSyncValidator_Constructor:test_ConstructingRevertedWithZeroL2UpdateFeedAddress() (gas: 81796) -ZKSyncValidator_GetChainId:test_CorrectlyGetsTheChainId() (gas: 8346) -ZKSyncValidator_GetSetL2GasPerPubdataByteLimit:test_CorrectlyGetsAndUpdatesTheGasPerPubdataByteLimit() (gas: 18896) -ZKSyncValidator_Validate:test_PostSequencerOffline() (gas: 52210) -ZKSyncValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 52279) -ZKSyncValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15623) \ No newline at end of file +ScrollSequencerUptimeFeed_Constructor:test_Constructor_InitialState_WhenValidL2XDomainMessenger() (gas: 1511902) +ScrollSequencerUptimeFeed_ValidateSender:test_ValidateSender_UpdateStatusWhen_StatusChangeAndNoTimeChange() (gas: 17864) +ScrollValidator_Validate:test_Validate_PostSequencerOffline() (gas: 78317) +ScrollValidator_Validate:test_Validate_PostSequencerStatus_NoStatusChange() (gas: 78338) +ZKSyncSequencerUptimeFeed_ValidateSender:test_ValidateSender_SuccessWhen_SenderIsValid() (gas: 12611) +ZKSyncValidator_GetChainId:test_GetChainId_CorrectlyGetsTheChainId() (gas: 8369) +ZKSyncValidator_GetSetL2GasPerPubdataByteLimit:test_GetSetL2GasPerPubdataByteLimit_CorrectlyHandlesGasPerPubdataByteLimit() (gas: 18918) +ZKSyncValidator_Validate:test_Validate_PostSequencerOffline() (gas: 52208) +ZKSyncValidator_Validate:test_Validate_PostSequencerStatus_NoStatusChange() (gas: 52280) \ No newline at end of file diff --git a/contracts/gas-snapshots/liquiditymanager.gas-snapshot b/contracts/gas-snapshots/liquiditymanager.gas-snapshot index 2e2d0962186..bc545b69d38 100644 --- a/contracts/gas-snapshots/liquiditymanager.gas-snapshot +++ b/contracts/gas-snapshots/liquiditymanager.gas-snapshot @@ -3,9 +3,9 @@ LiquidityManager_addLiquidity:test_addLiquiditySuccess() (gas: 279198) LiquidityManager_rebalanceLiquidity:test_InsufficientLiquidityReverts() (gas: 206764) LiquidityManager_rebalanceLiquidity:test_InvalidRemoteChainReverts() (gas: 192374) LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess() (gas: 9141798) -LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess_AlreadyFinalized() (gas: 9306766) -LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_MultiStageFinalization() (gas: 9301906) -LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_NativeRewrap() (gas: 9231739) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess_AlreadyFinalized() (gas: 9435757) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_MultiStageFinalization() (gas: 9430897) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_NativeRewrap() (gas: 9360730) LiquidityManager_rebalanceLiquidity:test_rebalanceLiquiditySuccess() (gas: 382928) LiquidityManager_receive:test_receive_success() (gas: 21182) LiquidityManager_removeLiquidity:test_InsufficientLiquidityReverts() (gas: 184959) @@ -19,7 +19,7 @@ LiquidityManager_setFinanceRole:test_OnlyOwnerReverts() (gas: 10987) LiquidityManager_setFinanceRole:test_setFinanceRoleSuccess() (gas: 21836) LiquidityManager_setLocalLiquidityContainer:test_OnlyOwnerReverts() (gas: 11030) LiquidityManager_setLocalLiquidityContainer:test_ReverstWhen_CalledWithTheZeroAddress() (gas: 10621) -LiquidityManager_setLocalLiquidityContainer:test_setLocalLiquidityContainerSuccess() (gas: 3847203) +LiquidityManager_setLocalLiquidityContainer:test_setLocalLiquidityContainerSuccess() (gas: 3976150) LiquidityManager_setMinimumLiquidity:test_OnlyOwnerReverts() (gas: 10925) LiquidityManager_setMinimumLiquidity:test_setMinimumLiquiditySuccess() (gas: 36389) LiquidityManager_withdrawERC20:test_withdrawERC20Reverts() (gas: 180396) diff --git a/contracts/gas-snapshots/workflow.gas-snapshot b/contracts/gas-snapshots/workflow.gas-snapshot index 73fdfbf7187..bdfd2b24aec 100644 --- a/contracts/gas-snapshots/workflow.gas-snapshot +++ b/contracts/gas-snapshots/workflow.gas-snapshot @@ -17,9 +17,9 @@ WorkflowRegistryManager_getVersion:test_WhenVersionNumberIsRegistered() (gas: 28 WorkflowRegistryManager_getVersionNumberByContractAddressAndChainID:test_WhenAVersionIsRegisteredForTheContractAddressAndChainIDCombination() (gas: 285022) WorkflowRegistryManager_getVersionNumberByContractAddressAndChainID:test_WhenNoVersionIsRegisteredForTheContractAddressAndChainIDCombination() (gas: 286634) WorkflowRegistryManager_getVersionNumberByContractAddressAndChainID:test_WhenTheContractAddressIsInvalid() (gas: 284604) -WorkflowRegistry_activateWorkflow:test_WhenTheCallerIsAnAuthorizedAddress() (gas: 495029) -WorkflowRegistry_deleteWorkflow:test_WhenTheCallerIsAnAuthorizedAddress_AndTheDonIDIsAllowed() (gas: 403945) -WorkflowRegistry_deleteWorkflow:test_WhenTheCallerIsAnAuthorizedAddress_AndTheDonIDIsNotAllowed() (gas: 421748) +WorkflowRegistry_activateWorkflow:test_WhenTheCallerIsAnAuthorizedAddress() (gas: 517416) +WorkflowRegistry_deleteWorkflow:test_WhenTheCallerIsAnAuthorizedAddress_AndTheDonIDIsAllowed() (gas: 422157) +WorkflowRegistry_deleteWorkflow:test_WhenTheCallerIsAnAuthorizedAddress_AndTheDonIDIsNotAllowed() (gas: 439960) WorkflowRegistry_getAllAllowedDONs:test_WhenTheRegistryIsLocked() (gas: 47473) WorkflowRegistry_getAllAllowedDONs:test_WhenTheSetOfAllowedDONsIsEmpty() (gas: 25780) WorkflowRegistry_getAllAllowedDONs:test_WhenThereAreMultipleAllowedDONs() (gas: 75437) @@ -28,9 +28,9 @@ WorkflowRegistry_getAllAuthorizedAddresses:test_WhenTheRegistryIsLocked() (gas: WorkflowRegistry_getAllAuthorizedAddresses:test_WhenTheSetOfAuthorizedAddressesIsEmpty() (gas: 26152) WorkflowRegistry_getAllAuthorizedAddresses:test_WhenThereAreMultipleAuthorizedAddresses() (gas: 78270) WorkflowRegistry_getAllAuthorizedAddresses:test_WhenThereIsASingleAuthorizedAddress() (gas: 16832) -WorkflowRegistry_getWorkflowMetadata:test_WhenTheRegistryIsLocked() (gas: 519145) +WorkflowRegistry_getWorkflowMetadata:test_WhenTheRegistryIsLocked() (gas: 541532) WorkflowRegistry_getWorkflowMetadata:test_WhenTheWorkflowDoesNotExist() (gas: 17543) -WorkflowRegistry_getWorkflowMetadata:test_WhenTheWorkflowExistsWithTheOwnerAndName() (gas: 490001) +WorkflowRegistry_getWorkflowMetadata:test_WhenTheWorkflowExistsWithTheOwnerAndName() (gas: 512388) WorkflowRegistry_getWorkflowMetadataListByDON:test_WhenLimitExceedsTotalWorkflows() (gas: 128146) WorkflowRegistry_getWorkflowMetadataListByDON:test_WhenLimitIsEqualToTotalWorkflows() (gas: 128035) WorkflowRegistry_getWorkflowMetadataListByDON:test_WhenLimitIsLessThanTotalWorkflows() (gas: 90141) @@ -48,17 +48,17 @@ WorkflowRegistry_getWorkflowMetadataListByOwner:test_WhenStartIsGreaterThanOrEqu WorkflowRegistry_getWorkflowMetadataListByOwner:test_WhenTheOwnerHasNoWorkflows() (gas: 14006) WorkflowRegistry_getWorkflowMetadataListByOwner:test_WhenTheRegistryIsLocked() (gas: 165968) WorkflowRegistry_lockRegistry:test_WhenTheCallerIsTheContractOwner() (gas: 38758) -WorkflowRegistry_pauseWorkflow:test_WhenTheDonIDIsAllowed_AndTheCallerIsAnAuthorizedAddress() (gas: 494993) -WorkflowRegistry_pauseWorkflow:test_WhenTheDonIDIsAllowed_AndTheCallerIsAnUnauthorizedAddress() (gas: 502796) -WorkflowRegistry_pauseWorkflow:test_WhenTheDonIDIsNotAllowed_AndTheCallerIsAnAuthorizedAddress() (gas: 502555) -WorkflowRegistry_pauseWorkflow:test_WhenTheDonIDIsNotAllowed_AndTheCallerIsAnUnauthorizedAddress() (gas: 506966) -WorkflowRegistry_registerWorkflow:test_WhenTheWorkflowInputsAreAllValid() (gas: 549769) -WorkflowRegistry_requestForceUpdateSecrets:test_WhenTheCallerIsAnAuthorizedAddress_AndTheWorkflowIsInAnAllowedDON() (gas: 891242) -WorkflowRegistry_requestForceUpdateSecrets:test_WhenTheCallerIsAnAuthorizedAddress_AndTheWorkflowIsNotInAnAllowedDON() (gas: 488397) -WorkflowRegistry_requestForceUpdateSecrets:test_WhenTheCallerIsNotAnAuthorizedAddress() (gas: 486751) +WorkflowRegistry_pauseWorkflow:test_WhenTheDonIDIsAllowed_AndTheCallerIsAnAuthorizedAddress() (gas: 517380) +WorkflowRegistry_pauseWorkflow:test_WhenTheDonIDIsAllowed_AndTheCallerIsAnUnauthorizedAddress() (gas: 525183) +WorkflowRegistry_pauseWorkflow:test_WhenTheDonIDIsNotAllowed_AndTheCallerIsAnAuthorizedAddress() (gas: 524942) +WorkflowRegistry_pauseWorkflow:test_WhenTheDonIDIsNotAllowed_AndTheCallerIsAnUnauthorizedAddress() (gas: 529353) +WorkflowRegistry_registerWorkflow:test_WhenTheWorkflowInputsAreAllValid() (gas: 572178) +WorkflowRegistry_requestForceUpdateSecrets:test_WhenTheCallerIsAnAuthorizedAddress_AndTheWorkflowIsInAnAllowedDON() (gas: 936016) +WorkflowRegistry_requestForceUpdateSecrets:test_WhenTheCallerIsAnAuthorizedAddress_AndTheWorkflowIsNotInAnAllowedDON() (gas: 510784) +WorkflowRegistry_requestForceUpdateSecrets:test_WhenTheCallerIsNotAnAuthorizedAddress() (gas: 509138) WorkflowRegistry_unlockRegistry:test_WhenTheCallerIsTheContractOwner() (gas: 30325) WorkflowRegistry_updateAllowedDONs:test_WhenTheBoolInputIsFalse() (gas: 29739) WorkflowRegistry_updateAllowedDONs:test_WhenTheBoolInputIsTrue() (gas: 170296) WorkflowRegistry_updateAuthorizedAddresses:test_WhenTheBoolInputIsFalse() (gas: 30278) WorkflowRegistry_updateAuthorizedAddresses:test_WhenTheBoolInputIsTrue() (gas: 175515) -WorkflowRegistry_updateWorkflow:test_WhenTheWorkflowInputsAreAllValid() (gas: 479601) +WorkflowRegistry_updateWorkflow:test_WhenTheWorkflowInputsAreAllValid() (gas: 515666) diff --git a/contracts/src/v0.8/ccip/FeeQuoter.sol b/contracts/src/v0.8/ccip/FeeQuoter.sol index 58261eff499..b312e732e61 100644 --- a/contracts/src/v0.8/ccip/FeeQuoter.sol +++ b/contracts/src/v0.8/ccip/FeeQuoter.sol @@ -103,12 +103,12 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver, // The following three properties are defaults, they can be overridden by setting the TokenTransferFeeConfig for a token. uint16 defaultTokenFeeUSDCents; // │ Default token fee charged per token transfer. uint32 defaultTokenDestGasOverhead; // ──────╯ Default gas charged to execute a token transfer on the destination chain. - uint32 defaultTxGasLimit; //─────────────────╮ Default gas limit for a tx. - uint64 gasMultiplierWeiPerEth; // │ Multiplier for gas costs, 1e18 based so 11e17 = 10% extra cost. - uint32 networkFeeUSDCents; // │ Flat network fee to charge for messages, multiples of 0.01 USD. - uint32 gasPriceStalenessThreshold; // │ The amount of time a gas price can be stale before it is considered invalid (0 means disabled). - bool enforceOutOfOrder; // │ Whether to enforce the allowOutOfOrderExecution extraArg value to be true. - bytes4 chainFamilySelector; // ──────────────╯ Selector that identifies the destination chain's family. Used to determine the correct validations to perform for the dest chain. + uint32 defaultTxGasLimit; //──────────╮ Default gas limit for a tx. + uint64 gasMultiplierWeiPerEth; // │ Multiplier for gas costs, 1e18 based so 11e17 = 10% extra cost. + uint32 networkFeeUSDCents; // │ Flat network fee to charge for messages, multiples of 0.01 USD. + uint32 gasPriceStalenessThreshold; // │ The amount of time a gas price can be stale before it is considered invalid (0 means disabled). + bool enforceOutOfOrder; // │ Whether to enforce the allowOutOfOrderExecution extraArg value to be true. + bytes4 chainFamilySelector; // ───────╯ Selector that identifies the destination chain's family. Used to determine the correct validations to perform for the dest chain. } /// @dev Struct to hold the configs and its destination chain selector. Same as DestChainConfig but with the @@ -121,13 +121,13 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver, /// @dev Struct with transfer fee configuration for token transfers. struct TokenTransferFeeConfig { - uint32 minFeeUSDCents; // ────╮ Minimum fee to charge per token transfer, multiples of 0.01 USD. - uint32 maxFeeUSDCents; // │ Maximum fee to charge per token transfer, multiples of 0.01 USD. - uint16 deciBps; // │ Basis points charged on token transfers, multiples of 0.1bps, or 1e-5. - uint32 destGasOverhead; // │ Gas charged to execute the token transfer on the destination chain. - // │ Extra data availability bytes that are returned from the source pool and sent to - uint32 destBytesOverhead; // │ the destination pool. Must be >= Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES. - bool isEnabled; // ───────────╯ Whether this token has custom transfer fees. + uint32 minFeeUSDCents; // ───╮ Minimum fee to charge per token transfer, multiples of 0.01 USD. + uint32 maxFeeUSDCents; // │ Maximum fee to charge per token transfer, multiples of 0.01 USD. + uint16 deciBps; // │ Basis points charged on token transfers, multiples of 0.1bps, or 1e-5. + uint32 destGasOverhead; // │ Gas charged to execute the token transfer on the destination chain. + // │ Data availability bytes that are returned from the source pool and sent to the dest + uint32 destBytesOverhead; // │ pool. Must be >= Pool.CCIP_LOCK_OR_BURN_V1_RET_BYTES. Set as multiple of 32 bytes. + bool isEnabled; // ──────────╯ Whether this token has custom transfer fees. } /// @dev Struct with token transfer fee configurations for a token, same as TokenTransferFeeConfig but with the token @@ -517,6 +517,7 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver, for (uint256 i = 0; i < feeds.length; ++i) { TokenPriceFeedConfig memory feedConfig = s_usdPriceFeedsPerToken[feeds[i].token]; + // If the token is not enabled we revert the entire report as that indicates some type of misconfiguration. if (!feedConfig.isEnabled) { revert TokenNotSupported(feeds[i].token); } @@ -710,6 +711,8 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver, continue; } + // In the case where bpsFeeUSDWei, minFeeUSDWei, and maxFeeUSDWei are all 0, we skip the fee. This is intended + // to allow for a fee of 0 to be set. tokenTransferFeeUSDWei += bpsFeeUSDWei; } @@ -863,7 +866,9 @@ contract FeeQuoter is AuthorizedCallers, IFeeQuoter, ITypeAndVersion, IReceiver, if (evmExtraArgs.gasLimit > uint256(destChainConfig.maxPerMsgGasLimit)) revert MessageGasLimitTooHigh(); - // If the chain enforces out of order execution, the extra args must allow it, otherwise revert. + // If the chain enforces out of order execution, the extra args must allow it, otherwise revert. We cannot assume + // the user intended to use OOO on any chain that requires it as it may lead to unexpected behavior. Therefore we + // revert instead of assuming the user intended to use OOO. if (destChainConfig.enforceOutOfOrder && !evmExtraArgs.allowOutOfOrderExecution) { revert ExtraArgOutOfOrderExecutionMustBeTrue(); } diff --git a/contracts/src/v0.8/ccip/LICENSE-MIT.md b/contracts/src/v0.8/ccip/LICENSE-MIT.md deleted file mode 100644 index 812debd8e9b..00000000000 --- a/contracts/src/v0.8/ccip/LICENSE-MIT.md +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2018 SmartContract ChainLink, Ltd. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/contracts/src/v0.8/ccip/NonceManager.sol b/contracts/src/v0.8/ccip/NonceManager.sol index f95380b23b2..382844c27d9 100644 --- a/contracts/src/v0.8/ccip/NonceManager.sol +++ b/contracts/src/v0.8/ccip/NonceManager.sol @@ -33,9 +33,9 @@ contract NonceManager is INonceManager, AuthorizedCallers, ITypeAndVersion { /// @dev The previous on/off ramps per chain selector. mapping(uint64 chainSelector => PreviousRamps previousRamps) private s_previousRamps; - /// @dev The current outbound nonce per sender used on the onramp. + /// @dev The current outbound nonce per sender used on the onRamp. mapping(uint64 destChainSelector => mapping(address sender => uint64 outboundNonce)) private s_outboundNonces; - /// @dev The current inbound nonce per sender used on the offramp. + /// @dev The current inbound nonce per sender used on the offRamp. /// Eventually in sync with the outbound nonce in the remote source chain NonceManager, used to enforce that messages /// are executed in the same order they are sent (assuming they are DON). mapping(uint64 sourceChainSelector => mapping(bytes sender => uint64 inboundNonce)) private s_inboundNonces; @@ -71,6 +71,8 @@ contract NonceManager is INonceManager, AuthorizedCallers, ITypeAndVersion { if (outboundNonce == 0) { address prevOnRamp = s_previousRamps[destChainSelector].prevOnRamp; if (prevOnRamp != address(0)) { + // This gets the current nonce for a sender, not the already incremented nonce like getIncrementedOutboundNonce + // would return. return IEVM2AnyOnRamp(prevOnRamp).getSenderNonce(sender); } } diff --git a/contracts/src/v0.8/ccip/capability/CCIPHome.sol b/contracts/src/v0.8/ccip/capability/CCIPHome.sol index e43e4b0d03f..829c54c5b62 100644 --- a/contracts/src/v0.8/ccip/capability/CCIPHome.sol +++ b/contracts/src/v0.8/ccip/capability/CCIPHome.sol @@ -2,7 +2,6 @@ pragma solidity 0.8.24; import {ICapabilityConfiguration} from "../../keystone/interfaces/ICapabilityConfiguration.sol"; - import {INodeInfoProvider} from "../../keystone/interfaces/INodeInfoProvider.sol"; import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; @@ -111,7 +110,7 @@ contract CCIPHome is Ownable2StepMsgSender, ITypeAndVersion, ICapabilityConfigur uint64 chainSelector; // │ The (remote) chain that the configuration is for. uint8 FRoleDON; // │ The "big F" parameter for the role DON. uint64 offchainConfigVersion; // ──────╯ The version of the exec offchain configuration. - bytes offrampAddress; // The remote chain offramp address. + bytes offrampAddress; // The remote chain offRamp address. bytes rmnHomeAddress; // The home chain RMN home address. OCR3Node[] nodes; // Keys & IDs of nodes part of the role DON. bytes offchainConfig; // The offchain configuration for the OCR3 plugin. Protobuf encoded. @@ -241,10 +240,9 @@ contract CCIPHome is Ownable2StepMsgSender, ITypeAndVersion, ICapabilityConfigur } /// @inheritdoc ICapabilityConfiguration - /// @dev The CCIP capability will fetch the configuration needed directly from this contract. - /// The offchain syncer will call this function, so its important that it doesn't revert. + /// @dev This function is not used in the CCIPHome contract but the interface requires it to be implemented. function getCapabilityConfiguration( - uint32 /* donId */ + uint32 ) external pure override returns (bytes memory configuration) { return bytes(""); } @@ -533,6 +531,15 @@ contract CCIPHome is Ownable2StepMsgSender, ITypeAndVersion, ICapabilityConfigur return s_remoteChainSelectors.length(); } + /// @notice Returns the chain configuration for a given chain selector. + /// @param chainSelector The chain selector. + /// @return chainConfig The chain configuration. + function getChainConfig( + uint64 chainSelector + ) external view returns (ChainConfig memory) { + return s_chainConfigurations[chainSelector]; + } + /// @notice Returns all the chain configurations. /// @param pageIndex The page index. /// @param pageSize The page size. diff --git a/contracts/src/v0.8/ccip/interfaces/IEVM2AnyOnRamp.sol b/contracts/src/v0.8/ccip/interfaces/IEVM2AnyOnRamp.sol index 2d27bd3a25c..e40b186dda4 100644 --- a/contracts/src/v0.8/ccip/interfaces/IEVM2AnyOnRamp.sol +++ b/contracts/src/v0.8/ccip/interfaces/IEVM2AnyOnRamp.sol @@ -8,9 +8,9 @@ interface IEVM2AnyOnRamp is IEVM2AnyOnRampClient { /// @return the next sequence number to be used. function getExpectedNextSequenceNumber() external view returns (uint64); - /// @notice Get the next nonce for a given sender. + /// @notice Get the current nonce for a given sender. /// @param sender The sender to get the nonce for. - /// @return nonce The next nonce for the sender. + /// @return nonce The current nonce for the sender. function getSenderNonce( address sender ) external view returns (uint64 nonce); diff --git a/contracts/src/v0.8/ccip/libraries/Internal.sol b/contracts/src/v0.8/ccip/libraries/Internal.sol index f5bcdd434f7..25d923ee1ed 100644 --- a/contracts/src/v0.8/ccip/libraries/Internal.sol +++ b/contracts/src/v0.8/ccip/libraries/Internal.sol @@ -3,14 +3,14 @@ pragma solidity ^0.8.4; import {MerkleMultiProof} from "../libraries/MerkleMultiProof.sol"; -// Library for CCIP internal definitions common to multiple contracts. +/// @notice Library for CCIP internal definitions common to multiple contracts. +/// @dev The following is a non-exhaustive list of "known issues" for CCIP: +/// - We could implement yield claiming for Blast. This is not worth the custom code path on non-blast chains. +/// - uint32 is used for timestamps, which will overflow in 2106. This is not a concern for the current use case, as we +/// expect to have migrated to a new version by then. library Internal { error InvalidEVMAddress(bytes encodedAddress); - /// @dev The minimum amount of gas to perform the call with exact gas. - /// We include this in the offramp so that we can redeploy to adjust it should a hardfork change the gas costs of - /// relevant opcodes in callWithExactGas. - uint16 internal constant GAS_FOR_CALL_EXACT_CHECK = 5_000; /// @dev We limit return data to a selector plus 4 words. This is to avoid malicious contracts from returning /// large amounts of data and causing repeated out-of-gas scenarios. uint16 internal constant MAX_RET_BYTES = 4 + 4 * 32; @@ -40,8 +40,8 @@ library Internal { /// @notice A timestamped uint224 value that can contain several tightly packed fields. struct TimestampedPackedUint224 { - uint224 value; // ──────╮ Value in uint224, packed. - uint32 timestamp; // ───╯ Timestamp of the most recent price update. + uint224 value; // ────╮ Value in uint224, packed. + uint32 timestamp; // ─╯ Timestamp of the most recent price update. } /// @dev Gas price is stored in 112-bit unsigned int. uint224 can pack 2 prices. @@ -196,10 +196,10 @@ library Internal { /// The messageId is not expected to match hash(message), since it may originate from another ramp family. struct RampMessageHeader { bytes32 messageId; // Unique identifier for the message, generated with the source chain's encoding scheme (i.e. not necessarily abi.encoded). - uint64 sourceChainSelector; // ──╮ the chain selector of the source chain, note: not chainId. - uint64 destChainSelector; // │ the chain selector of the destination chain, note: not chainId. - uint64 sequenceNumber; // │ sequence number, not unique across lanes. - uint64 nonce; // ────────────────╯ nonce for this lane for this sender, not unique across senders/lanes. + uint64 sourceChainSelector; // ─╮ the chain selector of the source chain, note: not chainId. + uint64 destChainSelector; // │ the chain selector of the destination chain, note: not chainId. + uint64 sequenceNumber; // │ sequence number, not unique across lanes. + uint64 nonce; // ───────────────╯ nonce for this lane for this sender, not unique across senders/lanes. } struct EVM2AnyTokenTransfer { @@ -268,7 +268,7 @@ library Internal { // solhint-disable-next-line gas-struct-packing struct MerkleRoot { uint64 sourceChainSelector; // Remote source chain selector that the Merkle Root is scoped to - bytes onRampAddress; // Generic onramp address, to support arbitrary sources; for EVM, use abi.encode + bytes onRampAddress; // Generic onRamp address, to support arbitrary sources; for EVM, use abi.encode uint64 minSeqNr; // ─────────╮ Minimum sequence number, inclusive uint64 maxSeqNr; // ─────────╯ Maximum sequence number, inclusive bytes32 merkleRoot; // Merkle root covering the interval & source chain messages diff --git a/contracts/src/v0.8/ccip/offRamp/OffRamp.sol b/contracts/src/v0.8/ccip/offRamp/OffRamp.sol index d276ce26a96..76424b4e2a7 100644 --- a/contracts/src/v0.8/ccip/offRamp/OffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/OffRamp.sol @@ -92,8 +92,9 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. // solhint-disable-next-line gas-struct-packing struct StaticConfig { - uint64 chainSelector; // ────╮ Destination chainSelector - IRMNRemote rmnRemote; // ────╯ RMN Verification Contract + uint64 chainSelector; // ───────╮ Destination chainSelector + uint16 gasForCallExactCheck; // | Gas for call exact check + IRMNRemote rmnRemote; // ───────╯ RMN Verification Contract address tokenAdminRegistry; // Token admin registry address address nonceManager; // Nonce manager address } @@ -151,6 +152,10 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { address internal immutable i_tokenAdminRegistry; /// @dev The address of the nonce manager. address internal immutable i_nonceManager; + /// @dev The minimum amount of gas to perform the call with exact gas. + /// We include this in the offramp so that we can redeploy to adjust it should a hardfork change the gas costs of + /// relevant opcodes in callWithExactGas. + uint16 internal immutable i_gasForCallExactCheck; // DYNAMIC CONFIG DynamicConfig internal s_dynamicConfig; @@ -193,6 +198,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { i_rmnRemote = staticConfig.rmnRemote; i_tokenAdminRegistry = staticConfig.tokenAdminRegistry; i_nonceManager = staticConfig.nonceManager; + i_gasForCallExactCheck = staticConfig.gasForCallExactCheck; emit StaticConfigSet(staticConfig); _setDynamicConfig(dynamicConfig); @@ -356,6 +362,8 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { /// @param manualExecGasExecOverrides An array of gas limits to use for manual execution. /// @dev If called from the DON, this array is always empty. /// @dev If called from manual execution, this array is always same length as messages. + /// @dev This function can fully revert in some cases, reverting potentially valid other reports with it. The reasons + /// for these reverts are so severe that we prefer to revert the entire batch instead of silently failing. function _executeSingleReport( Internal.ExecutionReport memory report, GasLimitOverride[] memory manualExecGasExecOverrides @@ -577,6 +585,8 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { destTokenAmounts: destTokenAmounts }); + // The main message interceptor is the aggregate rate limiter, but we also allow for a custom interceptor. This is + // why we always have to call into the contract when it's enabled, even when there are no tokens in the message. address messageInterceptor = s_dynamicConfig.messageInterceptor; if (messageInterceptor != address(0)) { try IMessageInterceptor(messageInterceptor).onInboundMessage(any2EvmMessage) {} @@ -601,7 +611,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { (bool success, bytes memory returnData,) = s_sourceChainConfigs[message.header.sourceChainSelector] .router - .routeMessage(any2EvmMessage, Internal.GAS_FOR_CALL_EXACT_CHECK, message.gasLimit, message.receiver); + .routeMessage(any2EvmMessage, i_gasForCallExactCheck, message.gasLimit, message.receiver); // If CCIP receiver execution is not successful, revert the call including token transfers. if (!success) revert ReceiverError(returnData); } @@ -665,7 +675,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { ), localPoolAddress, gasLeft, - Internal.GAS_FOR_CALL_EXACT_CHECK, + i_gasForCallExactCheck, Internal.MAX_RET_BYTES ); @@ -705,11 +715,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { uint256 gasLimit ) internal returns (uint256 balance, uint256 gasLeft) { (bool success, bytes memory returnData, uint256 gasUsed) = CallWithExactGas._callWithExactGasSafeReturnData( - abi.encodeCall(IERC20.balanceOf, (receiver)), - token, - gasLimit, - Internal.GAS_FOR_CALL_EXACT_CHECK, - Internal.MAX_RET_BYTES + abi.encodeCall(IERC20.balanceOf, (receiver)), token, gasLimit, i_gasForCallExactCheck, Internal.MAX_RET_BYTES ); if (!success) revert TokenHandlingError(token, returnData); @@ -906,6 +912,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base { function getStaticConfig() external view returns (StaticConfig memory) { return StaticConfig({ chainSelector: i_chainSelector, + gasForCallExactCheck: i_gasForCallExactCheck, rmnRemote: i_rmnRemote, tokenAdminRegistry: i_tokenAdminRegistry, nonceManager: i_nonceManager diff --git a/contracts/src/v0.8/ccip/pools/TokenPool.sol b/contracts/src/v0.8/ccip/pools/TokenPool.sol index 69bab031f57..9d8e77a7928 100644 --- a/contracts/src/v0.8/ccip/pools/TokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/TokenPool.sol @@ -52,6 +52,7 @@ abstract contract TokenPool is IPoolV1, Ownable2StepMsgSender { error PoolAlreadyAdded(uint64 remoteChainSelector, bytes remotePoolAddress); error InvalidRemotePoolForChain(uint64 remoteChainSelector, bytes remotePoolAddress); error InvalidRemoteChainDecimals(bytes sourcePoolData); + error MismatchedArrayLengths(); error OverflowDetected(uint8 remoteDecimals, uint8 localDecimals, uint256 remoteAmount); error InvalidDecimalArgs(uint8 expected, uint8 actual); @@ -536,6 +537,25 @@ abstract contract TokenPool is IPoolV1, Ownable2StepMsgSender { return s_remoteChainConfigs[remoteChainSelector].inboundRateLimiterConfig._currentTokenBucketState(); } + /// @notice Sets multiple chain rate limiter configs. + /// @param remoteChainSelectors The remote chain selector for which the rate limits apply. + /// @param outboundConfigs The new outbound rate limiter config, meaning the onRamp rate limits for the given chain. + /// @param inboundConfigs The new inbound rate limiter config, meaning the offRamp rate limits for the given chain. + function setChainRateLimiterConfigs( + uint64[] calldata remoteChainSelectors, + RateLimiter.Config[] calldata outboundConfigs, + RateLimiter.Config[] calldata inboundConfigs + ) external { + if (msg.sender != s_rateLimitAdmin && msg.sender != owner()) revert Unauthorized(msg.sender); + if (remoteChainSelectors.length != outboundConfigs.length || remoteChainSelectors.length != inboundConfigs.length) { + revert MismatchedArrayLengths(); + } + + for (uint256 i = 0; i < remoteChainSelectors.length; ++i) { + _setRateLimitConfig(remoteChainSelectors[i], outboundConfigs[i], inboundConfigs[i]); + } + } + /// @notice Sets the chain rate limiter config. /// @param remoteChainSelector The remote chain selector for which the rate limits apply. /// @param outboundConfig The new outbound rate limiter config, meaning the onRamp rate limits for the given chain. diff --git a/contracts/src/v0.8/ccip/test/BaseTest.t.sol b/contracts/src/v0.8/ccip/test/BaseTest.t.sol index dfc9e4e1eb1..1e9fcdd2fa5 100644 --- a/contracts/src/v0.8/ccip/test/BaseTest.t.sol +++ b/contracts/src/v0.8/ccip/test/BaseTest.t.sol @@ -41,7 +41,7 @@ contract BaseTest is Test { // OffRamp uint32 internal constant MAX_DATA_SIZE = 30_000; uint16 internal constant MAX_TOKENS_LENGTH = 5; - uint16 internal constant GAS_FOR_CALL_EXACT_CHECK = 5000; + uint16 internal constant GAS_FOR_CALL_EXACT_CHECK = 5_000; uint32 internal constant MAX_GAS_LIMIT = 4_000_000; MockRMN internal s_mockRMN; diff --git a/contracts/src/v0.8/ccip/test/NonceManager.t.sol b/contracts/src/v0.8/ccip/test/NonceManager.t.sol deleted file mode 100644 index b5c3ee6bd99..00000000000 --- a/contracts/src/v0.8/ccip/test/NonceManager.t.sol +++ /dev/null @@ -1,568 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.24; - -import {IEVM2AnyOnRamp} from "../interfaces/IEVM2AnyOnRamp.sol"; - -import {NonceManager} from "../NonceManager.sol"; -import {Client} from "../libraries/Client.sol"; -import {Internal} from "../libraries/Internal.sol"; -import {OffRamp} from "../offRamp/OffRamp.sol"; -import {OnRamp} from "../onRamp/OnRamp.sol"; -import {BaseTest} from "./BaseTest.t.sol"; -import {EVM2EVMOffRampHelper} from "./helpers/EVM2EVMOffRampHelper.sol"; -import {OnRampHelper} from "./helpers/OnRampHelper.sol"; -import {OffRampSetup} from "./offRamp/OffRamp/OffRampSetup.t.sol"; -import {OnRampSetup} from "./onRamp/OnRamp/OnRampSetup.t.sol"; - -import {Test} from "forge-std/Test.sol"; - -contract NonceManager_typeAndVersion is Test { - NonceManager private s_nonceManager; - - function setUp() public { - s_nonceManager = new NonceManager(new address[](0)); - } - - function test_typeAndVersion() public view { - assertEq(s_nonceManager.typeAndVersion(), "NonceManager 1.6.0-dev"); - } -} - -contract NonceManager_NonceIncrementation is BaseTest { - NonceManager private s_nonceManager; - - function setUp() public override { - address[] memory authorizedCallers = new address[](1); - authorizedCallers[0] = address(this); - s_nonceManager = new NonceManager(authorizedCallers); - } - - function test_getIncrementedOutboundNonce_Success() public { - address sender = address(this); - - assertEq(s_nonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, sender), 0); - - uint64 outboundNonce = s_nonceManager.getIncrementedOutboundNonce(DEST_CHAIN_SELECTOR, sender); - assertEq(outboundNonce, 1); - } - - function test_incrementInboundNonce_Success() public { - address sender = address(this); - - s_nonceManager.incrementInboundNonce(SOURCE_CHAIN_SELECTOR, 1, abi.encode(sender)); - - assertEq(s_nonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR, abi.encode(sender)), 1); - } - - function test_incrementInboundNonce_Skip() public { - address sender = address(this); - uint64 expectedNonce = 2; - - vm.expectEmit(); - emit NonceManager.SkippedIncorrectNonce(SOURCE_CHAIN_SELECTOR, expectedNonce, abi.encode(sender)); - - s_nonceManager.incrementInboundNonce(SOURCE_CHAIN_SELECTOR, expectedNonce, abi.encode(sender)); - - assertEq(s_nonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR, abi.encode(sender)), 0); - } - - function test_incrementNoncesInboundAndOutbound_Success() public { - address sender = address(this); - - assertEq(s_nonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, sender), 0); - uint64 outboundNonce = s_nonceManager.getIncrementedOutboundNonce(DEST_CHAIN_SELECTOR, sender); - assertEq(outboundNonce, 1); - - // Inbound nonce unchanged - assertEq(s_nonceManager.getInboundNonce(DEST_CHAIN_SELECTOR, abi.encode(sender)), 0); - - s_nonceManager.incrementInboundNonce(DEST_CHAIN_SELECTOR, 1, abi.encode(sender)); - assertEq(s_nonceManager.getInboundNonce(DEST_CHAIN_SELECTOR, abi.encode(sender)), 1); - - // Outbound nonce unchanged - assertEq(s_nonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, sender), 1); - } -} - -contract NonceManager_applyPreviousRampsUpdates is OnRampSetup { - function test_SingleRampUpdate_success() public { - address prevOnRamp = makeAddr("prevOnRamp"); - address prevOffRamp = makeAddr("prevOffRamp"); - NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); - previousRamps[0] = NonceManager.PreviousRampsArgs({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - prevRamps: NonceManager.PreviousRamps(prevOnRamp, prevOffRamp), - overrideExistingRamps: false - }); - - vm.expectEmit(); - emit NonceManager.PreviousRampsUpdated(DEST_CHAIN_SELECTOR, previousRamps[0].prevRamps); - - s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); - - _assertPreviousRampsEqual(s_outboundNonceManager.getPreviousRamps(DEST_CHAIN_SELECTOR), previousRamps[0].prevRamps); - } - - function test_MultipleRampsUpdates_success() public { - address prevOnRamp1 = makeAddr("prevOnRamp1"); - address prevOnRamp2 = makeAddr("prevOnRamp2"); - address prevOffRamp1 = makeAddr("prevOffRamp1"); - address prevOffRamp2 = makeAddr("prevOffRamp2"); - NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](2); - previousRamps[0] = NonceManager.PreviousRampsArgs({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - prevRamps: NonceManager.PreviousRamps(prevOnRamp1, prevOffRamp1), - overrideExistingRamps: false - }); - previousRamps[1] = NonceManager.PreviousRampsArgs({ - remoteChainSelector: DEST_CHAIN_SELECTOR + 1, - prevRamps: NonceManager.PreviousRamps(prevOnRamp2, prevOffRamp2), - overrideExistingRamps: false - }); - - vm.expectEmit(); - emit NonceManager.PreviousRampsUpdated(DEST_CHAIN_SELECTOR, previousRamps[0].prevRamps); - vm.expectEmit(); - emit NonceManager.PreviousRampsUpdated(DEST_CHAIN_SELECTOR + 1, previousRamps[1].prevRamps); - - s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); - - _assertPreviousRampsEqual(s_outboundNonceManager.getPreviousRamps(DEST_CHAIN_SELECTOR), previousRamps[0].prevRamps); - _assertPreviousRampsEqual( - s_outboundNonceManager.getPreviousRamps(DEST_CHAIN_SELECTOR + 1), previousRamps[1].prevRamps - ); - } - - function test_PreviousRampAlreadySet_overrideAllowed_success() public { - NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); - address prevOffRamp = makeAddr("prevOffRamp"); - previousRamps[0] = NonceManager.PreviousRampsArgs({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - prevRamps: NonceManager.PreviousRamps(address(0), prevOffRamp), - overrideExistingRamps: true - }); - - s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); - - previousRamps[0] = NonceManager.PreviousRampsArgs({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - prevRamps: NonceManager.PreviousRamps(address(0), prevOffRamp), - overrideExistingRamps: true - }); - - s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); - } - - function test_ZeroInput_success() public { - vm.recordLogs(); - s_outboundNonceManager.applyPreviousRampsUpdates(new NonceManager.PreviousRampsArgs[](0)); - - assertEq(vm.getRecordedLogs().length, 0); - } - - function test_PreviousRampAlreadySetOnRamp_Revert() public { - NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); - address prevOnRamp = makeAddr("prevOnRamp"); - previousRamps[0] = NonceManager.PreviousRampsArgs({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - prevRamps: NonceManager.PreviousRamps(prevOnRamp, address(0)), - overrideExistingRamps: false - }); - - s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); - - previousRamps[0] = NonceManager.PreviousRampsArgs({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - prevRamps: NonceManager.PreviousRamps(prevOnRamp, address(0)), - overrideExistingRamps: false - }); - - vm.expectRevert(NonceManager.PreviousRampAlreadySet.selector); - s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); - } - - function test_PreviousRampAlreadySetOffRamp_Revert() public { - NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); - address prevOffRamp = makeAddr("prevOffRamp"); - previousRamps[0] = NonceManager.PreviousRampsArgs({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - prevRamps: NonceManager.PreviousRamps(address(0), prevOffRamp), - overrideExistingRamps: false - }); - - s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); - - previousRamps[0] = NonceManager.PreviousRampsArgs({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - prevRamps: NonceManager.PreviousRamps(address(0), prevOffRamp), - overrideExistingRamps: false - }); - - vm.expectRevert(NonceManager.PreviousRampAlreadySet.selector); - s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); - } - - function test_PreviousRampAlreadySetOnRampAndOffRamp_Revert() public { - NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); - address prevOnRamp = makeAddr("prevOnRamp"); - address prevOffRamp = makeAddr("prevOffRamp"); - previousRamps[0] = NonceManager.PreviousRampsArgs({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - prevRamps: NonceManager.PreviousRamps(prevOnRamp, prevOffRamp), - overrideExistingRamps: false - }); - - s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); - - previousRamps[0] = NonceManager.PreviousRampsArgs({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - prevRamps: NonceManager.PreviousRamps(prevOnRamp, prevOffRamp), - overrideExistingRamps: false - }); - - vm.expectRevert(NonceManager.PreviousRampAlreadySet.selector); - s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); - } - - function _assertPreviousRampsEqual( - NonceManager.PreviousRamps memory a, - NonceManager.PreviousRamps memory b - ) internal pure { - assertEq(a.prevOnRamp, b.prevOnRamp); - assertEq(a.prevOffRamp, b.prevOffRamp); - } -} - -contract NonceManager_OnRampUpgrade is OnRampSetup { - uint256 internal constant FEE_AMOUNT = 1234567890; - OnRampHelper internal s_prevOnRamp; - - function setUp() public virtual override { - super.setUp(); - - (s_prevOnRamp,) = _deployOnRamp( - SOURCE_CHAIN_SELECTOR, s_sourceRouter, address(s_outboundNonceManager), address(s_tokenAdminRegistry) - ); - - // Since the previous onRamp is not a 1.5 ramp it doesn't have the getSenderNonce function. We mock it to return 0 - vm.mockCall(address(s_prevOnRamp), abi.encodeWithSelector(IEVM2AnyOnRamp.getSenderNonce.selector), abi.encode(0)); - - NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); - previousRamps[0] = NonceManager.PreviousRampsArgs({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - prevRamps: NonceManager.PreviousRamps(address(s_prevOnRamp), address(0)), - overrideExistingRamps: false - }); - s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); - - (s_onRamp, s_metadataHash) = _deployOnRamp( - SOURCE_CHAIN_SELECTOR, s_sourceRouter, address(s_outboundNonceManager), address(s_tokenAdminRegistry) - ); - - vm.startPrank(address(s_sourceRouter)); - } - - function test_Upgrade_Success() public { - Client.EVM2AnyMessage memory message = _generateEmptyMessage(); - - vm.expectEmit(); - emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, 1, _messageToEvent(message, 1, 1, FEE_AMOUNT, OWNER)); - - s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); - } - - function test_UpgradeSenderNoncesReadsPreviousRamp_Success() public { - Client.EVM2AnyMessage memory message = _generateEmptyMessage(); - uint64 startNonce = s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER); - - for (uint64 i = 1; i < 4; ++i) { - s_prevOnRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); - - assertEq(startNonce + i, s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER)); - } - } - - function test_UpgradeNonceStartsAtV1Nonce_Success() public { - Client.EVM2AnyMessage memory message = _generateEmptyMessage(); - - uint64 startNonce = s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER); - - // send 1 message from previous onramp - s_prevOnRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); - - assertEq(startNonce + 1, s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER)); - - // new onramp nonce should start from 2, while sequence number start from 1 - vm.expectEmit(); - emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, 1, _messageToEvent(message, 1, startNonce + 2, FEE_AMOUNT, OWNER)); - s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); - - assertEq(startNonce + 2, s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER)); - - // after another send, nonce should be 3, and sequence number be 2 - vm.expectEmit(); - emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, 2, _messageToEvent(message, 2, startNonce + 3, FEE_AMOUNT, OWNER)); - s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); - - assertEq(startNonce + 3, s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER)); - } - - function test_UpgradeNonceNewSenderStartsAtZero_Success() public { - Client.EVM2AnyMessage memory message = _generateEmptyMessage(); - - // send 1 message from previous onramp from OWNER - s_prevOnRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); - - address newSender = address(1234567); - // new onramp nonce should start from 1 for new sender - vm.expectEmit(); - emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, 1, _messageToEvent(message, 1, 1, FEE_AMOUNT, newSender)); - - s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, newSender); - } -} - -contract NonceManager_OffRampUpgrade is OffRampSetup { - EVM2EVMOffRampHelper internal s_prevOffRamp; - - address internal constant SINGLE_LANE_ON_RAMP_ADDRESS_1 = abi.decode(ON_RAMP_ADDRESS_1, (address)); - address internal constant SINGLE_LANE_ON_RAMP_ADDRESS_2 = abi.decode(ON_RAMP_ADDRESS_2, (address)); - address internal constant SINGLE_LANE_ON_RAMP_ADDRESS_3 = abi.decode(ON_RAMP_ADDRESS_3, (address)); - - function setUp() public virtual override { - super.setUp(); - - s_prevOffRamp = new EVM2EVMOffRampHelper(); - - NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); - previousRamps[0] = NonceManager.PreviousRampsArgs({ - remoteChainSelector: SOURCE_CHAIN_SELECTOR_1, - prevRamps: NonceManager.PreviousRamps(address(0), address(s_prevOffRamp)), - overrideExistingRamps: false - }); - - s_inboundNonceManager.applyPreviousRampsUpdates(previousRamps); - - OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](3); - sourceChainConfigs[0] = OffRamp.SourceChainConfigArgs({ - router: s_destRouter, - sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, - isEnabled: true, - onRamp: ON_RAMP_ADDRESS_1 - }); - sourceChainConfigs[1] = OffRamp.SourceChainConfigArgs({ - router: s_destRouter, - sourceChainSelector: SOURCE_CHAIN_SELECTOR_2, - isEnabled: true, - onRamp: ON_RAMP_ADDRESS_2 - }); - sourceChainConfigs[2] = OffRamp.SourceChainConfigArgs({ - router: s_destRouter, - sourceChainSelector: SOURCE_CHAIN_SELECTOR_3, - isEnabled: true, - onRamp: ON_RAMP_ADDRESS_3 - }); - - _setupMultipleOffRampsFromConfigs(sourceChainConfigs); - - s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_1, 1); - s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_3, 1); - } - - function test_Upgraded_Success() public { - Internal.Any2EVMRampMessage[] memory messages = - _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); - - vm.recordLogs(); - s_offRamp.executeSingleReport( - _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new OffRamp.GasLimitOverride[](0) - ); - _assertExecutionStateChangedEventLogs( - SOURCE_CHAIN_SELECTOR_1, - messages[0].header.sequenceNumber, - messages[0].header.messageId, - _hashMessage(messages[0], ON_RAMP_ADDRESS_1), - Internal.MessageExecutionState.SUCCESS, - "" - ); - } - - function test_NoPrevOffRampForChain_Success() public { - address[] memory senders = new address[](1); - senders[0] = OWNER; - - uint64 startNonceChain3 = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_3, abi.encode(senders[0])); - s_prevOffRamp.execute(senders); - - // Nonce unchanged for chain 3 - assertEq(startNonceChain3, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_3, abi.encode(senders[0]))); - - Internal.Any2EVMRampMessage[] memory messagesChain3 = - _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_3, ON_RAMP_ADDRESS_3); - - vm.recordLogs(); - - s_offRamp.executeSingleReport( - _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_3, messagesChain3), new OffRamp.GasLimitOverride[](0) - ); - _assertExecutionStateChangedEventLogs( - SOURCE_CHAIN_SELECTOR_3, - messagesChain3[0].header.sequenceNumber, - messagesChain3[0].header.messageId, - _hashMessage(messagesChain3[0], ON_RAMP_ADDRESS_3), - Internal.MessageExecutionState.SUCCESS, - "" - ); - - assertEq( - startNonceChain3 + 1, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_3, messagesChain3[0].sender) - ); - } - - function test_UpgradedSenderNoncesReadsPreviousRamp_Success() public { - address[] memory senders = new address[](1); - senders[0] = OWNER; - - uint64 startNonce = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(senders[0])); - - for (uint64 i = 1; i < 4; ++i) { - s_prevOffRamp.execute(senders); - - assertEq(startNonce + i, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(senders[0]))); - } - } - - function test_UpgradedNonceStartsAtV1Nonce_Success() public { - address[] memory senders = new address[](1); - senders[0] = OWNER; - - uint64 startNonce = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(senders[0])); - s_prevOffRamp.execute(senders); - - assertEq(startNonce + 1, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(senders[0]))); - - Internal.Any2EVMRampMessage[] memory messagesMultiRamp = - _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); - - messagesMultiRamp[0].header.nonce++; - messagesMultiRamp[0].header.messageId = _hashMessage(messagesMultiRamp[0], ON_RAMP_ADDRESS_1); - - vm.recordLogs(); - - s_offRamp.executeSingleReport( - _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp), new OffRamp.GasLimitOverride[](0) - ); - - _assertExecutionStateChangedEventLogs( - SOURCE_CHAIN_SELECTOR_1, - messagesMultiRamp[0].header.sequenceNumber, - messagesMultiRamp[0].header.messageId, - _hashMessage(messagesMultiRamp[0], ON_RAMP_ADDRESS_1), - Internal.MessageExecutionState.SUCCESS, - "" - ); - - assertEq( - startNonce + 2, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp[0].sender) - ); - - messagesMultiRamp[0].header.nonce++; - messagesMultiRamp[0].header.sequenceNumber++; - messagesMultiRamp[0].header.messageId = _hashMessage(messagesMultiRamp[0], ON_RAMP_ADDRESS_1); - - vm.recordLogs(); - s_offRamp.executeSingleReport( - _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp), new OffRamp.GasLimitOverride[](0) - ); - _assertExecutionStateChangedEventLogs( - SOURCE_CHAIN_SELECTOR_1, - messagesMultiRamp[0].header.sequenceNumber, - messagesMultiRamp[0].header.messageId, - _hashMessage(messagesMultiRamp[0], ON_RAMP_ADDRESS_1), - Internal.MessageExecutionState.SUCCESS, - "" - ); - - assertEq( - startNonce + 3, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp[0].sender) - ); - } - - function test_UpgradedNonceNewSenderStartsAtZero_Success() public { - address[] memory senders = new address[](1); - senders[0] = OWNER; - - s_prevOffRamp.execute(senders); - - Internal.Any2EVMRampMessage[] memory messagesMultiRamp = - _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); - - bytes memory newSender = abi.encode(address(1234567)); - messagesMultiRamp[0].sender = newSender; - messagesMultiRamp[0].header.messageId = _hashMessage(messagesMultiRamp[0], ON_RAMP_ADDRESS_1); - - // new sender nonce in new offramp should go from 0 -> 1 - assertEq(s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, newSender), 0); - vm.recordLogs(); - s_offRamp.executeSingleReport( - _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp), new OffRamp.GasLimitOverride[](0) - ); - _assertExecutionStateChangedEventLogs( - SOURCE_CHAIN_SELECTOR_1, - messagesMultiRamp[0].header.sequenceNumber, - messagesMultiRamp[0].header.messageId, - _hashMessage(messagesMultiRamp[0], ON_RAMP_ADDRESS_1), - Internal.MessageExecutionState.SUCCESS, - "" - ); - assertEq(s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, newSender), 1); - } - - function test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() public { - Internal.Any2EVMRampMessage[] memory messages = - _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); - - address newSender = address(1234567); - messages[0].sender = abi.encode(newSender); - messages[0].header.nonce = 2; - messages[0].header.messageId = _hashMessage(messages[0], ON_RAMP_ADDRESS_1); - - uint64 startNonce = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender); - - // new offramp sees msg nonce higher than senderNonce - // it waits for previous offramp to execute - vm.expectEmit(); - emit NonceManager.SkippedIncorrectNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].header.nonce, messages[0].sender); - s_offRamp.executeSingleReport( - _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new OffRamp.GasLimitOverride[](0) - ); - assertEq(startNonce, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender)); - - address[] memory senders = new address[](1); - senders[0] = newSender; - - // previous offramp executes msg and increases nonce - s_prevOffRamp.execute(senders); - assertEq(startNonce + 1, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(senders[0]))); - - messages[0].header.nonce = 2; - messages[0].header.messageId = _hashMessage(messages[0], ON_RAMP_ADDRESS_1); - - // new offramp is able to execute - vm.recordLogs(); - s_offRamp.executeSingleReport( - _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new OffRamp.GasLimitOverride[](0) - ); - - _assertExecutionStateChangedEventLogs( - SOURCE_CHAIN_SELECTOR_1, - messages[0].header.sequenceNumber, - messages[0].header.messageId, - _hashMessage(messages[0], ON_RAMP_ADDRESS_1), - Internal.MessageExecutionState.SUCCESS, - "" - ); - - assertEq(startNonce + 2, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender)); - } -} diff --git a/contracts/src/v0.8/ccip/test/NonceManager/NonceManager.applyPreviousRampsUpdates.t.sol b/contracts/src/v0.8/ccip/test/NonceManager/NonceManager.applyPreviousRampsUpdates.t.sol new file mode 100644 index 00000000000..fe4316423ec --- /dev/null +++ b/contracts/src/v0.8/ccip/test/NonceManager/NonceManager.applyPreviousRampsUpdates.t.sol @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {NonceManager} from "../../NonceManager.sol"; +import {OnRampSetup} from "../onRamp/OnRamp/OnRampSetup.t.sol"; + +contract NonceManager_applyPreviousRampsUpdates is OnRampSetup { + function test_SingleRampUpdate_success() public { + address prevOnRamp = makeAddr("prevOnRamp"); + address prevOffRamp = makeAddr("prevOffRamp"); + NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); + previousRamps[0] = NonceManager.PreviousRampsArgs({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + prevRamps: NonceManager.PreviousRamps(prevOnRamp, prevOffRamp), + overrideExistingRamps: false + }); + + vm.expectEmit(); + emit NonceManager.PreviousRampsUpdated(DEST_CHAIN_SELECTOR, previousRamps[0].prevRamps); + + s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); + + _assertPreviousRampsEqual(s_outboundNonceManager.getPreviousRamps(DEST_CHAIN_SELECTOR), previousRamps[0].prevRamps); + } + + function test_MultipleRampsUpdates() public { + address prevOnRamp1 = makeAddr("prevOnRamp1"); + address prevOnRamp2 = makeAddr("prevOnRamp2"); + address prevOffRamp1 = makeAddr("prevOffRamp1"); + address prevOffRamp2 = makeAddr("prevOffRamp2"); + NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](2); + previousRamps[0] = NonceManager.PreviousRampsArgs({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + prevRamps: NonceManager.PreviousRamps(prevOnRamp1, prevOffRamp1), + overrideExistingRamps: false + }); + previousRamps[1] = NonceManager.PreviousRampsArgs({ + remoteChainSelector: DEST_CHAIN_SELECTOR + 1, + prevRamps: NonceManager.PreviousRamps(prevOnRamp2, prevOffRamp2), + overrideExistingRamps: false + }); + + vm.expectEmit(); + emit NonceManager.PreviousRampsUpdated(DEST_CHAIN_SELECTOR, previousRamps[0].prevRamps); + vm.expectEmit(); + emit NonceManager.PreviousRampsUpdated(DEST_CHAIN_SELECTOR + 1, previousRamps[1].prevRamps); + + s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); + + _assertPreviousRampsEqual(s_outboundNonceManager.getPreviousRamps(DEST_CHAIN_SELECTOR), previousRamps[0].prevRamps); + _assertPreviousRampsEqual( + s_outboundNonceManager.getPreviousRamps(DEST_CHAIN_SELECTOR + 1), previousRamps[1].prevRamps + ); + } + + function test_PreviousRampAlreadySet_overrideAllowed() public { + NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); + address prevOffRamp = makeAddr("prevOffRamp"); + previousRamps[0] = NonceManager.PreviousRampsArgs({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + prevRamps: NonceManager.PreviousRamps(address(0), prevOffRamp), + overrideExistingRamps: true + }); + + s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); + + previousRamps[0] = NonceManager.PreviousRampsArgs({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + prevRamps: NonceManager.PreviousRamps(address(0), prevOffRamp), + overrideExistingRamps: true + }); + + s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); + } + + function test_ZeroInput() public { + vm.recordLogs(); + s_outboundNonceManager.applyPreviousRampsUpdates(new NonceManager.PreviousRampsArgs[](0)); + + assertEq(vm.getRecordedLogs().length, 0); + } + + function test_applyPreviousRampsUpdates_RevertWhen_PreviousRampAlreadySetOnRamp() public { + NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); + address prevOnRamp = makeAddr("prevOnRamp"); + previousRamps[0] = NonceManager.PreviousRampsArgs({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + prevRamps: NonceManager.PreviousRamps(prevOnRamp, address(0)), + overrideExistingRamps: false + }); + + s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); + + previousRamps[0] = NonceManager.PreviousRampsArgs({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + prevRamps: NonceManager.PreviousRamps(prevOnRamp, address(0)), + overrideExistingRamps: false + }); + + vm.expectRevert(NonceManager.PreviousRampAlreadySet.selector); + s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); + } + + function test_applyPreviousRampsUpdates_RevertWhen_PreviousRampAlreadySetOffRamp() public { + NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); + address prevOffRamp = makeAddr("prevOffRamp"); + previousRamps[0] = NonceManager.PreviousRampsArgs({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + prevRamps: NonceManager.PreviousRamps(address(0), prevOffRamp), + overrideExistingRamps: false + }); + + s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); + + previousRamps[0] = NonceManager.PreviousRampsArgs({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + prevRamps: NonceManager.PreviousRamps(address(0), prevOffRamp), + overrideExistingRamps: false + }); + + vm.expectRevert(NonceManager.PreviousRampAlreadySet.selector); + s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); + } + + function test_applyPreviousRampsUpdates_RevertWhen_PreviousRampAlreadySetOnRampAndOffRamp_Revert() public { + NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); + address prevOnRamp = makeAddr("prevOnRamp"); + address prevOffRamp = makeAddr("prevOffRamp"); + previousRamps[0] = NonceManager.PreviousRampsArgs({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + prevRamps: NonceManager.PreviousRamps(prevOnRamp, prevOffRamp), + overrideExistingRamps: false + }); + + s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); + + previousRamps[0] = NonceManager.PreviousRampsArgs({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + prevRamps: NonceManager.PreviousRamps(prevOnRamp, prevOffRamp), + overrideExistingRamps: false + }); + + vm.expectRevert(NonceManager.PreviousRampAlreadySet.selector); + s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); + } + + function _assertPreviousRampsEqual( + NonceManager.PreviousRamps memory a, + NonceManager.PreviousRamps memory b + ) internal pure { + assertEq(a.prevOnRamp, b.prevOnRamp); + assertEq(a.prevOffRamp, b.prevOffRamp); + } +} diff --git a/contracts/src/v0.8/ccip/test/NonceManager/NonceManager.getInboundNonce.t.sol b/contracts/src/v0.8/ccip/test/NonceManager/NonceManager.getInboundNonce.t.sol new file mode 100644 index 00000000000..4078c3c0d01 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/NonceManager/NonceManager.getInboundNonce.t.sol @@ -0,0 +1,253 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {NonceManager} from "../../NonceManager.sol"; +import {Internal} from "../../libraries/Internal.sol"; +import {OffRamp} from "../../offRamp/OffRamp.sol"; +import {EVM2EVMOffRampHelper} from "../helpers/EVM2EVMOffRampHelper.sol"; +import {OffRampSetup} from "../offRamp/OffRamp/OffRampSetup.t.sol"; + +contract NonceManager_getInboundNonce is OffRampSetup { + EVM2EVMOffRampHelper internal s_prevOffRamp; + + address internal constant SINGLE_LANE_ON_RAMP_ADDRESS_1 = abi.decode(ON_RAMP_ADDRESS_1, (address)); + address internal constant SINGLE_LANE_ON_RAMP_ADDRESS_2 = abi.decode(ON_RAMP_ADDRESS_2, (address)); + address internal constant SINGLE_LANE_ON_RAMP_ADDRESS_3 = abi.decode(ON_RAMP_ADDRESS_3, (address)); + + function setUp() public virtual override { + super.setUp(); + + s_prevOffRamp = new EVM2EVMOffRampHelper(); + + NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); + previousRamps[0] = NonceManager.PreviousRampsArgs({ + remoteChainSelector: SOURCE_CHAIN_SELECTOR_1, + prevRamps: NonceManager.PreviousRamps(address(0), address(s_prevOffRamp)), + overrideExistingRamps: false + }); + + s_inboundNonceManager.applyPreviousRampsUpdates(previousRamps); + + OffRamp.SourceChainConfigArgs[] memory sourceChainConfigs = new OffRamp.SourceChainConfigArgs[](3); + sourceChainConfigs[0] = OffRamp.SourceChainConfigArgs({ + router: s_destRouter, + sourceChainSelector: SOURCE_CHAIN_SELECTOR_1, + isEnabled: true, + onRamp: ON_RAMP_ADDRESS_1 + }); + sourceChainConfigs[1] = OffRamp.SourceChainConfigArgs({ + router: s_destRouter, + sourceChainSelector: SOURCE_CHAIN_SELECTOR_2, + isEnabled: true, + onRamp: ON_RAMP_ADDRESS_2 + }); + sourceChainConfigs[2] = OffRamp.SourceChainConfigArgs({ + router: s_destRouter, + sourceChainSelector: SOURCE_CHAIN_SELECTOR_3, + isEnabled: true, + onRamp: ON_RAMP_ADDRESS_3 + }); + + _setupMultipleOffRampsFromConfigs(sourceChainConfigs); + + s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_1, 1); + s_offRamp.setVerifyOverrideResult(SOURCE_CHAIN_SELECTOR_3, 1); + } + + function test_getInboundNonce_Upgraded() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + + vm.recordLogs(); + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new OffRamp.GasLimitOverride[](0) + ); + _assertExecutionStateChangedEventLogs( + SOURCE_CHAIN_SELECTOR_1, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + _hashMessage(messages[0], ON_RAMP_ADDRESS_1), + Internal.MessageExecutionState.SUCCESS, + "" + ); + } + + function test_getInboundNonce_NoPrevOffRampForChain() public { + address[] memory senders = new address[](1); + senders[0] = OWNER; + + uint64 startNonceChain3 = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_3, abi.encode(senders[0])); + s_prevOffRamp.execute(senders); + + // Nonce unchanged for chain 3 + assertEq(startNonceChain3, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_3, abi.encode(senders[0]))); + + Internal.Any2EVMRampMessage[] memory messagesChain3 = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_3, ON_RAMP_ADDRESS_3); + + vm.recordLogs(); + + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_3, messagesChain3), new OffRamp.GasLimitOverride[](0) + ); + _assertExecutionStateChangedEventLogs( + SOURCE_CHAIN_SELECTOR_3, + messagesChain3[0].header.sequenceNumber, + messagesChain3[0].header.messageId, + _hashMessage(messagesChain3[0], ON_RAMP_ADDRESS_3), + Internal.MessageExecutionState.SUCCESS, + "" + ); + + assertEq( + startNonceChain3 + 1, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_3, messagesChain3[0].sender) + ); + } + + function test_getInboundNonce_UpgradedSenderNoncesReadsPreviousRamp() public { + address[] memory senders = new address[](1); + senders[0] = OWNER; + + uint64 startNonce = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(senders[0])); + + for (uint64 i = 1; i < 4; ++i) { + s_prevOffRamp.execute(senders); + + assertEq(startNonce + i, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(senders[0]))); + } + } + + function test_getInboundNonce_UpgradedNonceStartsAtV1Nonce() public { + address[] memory senders = new address[](1); + senders[0] = OWNER; + + uint64 startNonce = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(senders[0])); + s_prevOffRamp.execute(senders); + + assertEq(startNonce + 1, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(senders[0]))); + + Internal.Any2EVMRampMessage[] memory messagesMultiRamp = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + + messagesMultiRamp[0].header.nonce++; + messagesMultiRamp[0].header.messageId = _hashMessage(messagesMultiRamp[0], ON_RAMP_ADDRESS_1); + + vm.recordLogs(); + + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp), new OffRamp.GasLimitOverride[](0) + ); + + _assertExecutionStateChangedEventLogs( + SOURCE_CHAIN_SELECTOR_1, + messagesMultiRamp[0].header.sequenceNumber, + messagesMultiRamp[0].header.messageId, + _hashMessage(messagesMultiRamp[0], ON_RAMP_ADDRESS_1), + Internal.MessageExecutionState.SUCCESS, + "" + ); + + assertEq( + startNonce + 2, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp[0].sender) + ); + + messagesMultiRamp[0].header.nonce++; + messagesMultiRamp[0].header.sequenceNumber++; + messagesMultiRamp[0].header.messageId = _hashMessage(messagesMultiRamp[0], ON_RAMP_ADDRESS_1); + + vm.recordLogs(); + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp), new OffRamp.GasLimitOverride[](0) + ); + _assertExecutionStateChangedEventLogs( + SOURCE_CHAIN_SELECTOR_1, + messagesMultiRamp[0].header.sequenceNumber, + messagesMultiRamp[0].header.messageId, + _hashMessage(messagesMultiRamp[0], ON_RAMP_ADDRESS_1), + Internal.MessageExecutionState.SUCCESS, + "" + ); + + assertEq( + startNonce + 3, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp[0].sender) + ); + } + + function test_getInboundNonce_UpgradedNonceNewSenderStartsAtZero() public { + address[] memory senders = new address[](1); + senders[0] = OWNER; + + s_prevOffRamp.execute(senders); + + Internal.Any2EVMRampMessage[] memory messagesMultiRamp = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + + bytes memory newSender = abi.encode(address(1234567)); + messagesMultiRamp[0].sender = newSender; + messagesMultiRamp[0].header.messageId = _hashMessage(messagesMultiRamp[0], ON_RAMP_ADDRESS_1); + + // new sender nonce in new offRamp should go from 0 -> 1 + assertEq(s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, newSender), 0); + vm.recordLogs(); + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messagesMultiRamp), new OffRamp.GasLimitOverride[](0) + ); + _assertExecutionStateChangedEventLogs( + SOURCE_CHAIN_SELECTOR_1, + messagesMultiRamp[0].header.sequenceNumber, + messagesMultiRamp[0].header.messageId, + _hashMessage(messagesMultiRamp[0], ON_RAMP_ADDRESS_1), + Internal.MessageExecutionState.SUCCESS, + "" + ); + assertEq(s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, newSender), 1); + } + + function test_getInboundNonce_UpgradedOffRampNonceSkipsIfMsgInFlight() public { + Internal.Any2EVMRampMessage[] memory messages = + _generateSingleBasicMessage(SOURCE_CHAIN_SELECTOR_1, ON_RAMP_ADDRESS_1); + + address newSender = address(1234567); + messages[0].sender = abi.encode(newSender); + messages[0].header.nonce = 2; + messages[0].header.messageId = _hashMessage(messages[0], ON_RAMP_ADDRESS_1); + + uint64 startNonce = s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender); + + // new offRamp sees msg nonce higher than senderNonce + // it waits for previous offRamp to execute + vm.expectEmit(); + emit NonceManager.SkippedIncorrectNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].header.nonce, messages[0].sender); + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new OffRamp.GasLimitOverride[](0) + ); + assertEq(startNonce, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender)); + + address[] memory senders = new address[](1); + senders[0] = newSender; + + // previous offRamp executes msg and increases nonce + s_prevOffRamp.execute(senders); + assertEq(startNonce + 1, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, abi.encode(senders[0]))); + + messages[0].header.nonce = 2; + messages[0].header.messageId = _hashMessage(messages[0], ON_RAMP_ADDRESS_1); + + // new offRamp is able to execute + vm.recordLogs(); + s_offRamp.executeSingleReport( + _generateReportFromMessages(SOURCE_CHAIN_SELECTOR_1, messages), new OffRamp.GasLimitOverride[](0) + ); + + _assertExecutionStateChangedEventLogs( + SOURCE_CHAIN_SELECTOR_1, + messages[0].header.sequenceNumber, + messages[0].header.messageId, + _hashMessage(messages[0], ON_RAMP_ADDRESS_1), + Internal.MessageExecutionState.SUCCESS, + "" + ); + + assertEq(startNonce + 2, s_inboundNonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR_1, messages[0].sender)); + } +} diff --git a/contracts/src/v0.8/ccip/test/NonceManager/NonceManager.getIncrementedOutboundNonce.t.sol b/contracts/src/v0.8/ccip/test/NonceManager/NonceManager.getIncrementedOutboundNonce.t.sol new file mode 100644 index 00000000000..1ac25d6c31f --- /dev/null +++ b/contracts/src/v0.8/ccip/test/NonceManager/NonceManager.getIncrementedOutboundNonce.t.sol @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {NonceManager} from "../../NonceManager.sol"; +import {BaseTest} from "../BaseTest.t.sol"; + +contract NonceManager_getIncrementedOutboundNonce is BaseTest { + NonceManager private s_nonceManager; + + function setUp() public override { + address[] memory authorizedCallers = new address[](1); + authorizedCallers[0] = address(this); + s_nonceManager = new NonceManager(authorizedCallers); + } + + function test_getIncrementedOutboundNonce() public { + address sender = address(this); + + assertEq(s_nonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, sender), 0); + + uint64 outboundNonce = s_nonceManager.getIncrementedOutboundNonce(DEST_CHAIN_SELECTOR, sender); + assertEq(outboundNonce, 1); + } + + function test_incrementInboundNonce() public { + address sender = address(this); + + s_nonceManager.incrementInboundNonce(SOURCE_CHAIN_SELECTOR, 1, abi.encode(sender)); + + assertEq(s_nonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR, abi.encode(sender)), 1); + } + + function test_incrementInboundNonce_SkippedIncorrectNonce() public { + address sender = address(this); + uint64 expectedNonce = 2; + + vm.expectEmit(); + emit NonceManager.SkippedIncorrectNonce(SOURCE_CHAIN_SELECTOR, expectedNonce, abi.encode(sender)); + + s_nonceManager.incrementInboundNonce(SOURCE_CHAIN_SELECTOR, expectedNonce, abi.encode(sender)); + + assertEq(s_nonceManager.getInboundNonce(SOURCE_CHAIN_SELECTOR, abi.encode(sender)), 0); + } + + function test_incrementNoncesInboundAndOutbound() public { + address sender = address(this); + + assertEq(s_nonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, sender), 0); + uint64 outboundNonce = s_nonceManager.getIncrementedOutboundNonce(DEST_CHAIN_SELECTOR, sender); + assertEq(outboundNonce, 1); + + // Inbound nonce unchanged + assertEq(s_nonceManager.getInboundNonce(DEST_CHAIN_SELECTOR, abi.encode(sender)), 0); + + s_nonceManager.incrementInboundNonce(DEST_CHAIN_SELECTOR, 1, abi.encode(sender)); + assertEq(s_nonceManager.getInboundNonce(DEST_CHAIN_SELECTOR, abi.encode(sender)), 1); + + // Outbound nonce unchanged + assertEq(s_nonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, sender), 1); + } +} diff --git a/contracts/src/v0.8/ccip/test/NonceManager/NonceManager.getOutboundNonce.t.sol b/contracts/src/v0.8/ccip/test/NonceManager/NonceManager.getOutboundNonce.t.sol new file mode 100644 index 00000000000..2fe02bfb59d --- /dev/null +++ b/contracts/src/v0.8/ccip/test/NonceManager/NonceManager.getOutboundNonce.t.sol @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IEVM2AnyOnRamp} from "../../interfaces/IEVM2AnyOnRamp.sol"; + +import {NonceManager} from "../../NonceManager.sol"; +import {Client} from "../../libraries/Client.sol"; +import {OnRamp} from "../../onRamp/OnRamp.sol"; +import {OnRampHelper} from "../helpers/OnRampHelper.sol"; +import {OnRampSetup} from "../onRamp/OnRamp/OnRampSetup.t.sol"; + +contract NonceManager_getOutboundNonce is OnRampSetup { + uint256 internal constant FEE_AMOUNT = 1234567890; + OnRampHelper internal s_prevOnRamp; + + function setUp() public virtual override { + super.setUp(); + + (s_prevOnRamp,) = _deployOnRamp( + SOURCE_CHAIN_SELECTOR, s_sourceRouter, address(s_outboundNonceManager), address(s_tokenAdminRegistry) + ); + + // Since the previous onRamp is not a 1.5 ramp it doesn't have the getSenderNonce function. We mock it to return 0 + vm.mockCall(address(s_prevOnRamp), abi.encodeWithSelector(IEVM2AnyOnRamp.getSenderNonce.selector), abi.encode(0)); + + NonceManager.PreviousRampsArgs[] memory previousRamps = new NonceManager.PreviousRampsArgs[](1); + previousRamps[0] = NonceManager.PreviousRampsArgs({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + prevRamps: NonceManager.PreviousRamps(address(s_prevOnRamp), address(0)), + overrideExistingRamps: false + }); + s_outboundNonceManager.applyPreviousRampsUpdates(previousRamps); + + (s_onRamp, s_metadataHash) = _deployOnRamp( + SOURCE_CHAIN_SELECTOR, s_sourceRouter, address(s_outboundNonceManager), address(s_tokenAdminRegistry) + ); + + vm.startPrank(address(s_sourceRouter)); + } + + function test_getOutboundNonce_Upgrade() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + vm.expectEmit(); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, 1, _messageToEvent(message, 1, 1, FEE_AMOUNT, OWNER)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); + } + + function test_getOutboundNonce_UpgradeSenderNoncesReadsPreviousRamp() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + uint64 startNonce = s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER); + uint64 prevRampNextOutboundNonce = IEVM2AnyOnRamp(address(s_prevOnRamp)).getSenderNonce(OWNER); + + assertEq(startNonce, prevRampNextOutboundNonce); + + for (uint64 i = 1; i < 4; ++i) { + s_prevOnRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, 0, OWNER); + + assertEq(startNonce + i, s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER)); + } + } + + function test_getOutboundNonce_UpgradeNonceStartsAtV1Nonce() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + uint64 startNonce = s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER); + + // send 1 message from previous onRamp + s_prevOnRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); + + assertEq(startNonce + 1, s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER)); + + // new onRamp nonce should start from 2, while sequence number start from 1 + vm.expectEmit(); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, 1, _messageToEvent(message, 1, startNonce + 2, FEE_AMOUNT, OWNER)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); + + assertEq(startNonce + 2, s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER)); + + // after another send, nonce should be 3, and sequence number be 2 + vm.expectEmit(); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, 2, _messageToEvent(message, 2, startNonce + 3, FEE_AMOUNT, OWNER)); + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); + + assertEq(startNonce + 3, s_outboundNonceManager.getOutboundNonce(DEST_CHAIN_SELECTOR, OWNER)); + } + + function test_getOutboundNonce_UpgradeNonceNewSenderStartsAtZero() public { + Client.EVM2AnyMessage memory message = _generateEmptyMessage(); + + // send 1 message from previous onRamp from OWNER + s_prevOnRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, OWNER); + + address newSender = address(1234567); + // new onRamp nonce should start from 1 for new sender + vm.expectEmit(); + emit OnRamp.CCIPMessageSent(DEST_CHAIN_SELECTOR, 1, _messageToEvent(message, 1, 1, FEE_AMOUNT, newSender)); + + s_onRamp.forwardFromRouter(DEST_CHAIN_SELECTOR, message, FEE_AMOUNT, newSender); + } +} diff --git a/contracts/src/v0.8/ccip/test/capability/CCIPHome/CCIPHome.applyChainConfigUpdates.t.sol b/contracts/src/v0.8/ccip/test/capability/CCIPHome/CCIPHome.applyChainConfigUpdates.t.sol index 1d2c3a70895..9bf096b9551 100644 --- a/contracts/src/v0.8/ccip/test/capability/CCIPHome/CCIPHome.applyChainConfigUpdates.t.sol +++ b/contracts/src/v0.8/ccip/test/capability/CCIPHome/CCIPHome.applyChainConfigUpdates.t.sol @@ -109,6 +109,7 @@ contract CCIPHome_applyChainConfigUpdates is CCIPHomeTestSetup { function test_applyChainConfigUpdates_removeChainConfigs_Success() public { bytes32[] memory chainReaders = new bytes32[](1); chainReaders[0] = keccak256(abi.encode(1)); + CCIPHome.ChainConfigArgs[] memory adds = new CCIPHome.ChainConfigArgs[](2); adds[0] = CCIPHome.ChainConfigArgs({ chainSelector: 1, @@ -130,6 +131,7 @@ contract CCIPHome_applyChainConfigUpdates is CCIPHomeTestSetup { workflowDONId: uint32(1), capabilitiesDONIds: new uint256[](0) }); + vm.mockCall( CAPABILITIES_REGISTRY, abi.encodeWithSelector(INodeInfoProvider.getNodesByP2PIds.selector, chainReaders), @@ -140,10 +142,14 @@ contract CCIPHome_applyChainConfigUpdates is CCIPHomeTestSetup { emit CCIPHome.ChainConfigSet(1, adds[0].chainConfig); vm.expectEmit(); emit CCIPHome.ChainConfigSet(2, adds[1].chainConfig); + s_ccipHome.applyChainConfigUpdates(new uint64[](0), adds); assertEq(s_ccipHome.getNumChainConfigurations(), 2, "total chain configs must be 2"); + assertEq(s_ccipHome.getChainConfig(adds[0].chainSelector).config, adds[0].chainConfig.config); + assertEq(s_ccipHome.getChainConfig(adds[1].chainSelector).config, adds[1].chainConfig.config); + uint64[] memory removes = new uint64[](1); removes[0] = uint64(1); diff --git a/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.afterOC3ConfigSet.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.afterOC3ConfigSet.t.sol index 91694dbcb05..d2edb7a261a 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.afterOC3ConfigSet.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.afterOC3ConfigSet.t.sol @@ -12,6 +12,7 @@ contract OffRamp_afterOC3ConfigSet is OffRampSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, + gasForCallExactCheck: GAS_FOR_CALL_EXACT_CHECK, rmnRemote: s_mockRMNRemote, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) diff --git a/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.constructor.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.constructor.t.sol index bd7bb94344c..d31b7939d9c 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.constructor.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.constructor.t.sol @@ -13,6 +13,7 @@ contract OffRamp_constructor is OffRampSetup { function test_Constructor_Success() public { OffRamp.StaticConfig memory staticConfig = OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, + gasForCallExactCheck: GAS_FOR_CALL_EXACT_CHECK, rmnRemote: s_mockRMNRemote, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) @@ -142,6 +143,7 @@ contract OffRamp_constructor is OffRampSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, + gasForCallExactCheck: GAS_FOR_CALL_EXACT_CHECK, rmnRemote: s_mockRMNRemote, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) @@ -168,6 +170,7 @@ contract OffRamp_constructor is OffRampSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, + gasForCallExactCheck: GAS_FOR_CALL_EXACT_CHECK, rmnRemote: s_mockRMNRemote, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) @@ -188,6 +191,7 @@ contract OffRamp_constructor is OffRampSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, + gasForCallExactCheck: GAS_FOR_CALL_EXACT_CHECK, rmnRemote: IRMNRemote(address(0)), tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) @@ -208,6 +212,7 @@ contract OffRamp_constructor is OffRampSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: 0, + gasForCallExactCheck: GAS_FOR_CALL_EXACT_CHECK, rmnRemote: s_mockRMNRemote, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) @@ -228,6 +233,7 @@ contract OffRamp_constructor is OffRampSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, + gasForCallExactCheck: GAS_FOR_CALL_EXACT_CHECK, rmnRemote: s_mockRMNRemote, tokenAdminRegistry: address(0), nonceManager: address(s_inboundNonceManager) @@ -248,6 +254,7 @@ contract OffRamp_constructor is OffRampSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, + gasForCallExactCheck: GAS_FOR_CALL_EXACT_CHECK, rmnRemote: s_mockRMNRemote, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(0) diff --git a/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.executeSingleMessage.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.executeSingleMessage.t.sol index 727a7c63bb1..20b711f529e 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.executeSingleMessage.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRamp.executeSingleMessage.t.sol @@ -36,7 +36,7 @@ contract OffRamp_executeSingleMessage is OffRampSetup { abi.encodeWithSelector( IRouter.routeMessage.selector, expectedAny2EvmMessage, - Internal.GAS_FOR_CALL_EXACT_CHECK, + GAS_FOR_CALL_EXACT_CHECK, message.gasLimit, message.receiver ) diff --git a/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRampSetup.t.sol b/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRampSetup.t.sol index 858ee9e4a45..f8b70ebf283 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/OffRamp/OffRampSetup.t.sol @@ -70,6 +70,7 @@ contract OffRampSetup is FeeQuoterSetup, MultiOCR3BaseSetup { OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, rmnRemote: rmnRemote, + gasForCallExactCheck: GAS_FOR_CALL_EXACT_CHECK, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(nonceManager) }), @@ -348,6 +349,7 @@ contract OffRampSetup is FeeQuoterSetup, MultiOCR3BaseSetup { s_offRamp = new OffRampHelper( OffRamp.StaticConfig({ chainSelector: DEST_CHAIN_SELECTOR, + gasForCallExactCheck: GAS_FOR_CALL_EXACT_CHECK, rmnRemote: s_mockRMNRemote, tokenAdminRegistry: address(s_tokenAdminRegistry), nonceManager: address(s_inboundNonceManager) diff --git a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.setChainRateLimiterConfigs.t.sol b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.setChainRateLimiterConfigs.t.sol new file mode 100644 index 00000000000..716e06734ee --- /dev/null +++ b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.setChainRateLimiterConfigs.t.sol @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {RateLimiter} from "../../../libraries/RateLimiter.sol"; +import {TokenPool} from "../../../pools/TokenPool.sol"; +import {TokenPoolSetup} from "./TokenPoolSetup.t.sol"; + +contract TokenPool_setChainRateLimiterConfigs is TokenPoolSetup { + uint64 internal s_remoteChainSelector; + + function setUp() public virtual override { + TokenPoolSetup.setUp(); + + bytes[] memory remotePoolAddresses = new bytes[](1); + remotePoolAddresses[0] = abi.encode(address(2)); + + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); + s_remoteChainSelector = 123124; + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: s_remoteChainSelector, + remotePoolAddresses: remotePoolAddresses, + remoteTokenAddress: abi.encode(address(3)), + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() + }); + s_tokenPool.applyChainUpdates(new uint64[](0), chainUpdates); + } + + function testFuzz_SetChainRateLimiterConfigs_Success(uint128 capacity, uint128 rate, uint32 newTime) public { + // Cap the lower bound to 4 so 4/2 is still >= 2 + vm.assume(capacity >= 4); + // Cap the lower bound to 2 so 2/2 is still >= 1 + rate = uint128(bound(rate, 2, capacity - 2)); + // Bucket updates only work on increasing time + newTime = uint32(bound(newTime, block.timestamp + 1, type(uint32).max)); + vm.warp(newTime); + + uint256 oldOutboundTokens = s_tokenPool.getCurrentOutboundRateLimiterState(DEST_CHAIN_SELECTOR).tokens; + uint256 oldInboundTokens = s_tokenPool.getCurrentInboundRateLimiterState(DEST_CHAIN_SELECTOR).tokens; + + RateLimiter.Config memory newOutboundConfig = RateLimiter.Config({isEnabled: true, capacity: capacity, rate: rate}); + RateLimiter.Config memory newInboundConfig = + RateLimiter.Config({isEnabled: true, capacity: capacity / 2, rate: rate / 2}); + + uint64[] memory chainSelectors = new uint64[](1); + chainSelectors[0] = DEST_CHAIN_SELECTOR; + + RateLimiter.Config[] memory newOutboundConfigs = new RateLimiter.Config[](1); + newOutboundConfigs[0] = newOutboundConfig; + + RateLimiter.Config[] memory newInboundConfigs = new RateLimiter.Config[](1); + newInboundConfigs[0] = newInboundConfig; + + vm.expectEmit(); + emit RateLimiter.ConfigChanged(newOutboundConfig); + vm.expectEmit(); + emit RateLimiter.ConfigChanged(newInboundConfig); + vm.expectEmit(); + emit TokenPool.ChainConfigured(DEST_CHAIN_SELECTOR, newOutboundConfig, newInboundConfig); + + s_tokenPool.setChainRateLimiterConfigs(chainSelectors, newOutboundConfigs, newInboundConfigs); + + uint256 expectedTokens = RateLimiter._min(newOutboundConfig.capacity, oldOutboundTokens); + + RateLimiter.TokenBucket memory bucket = s_tokenPool.getCurrentOutboundRateLimiterState(DEST_CHAIN_SELECTOR); + assertEq(bucket.capacity, newOutboundConfig.capacity); + assertEq(bucket.rate, newOutboundConfig.rate); + assertEq(bucket.tokens, expectedTokens); + assertEq(bucket.lastUpdated, newTime); + + expectedTokens = RateLimiter._min(newInboundConfig.capacity, oldInboundTokens); + + bucket = s_tokenPool.getCurrentInboundRateLimiterState(DEST_CHAIN_SELECTOR); + assertEq(bucket.capacity, newInboundConfig.capacity); + assertEq(bucket.rate, newInboundConfig.rate); + assertEq(bucket.tokens, expectedTokens); + assertEq(bucket.lastUpdated, newTime); + } + + // Reverts + + function test_OnlyOwnerOrRateLimitAdmin_Revert() public { + uint64[] memory chainSelectors = new uint64[](1); + chainSelectors[0] = DEST_CHAIN_SELECTOR; + + RateLimiter.Config[] memory newOutboundConfigs = new RateLimiter.Config[](1); + newOutboundConfigs[0] = _getOutboundRateLimiterConfig(); + + RateLimiter.Config[] memory newInboundConfigs = new RateLimiter.Config[](1); + newInboundConfigs[0] = _getInboundRateLimiterConfig(); + + vm.startPrank(STRANGER); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.Unauthorized.selector, STRANGER)); + s_tokenPool.setChainRateLimiterConfigs(chainSelectors, newOutboundConfigs, newInboundConfigs); + } + + function test_NonExistentChain_Revert() public { + uint64 wrongChainSelector = 9084102894; + + uint64[] memory chainSelectors = new uint64[](1); + chainSelectors[0] = wrongChainSelector; + + RateLimiter.Config[] memory newOutboundConfigs = new RateLimiter.Config[](1); + RateLimiter.Config[] memory newInboundConfigs = new RateLimiter.Config[](1); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.NonExistentChain.selector, wrongChainSelector)); + s_tokenPool.setChainRateLimiterConfigs(chainSelectors, newOutboundConfigs, newInboundConfigs); + } + + function test_MismatchedArrayLengths_Revert() public { + uint64[] memory chainSelectors = new uint64[](1); + + RateLimiter.Config[] memory newOutboundConfigs = new RateLimiter.Config[](1); + RateLimiter.Config[] memory newInboundConfigs = new RateLimiter.Config[](2); + + // test mismatched array lengths between rate limiters + vm.expectRevert(abi.encodeWithSelector(TokenPool.MismatchedArrayLengths.selector)); + s_tokenPool.setChainRateLimiterConfigs(chainSelectors, newOutboundConfigs, newInboundConfigs); + + newInboundConfigs = new RateLimiter.Config[](1); + chainSelectors = new uint64[](2); + + // test mismatched array lengths between chain selectors and rate limiters + vm.expectRevert(abi.encodeWithSelector(TokenPool.MismatchedArrayLengths.selector)); + s_tokenPool.setChainRateLimiterConfigs(chainSelectors, newOutboundConfigs, newInboundConfigs); + } +} diff --git a/contracts/src/v0.8/ccip/test/router/Router/Router.applyRampUpdates.t.sol b/contracts/src/v0.8/ccip/test/router/Router/Router.applyRampUpdates.t.sol index 9b46741f96d..be0999542ea 100644 --- a/contracts/src/v0.8/ccip/test/router/Router/Router.applyRampUpdates.t.sol +++ b/contracts/src/v0.8/ccip/test/router/Router/Router.applyRampUpdates.t.sol @@ -38,7 +38,7 @@ contract Router_applyRampUpdates is RouterSetup { ); } - function testFuzz_OffRampUpdates( + function testFuzz_applyRampUpdates_OffRampUpdates( address[20] memory offRampsInput ) public { Router.OffRamp[] memory offRamps = new Router.OffRamp[](20); @@ -72,7 +72,7 @@ contract Router_applyRampUpdates is RouterSetup { } } - function test_OffRampUpdatesWithRouting() public { + function test_applyRampUpdates_OffRampUpdatesWithRouting() public { // Explicitly construct chain selectors and ramp addresses so we have ramp uniqueness for the various test scenarios. uint256 numberOfSelectors = 10; uint64[] memory sourceChainSelectors = new uint64[](numberOfSelectors); @@ -219,7 +219,7 @@ contract Router_applyRampUpdates is RouterSetup { } } - function testFuzz_OnRampUpdates( + function testFuzz_applyRampUpdates_OnRampUpdates( Router.OnRamp[] memory onRamps ) public { // Test adding onRamps @@ -244,7 +244,7 @@ contract Router_applyRampUpdates is RouterSetup { } } - function test_OnRampDisable() public { + function test_applyRampUpdates_OnRampDisable() public { // Add onRamp Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](0); @@ -267,7 +267,7 @@ contract Router_applyRampUpdates is RouterSetup { assertTrue(s_sourceRouter.isChainSupported(DEST_CHAIN_SELECTOR)); } - function test_OnlyOwner_Revert() public { + function test_applyRampUpdates_RevertWhen_OnlyOwner() public { vm.stopPrank(); vm.expectRevert("Only callable by owner"); Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](0); @@ -275,7 +275,7 @@ contract Router_applyRampUpdates is RouterSetup { s_sourceRouter.applyRampUpdates(onRampUpdates, offRampUpdates, offRampUpdates); } - function test_OffRampMismatch_Revert() public { + function test_applyRampUpdates_RevertWhen_OffRampMismatch() public { address offRamp = address(uint160(2)); Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](0); diff --git a/contracts/src/v0.8/l2ep/shared/BaseSequencerUptimeFeed.sol b/contracts/src/v0.8/l2ep/base/BaseSequencerUptimeFeed.sol similarity index 93% rename from contracts/src/v0.8/l2ep/shared/BaseSequencerUptimeFeed.sol rename to contracts/src/v0.8/l2ep/base/BaseSequencerUptimeFeed.sol index 344270fcff8..81fcb11ca95 100644 --- a/contracts/src/v0.8/l2ep/shared/BaseSequencerUptimeFeed.sol +++ b/contracts/src/v0.8/l2ep/base/BaseSequencerUptimeFeed.sol @@ -59,7 +59,7 @@ abstract contract BaseSequencerUptimeFeed is /// @param l1SenderAddress Address of the L1 contract that is permissioned to call this contract /// @param initialStatus The initial status of the feed constructor(address l1SenderAddress, bool initialStatus) { - // We neet to allow l1SenderAddress to be zero because this contract is deployed first + // We need to allow l1SenderAddress to be zero because this contract is deployed first // After deploying the validator contract, this contract will be updated with the correct L1 sender address _setL1Sender(l1SenderAddress); @@ -81,9 +81,9 @@ abstract contract BaseSequencerUptimeFeed is /// @notice Set the allowed L1 sender for this contract to a new L1 sender /// @dev Can be disabled by setting the L1 sender as `address(0)`. Accessible only by owner. - /// @param to new L1 sender that will be allowed to call `updateStatus` on this contract - function transferL1Sender(address to) external virtual onlyOwner { - _setL1Sender(to); + /// @param newSender new L1 sender that will be allowed to call `updateStatus` on this contract + function transferL1Sender(address newSender) external virtual onlyOwner { + _setL1Sender(newSender); } /// @notice internal method that stores the L1 sender @@ -164,13 +164,10 @@ abstract contract BaseSequencerUptimeFeed is return s_rounds[uint80(roundId)].startedAt; } - /** - * @notice Record a new status and timestamp if it has changed since the last round. - * @dev This function will revert if not called from `l1Sender` via the L1->L2 messenger. - * - * @param status Sequencer status - * @param timestamp Block timestamp of status update - */ + /// @notice Record a new status and timestamp if it has changed since the last round. + /// @dev This function will revert if not called from `l1Sender` via the L1->L2 messenger. + /// @param status Sequencer status + /// @param timestamp Block timestamp of status update function updateStatus(bool status, uint64 timestamp) external override { _validateSender(s_l1Sender); diff --git a/contracts/src/v0.8/l2ep/shared/BaseValidator.sol b/contracts/src/v0.8/l2ep/base/BaseValidator.sol similarity index 96% rename from contracts/src/v0.8/l2ep/shared/BaseValidator.sol rename to contracts/src/v0.8/l2ep/base/BaseValidator.sol index 8b38da391ec..4f9c6912a00 100644 --- a/contracts/src/v0.8/l2ep/shared/BaseValidator.sol +++ b/contracts/src/v0.8/l2ep/base/BaseValidator.sol @@ -24,7 +24,7 @@ abstract contract BaseValidator is SimpleWriteAccessController, AggregatorValida uint32 internal s_gasLimit; /// @param l1CrossDomainMessengerAddress address the L1CrossDomainMessenger contract address - /// @param l2UptimeFeedAddr the address of the SequencerUptimeFeed contract address + /// @param l2UptimeFeedAddr the address of the L2 SequencerUptimeFeed contract address /// @param gasLimit the gasLimit to use for sending a message from L1 to L2 constructor(address l1CrossDomainMessengerAddress, address l2UptimeFeedAddr, uint32 gasLimit) { if (l1CrossDomainMessengerAddress == address(0)) { diff --git a/contracts/src/v0.8/l2ep/optimism/OptimismSequencerUptimeFeed.sol b/contracts/src/v0.8/l2ep/optimism/OptimismSequencerUptimeFeed.sol index 0e6f9c52f22..b160fe46155 100644 --- a/contracts/src/v0.8/l2ep/optimism/OptimismSequencerUptimeFeed.sol +++ b/contracts/src/v0.8/l2ep/optimism/OptimismSequencerUptimeFeed.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -import {BaseSequencerUptimeFeed} from "../shared/BaseSequencerUptimeFeed.sol"; +import {BaseSequencerUptimeFeed} from "../base/BaseSequencerUptimeFeed.sol"; import {IL2CrossDomainMessenger} from "@eth-optimism/contracts/L2/messaging/IL2CrossDomainMessenger.sol"; diff --git a/contracts/src/v0.8/l2ep/optimism/OptimismValidator.sol b/contracts/src/v0.8/l2ep/optimism/OptimismValidator.sol index cf5222f017e..97c202dcd88 100644 --- a/contracts/src/v0.8/l2ep/optimism/OptimismValidator.sol +++ b/contracts/src/v0.8/l2ep/optimism/OptimismValidator.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.19; import {ISequencerUptimeFeed} from "./../interfaces/ISequencerUptimeFeed.sol"; -import {BaseValidator} from "../shared/BaseValidator.sol"; +import {BaseValidator} from "../base/BaseValidator.sol"; import {IL1CrossDomainMessenger} from "@eth-optimism/contracts/L1/messaging/IL1CrossDomainMessenger.sol"; diff --git a/contracts/src/v0.8/l2ep/scroll/ScrollSequencerUptimeFeed.sol b/contracts/src/v0.8/l2ep/scroll/ScrollSequencerUptimeFeed.sol index 40f2941aa69..9c0c22290f2 100644 --- a/contracts/src/v0.8/l2ep/scroll/ScrollSequencerUptimeFeed.sol +++ b/contracts/src/v0.8/l2ep/scroll/ScrollSequencerUptimeFeed.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; -import {BaseSequencerUptimeFeed} from "../shared/BaseSequencerUptimeFeed.sol"; +import {BaseSequencerUptimeFeed} from "../base/BaseSequencerUptimeFeed.sol"; import {IL2ScrollMessenger} from "@scroll-tech/contracts/L2/IL2ScrollMessenger.sol"; diff --git a/contracts/src/v0.8/l2ep/scroll/ScrollValidator.sol b/contracts/src/v0.8/l2ep/scroll/ScrollValidator.sol index b009c80fdfd..0eda14d0adc 100644 --- a/contracts/src/v0.8/l2ep/scroll/ScrollValidator.sol +++ b/contracts/src/v0.8/l2ep/scroll/ScrollValidator.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.24; import {ISequencerUptimeFeed} from "../interfaces/ISequencerUptimeFeed.sol"; -import {BaseValidator} from "../shared/BaseValidator.sol"; +import {BaseValidator} from "../base/BaseValidator.sol"; import {IL1MessageQueue} from "@scroll-tech/contracts/L1/rollup/IL1MessageQueue.sol"; import {IL1ScrollMessenger} from "@scroll-tech/contracts/L1/IL1ScrollMessenger.sol"; diff --git a/contracts/src/v0.8/l2ep/test/mocks/MockBaseSequencerUptimeFeed.sol b/contracts/src/v0.8/l2ep/test/mocks/MockBaseSequencerUptimeFeed.sol new file mode 100644 index 00000000000..50d852faa45 --- /dev/null +++ b/contracts/src/v0.8/l2ep/test/mocks/MockBaseSequencerUptimeFeed.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import {BaseSequencerUptimeFeed} from "../../base/BaseSequencerUptimeFeed.sol"; + +contract MockBaseSequencerUptimeFeed is BaseSequencerUptimeFeed { + string public constant override typeAndVersion = "MockSequencerUptimeFeed 1.1.0-dev"; + + /// @dev this will be used for internal testing + bool private s_validateSenderShouldPass; + + constructor( + address l1SenderAddress, + bool initialStatus, + bool validateSenderShouldPass + ) BaseSequencerUptimeFeed(l1SenderAddress, initialStatus) { + s_validateSenderShouldPass = validateSenderShouldPass; + } + + function _validateSender(address /* l1Sender */) internal view override { + if (!s_validateSenderShouldPass) { + revert InvalidSender(); + } + } +} diff --git a/contracts/src/v0.8/l2ep/test/mocks/MockBaseValidator.sol b/contracts/src/v0.8/l2ep/test/mocks/MockBaseValidator.sol new file mode 100644 index 00000000000..d23efb48656 --- /dev/null +++ b/contracts/src/v0.8/l2ep/test/mocks/MockBaseValidator.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import {BaseValidator} from "../../base/BaseValidator.sol"; + +contract MockBaseValidator is BaseValidator { + string public constant override typeAndVersion = "MockValidator 1.1.0-dev"; + + constructor( + address l1CrossDomainMessengerAddress, + address l2UptimeFeedAddr, + uint32 gasLimit + ) BaseValidator(l1CrossDomainMessengerAddress, l2UptimeFeedAddr, gasLimit) {} + + function validate( + uint256 /* previousRoundId */, + int256 /* previousAnswer */, + uint256 /* currentRoundId */, + int256 /* currentAnswer */ + ) external view override checkAccess returns (bool) { + return true; + } +} diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismSequencerUptimeFeed.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismSequencerUptimeFeed.t.sol index daf50962a1e..34010c313e8 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismSequencerUptimeFeed.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismSequencerUptimeFeed.t.sol @@ -4,30 +4,36 @@ pragma solidity 0.8.24; import {MockOptimismL1CrossDomainMessenger} from "../../../../tests/MockOptimismL1CrossDomainMessenger.sol"; import {MockOptimismL2CrossDomainMessenger} from "../../../../tests/MockOptimismL2CrossDomainMessenger.sol"; import {OptimismSequencerUptimeFeed} from "../../../optimism/OptimismSequencerUptimeFeed.sol"; -import {BaseSequencerUptimeFeed} from "../../../shared/BaseSequencerUptimeFeed.sol"; -import {FeedConsumer} from "../../../../tests/FeedConsumer.sol"; +import {BaseSequencerUptimeFeed} from "../../../base/BaseSequencerUptimeFeed.sol"; import {L2EPTest} from "../L2EPTest.t.sol"; -contract OptimismSequencerUptimeFeedTest is L2EPTest { - /// Constants - uint256 internal constant GAS_USED_DEVIATION = 100; +contract OptimismSequencerUptimeFeed_TestWrapper is OptimismSequencerUptimeFeed { + constructor( + address l1SenderAddress, + address l2CrossDomainMessengerAddr, + bool initialStatus + ) OptimismSequencerUptimeFeed(l1SenderAddress, l2CrossDomainMessengerAddr, initialStatus) {} + + /// @notice Exposes the internal `_validateSender` function for testing + function validateSenderTestWrapper(address l1Sender) external view { + super._validateSender(l1Sender); + } +} + +contract OptimismSequencerUptimeFeed_Setup is L2EPTest { + event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt); /// L2EP contracts MockOptimismL1CrossDomainMessenger internal s_mockOptimismL1CrossDomainMessenger; MockOptimismL2CrossDomainMessenger internal s_mockOptimismL2CrossDomainMessenger; - OptimismSequencerUptimeFeed internal s_optimismSequencerUptimeFeed; - - /// Events - event UpdateIgnored(bool latestStatus, uint64 latestTimestamp, bool incomingStatus, uint64 incomingTimestamp); - event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt); - event RoundUpdated(int256 status, uint64 updatedAt); + OptimismSequencerUptimeFeed_TestWrapper internal s_optimismSequencerUptimeFeed; /// Setup function setUp() public { - // Deploys contracts + // Deploy contracts s_mockOptimismL1CrossDomainMessenger = new MockOptimismL1CrossDomainMessenger(); s_mockOptimismL2CrossDomainMessenger = new MockOptimismL2CrossDomainMessenger(); - s_optimismSequencerUptimeFeed = new OptimismSequencerUptimeFeed( + s_optimismSequencerUptimeFeed = new OptimismSequencerUptimeFeed_TestWrapper( s_l1OwnerAddr, address(s_mockOptimismL2CrossDomainMessenger), false @@ -38,12 +44,14 @@ contract OptimismSequencerUptimeFeedTest is L2EPTest { } } -contract OptimismSequencerUptimeFeed_Constructor is OptimismSequencerUptimeFeedTest { - /// @notice it should have been deployed with the correct initial state - function test_InitialState() public { +contract OptimismSequencerUptimeFeed_Constructor is OptimismSequencerUptimeFeed_Setup { + /// @notice Tests the initial state of the contract + function test_Constructor_InitialState() public { // Sets msg.sender and tx.origin to a valid address vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); + new OptimismSequencerUptimeFeed_TestWrapper(s_l1OwnerAddr, address(s_mockOptimismL2CrossDomainMessenger), false); + // Checks L1 sender address actualL1Addr = s_optimismSequencerUptimeFeed.l1Sender(); assertEq(actualL1Addr, s_l1OwnerAddr); @@ -55,267 +63,33 @@ contract OptimismSequencerUptimeFeed_Constructor is OptimismSequencerUptimeFeedT } } -contract OptimismSequencerUptimeFeed_UpdateStatus is OptimismSequencerUptimeFeedTest { - /// @notice it should revert if called by an address that is not the L2 Cross Domain Messenger - function test_RevertIfNotL2CrossDomainMessengerAddr() public { - // Sets msg.sender and tx.origin to an unauthorized address - vm.startPrank(s_strangerAddr, s_strangerAddr); +contract OptimismSequencerUptimeFeed_ValidateSender is OptimismSequencerUptimeFeed_Setup { + /// @notice Reverts if called by an address that is not the L2 Cross Domain Messenger + function test_ValidateSender_RevertWhen_SenderIsNotL2CrossDomainMessengerAddr() public { + address l2MessengerAddr = address(s_mockOptimismL2CrossDomainMessenger); + // Sets msg.sender to a different address + vm.startPrank(s_strangerAddr, l2MessengerAddr); - // Tries to update the status from an unauthorized account vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(1)); + s_optimismSequencerUptimeFeed.validateSenderTestWrapper(s_l1OwnerAddr); } - /// @notice it should revert if called by an address that is not the L2 Cross Domain Messenger and is not the L1 sender - function test_RevertIfNotL2CrossDomainMessengerAddrAndNotL1SenderAddr() public { + /// @notice Reverts if the L1 sender address is not the L1 Cross Domain Messenger Sender + function test_ValidateSender_RevertWhen_L1CrossDomainMessengerAddrIsNotL1SenderAddr() public { // Sets msg.sender and tx.origin to an unauthorized address - vm.startPrank(s_strangerAddr, s_strangerAddr); - - // Sets mock sender in mock L2 messenger contract - s_mockOptimismL2CrossDomainMessenger.setSender(s_strangerAddr); - - // Tries to update the status from an unauthorized account - vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(1)); - } - - /// @notice it should update status when status has not changed and incoming timestamp is the same as latest - function test_UpdateStatusWhenNoChange() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockOptimismL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Fetches the latest timestamp - uint256 timestamp = s_optimismSequencerUptimeFeed.latestTimestamp(); - - // Submits a status update - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_optimismSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_optimismSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Stores the current round data before updating it - ( - uint80 roundIdBeforeUpdate, - int256 answerBeforeUpdate, - uint256 startedAtBeforeUpdate, - , - uint80 answeredInRoundBeforeUpdate - ) = s_optimismSequencerUptimeFeed.latestRoundData(); - - // Submit another status update with the same status - vm.expectEmit(); - emit RoundUpdated(1, uint64(block.timestamp)); - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(timestamp + 200)); - assertEq(s_optimismSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_optimismSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Stores the current round data after updating it - ( - uint80 roundIdAfterUpdate, - int256 answerAfterUpdate, - uint256 startedAtAfterUpdate, - uint256 updatedAtAfterUpdate, - uint80 answeredInRoundAfterUpdate - ) = s_optimismSequencerUptimeFeed.latestRoundData(); - - // Verifies the latest round data has been properly updated - assertEq(roundIdAfterUpdate, roundIdBeforeUpdate); - assertEq(answerAfterUpdate, answerBeforeUpdate); - assertEq(startedAtAfterUpdate, startedAtBeforeUpdate); - assertEq(answeredInRoundAfterUpdate, answeredInRoundBeforeUpdate); - assertEq(updatedAtAfterUpdate, block.timestamp); - } - - /// @notice it should update status when status has changed and incoming timestamp is newer than the latest - function test_UpdateStatusWhenStatusChangeAndTimeChange() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockOptimismL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Submits a status update - uint256 timestamp = s_optimismSequencerUptimeFeed.latestTimestamp(); - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_optimismSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_optimismSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Submit another status update, different status, newer timestamp should update - timestamp = timestamp + 200; - vm.expectEmit(); - emit AnswerUpdated(0, 3, timestamp); - s_optimismSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); - assertEq(s_optimismSequencerUptimeFeed.latestAnswer(), 0); - assertEq(s_optimismSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - } - - /// @notice it should update status when status has changed and incoming timestamp is the same as latest - function test_UpdateStatusWhenStatusChangeAndNoTimeChange() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockOptimismL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Fetches the latest timestamp - uint256 timestamp = s_optimismSequencerUptimeFeed.latestTimestamp(); - - // Submits a status update - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_optimismSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_optimismSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Submit another status update, different status, same timestamp should update - vm.expectEmit(); - emit AnswerUpdated(0, 3, timestamp); - s_optimismSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); - assertEq(s_optimismSequencerUptimeFeed.latestAnswer(), 0); - assertEq(s_optimismSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - } - - /// @notice it should ignore out-of-order updates - function test_IgnoreOutOfOrderUpdates() public { - // Sets msg.sender and tx.origin to a valid address address l2MessengerAddr = address(s_mockOptimismL2CrossDomainMessenger); vm.startPrank(l2MessengerAddr, l2MessengerAddr); - // Submits a status update - uint256 timestamp = s_optimismSequencerUptimeFeed.latestTimestamp() + 10000; - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_optimismSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_optimismSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Update with different status, but stale timestamp, should be ignored - timestamp = timestamp - 1000; - vm.expectEmit(false, false, false, false); - emit UpdateIgnored(true, 0, true, 0); // arguments are dummy values - // TODO: how can we check that an AnswerUpdated event was NOT emitted - s_optimismSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); + vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); + s_optimismSequencerUptimeFeed.validateSenderTestWrapper(s_strangerAddr); } -} -contract OptimismSequencerUptimeFeed_AggregatorV3Interface is OptimismSequencerUptimeFeedTest { - /// @notice it should return valid answer from getRoundData and latestRoundData - function test_AggregatorV3Interface() public { + /// @notice Updates status when status has changed and incoming timestamp is the same as the latest + function test_ValidateSender_UpdateStatusWhen_StatusChangeAndNoTimeChange() public { // Sets msg.sender and tx.origin to a valid address address l2MessengerAddr = address(s_mockOptimismL2CrossDomainMessenger); vm.startPrank(l2MessengerAddr, l2MessengerAddr); - // Defines helper variables - uint80 roundId; - int256 answer; - uint256 startedAt; - uint256 updatedAt; - uint80 answeredInRound; - - // Checks initial state - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_optimismSequencerUptimeFeed.latestRoundData(); - assertEq(roundId, 1); - assertEq(answer, 0); - assertEq(answeredInRound, roundId); - assertEq(startedAt, updatedAt); - - // Submits status update with different status and newer timestamp, should update - uint256 timestamp = startedAt + 1000; - s_optimismSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_optimismSequencerUptimeFeed.getRoundData(2); - assertEq(roundId, 2); - assertEq(answer, 1); - assertEq(answeredInRound, roundId); - assertEq(startedAt, timestamp); - assertLe(updatedAt, startedAt); - - // Saves round 2 data - uint80 roundId2 = roundId; - int256 answer2 = answer; - uint256 startedAt2 = startedAt; - uint256 updatedAt2 = updatedAt; - uint80 answeredInRound2 = answeredInRound; - - // Checks that last round is still returning the correct data - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_optimismSequencerUptimeFeed.getRoundData(1); - assertEq(roundId, 1); - assertEq(answer, 0); - assertEq(answeredInRound, roundId); - assertEq(startedAt, updatedAt); - - // Assert latestRoundData corresponds to latest round id - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_optimismSequencerUptimeFeed.latestRoundData(); - assertEq(roundId2, roundId); - assertEq(answer2, answer); - assertEq(startedAt2, startedAt); - assertEq(updatedAt2, updatedAt); - assertEq(answeredInRound2, answeredInRound); - } - - /// @notice it should revert from #getRoundData when round does not yet exist (future roundId) - function test_RevertGetRoundDataWhenRoundDoesNotExistYet() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); - - // Gets data from a round that has not happened yet - vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); - s_optimismSequencerUptimeFeed.getRoundData(2); - } - - /// @notice it should revert from #getAnswer when round does not yet exist (future roundId) - function test_RevertGetAnswerWhenRoundDoesNotExistYet() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); - - // Gets data from a round that has not happened yet - vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); - s_optimismSequencerUptimeFeed.getAnswer(2); - } - - /// @notice it should revert from #getTimestamp when round does not yet exist (future roundId) - function test_RevertGetTimestampWhenRoundDoesNotExistYet() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); - - // Gets data from a round that has not happened yet - vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); - s_optimismSequencerUptimeFeed.getTimestamp(2); - } -} - -contract OptimismSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions is OptimismSequencerUptimeFeedTest { - /// @notice it should disallow reads on AggregatorV2V3Interface functions when consuming contract is not whitelisted - function test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() public { - // Deploys a FeedConsumer contract - FeedConsumer feedConsumer = new FeedConsumer(address(s_optimismSequencerUptimeFeed)); - - // Sanity - consumer is not whitelisted - assertEq(s_optimismSequencerUptimeFeed.checkEnabled(), true); - assertEq(s_optimismSequencerUptimeFeed.hasAccess(address(feedConsumer), abi.encode("")), false); - - // Asserts reads are not possible from consuming contract - vm.expectRevert("No access"); - feedConsumer.latestAnswer(); - vm.expectRevert("No access"); - feedConsumer.latestRoundData(); - } - - /// @notice it should allow reads on AggregatorV2V3Interface functions when consuming contract is whitelisted - function test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() public { - // Deploys a FeedConsumer contract - FeedConsumer feedConsumer = new FeedConsumer(address(s_optimismSequencerUptimeFeed)); - - // Whitelist consumer - s_optimismSequencerUptimeFeed.addAccess(address(feedConsumer)); - - // Sanity - consumer is whitelisted - assertEq(s_optimismSequencerUptimeFeed.checkEnabled(), true); - assertEq(s_optimismSequencerUptimeFeed.hasAccess(address(feedConsumer), abi.encode("")), true); - - // Asserts reads are possible from consuming contract - (uint80 roundId, int256 answer, , , ) = feedConsumer.latestRoundData(); - assertEq(feedConsumer.latestAnswer(), 0); - assertEq(roundId, 1); - assertEq(answer, 0); + s_optimismSequencerUptimeFeed.validateSenderTestWrapper(s_l1OwnerAddr); } } diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismValidator.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismValidator.t.sol index ba9e3f872f1..48ff1f7778d 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismValidator.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/optimism/OptimismValidator.t.sol @@ -9,7 +9,7 @@ import {OptimismSequencerUptimeFeed} from "../../../optimism/OptimismSequencerUp import {OptimismValidator} from "../../../optimism/OptimismValidator.sol"; import {L2EPTest} from "../L2EPTest.t.sol"; -contract OptimismValidatorTest is L2EPTest { +contract OptimismValidator_Setup is L2EPTest { /// Helper constants address internal constant L2_SEQ_STATUS_RECORDER_ADDRESS = 0x491B1dDA0A8fa069bbC1125133A975BF4e85a91b; uint32 internal constant INIT_GAS_LIMIT = 1900000; @@ -42,26 +42,16 @@ contract OptimismValidatorTest is L2EPTest { } } -contract OptimismValidator_SetGasLimit is OptimismValidatorTest { - /// @notice it correctly updates the gas limit - function test_CorrectlyUpdatesTheGasLimit() public { - uint32 newGasLimit = 2000000; - assertEq(s_optimismValidator.getGasLimit(), INIT_GAS_LIMIT); - s_optimismValidator.setGasLimit(newGasLimit); - assertEq(s_optimismValidator.getGasLimit(), newGasLimit); - } -} - -contract OptimismValidator_Validate is OptimismValidatorTest { +contract OptimismValidator_Validate is OptimismValidator_Setup { /// @notice it reverts if called by account with no access - function test_RevertsIfCalledByAnAccountWithNoAccess() public { + function test_Validate_RevertWhen_CalledByAccountWithNoAccess() public { vm.startPrank(s_strangerAddr); vm.expectRevert("No access"); s_optimismValidator.validate(0, 0, 1, 1); } - /// @notice it posts sequencer status when there is not status change - function test_PostSequencerStatusWhenThereIsNotStatusChange() public { + /// @notice it posts sequencer status when there is no status change + function test_Validate_PostSequencerStatus_NoStatusChange() public { // Gives access to the s_eoaValidator s_optimismValidator.addAccess(s_eoaValidator); @@ -84,8 +74,8 @@ contract OptimismValidator_Validate is OptimismValidatorTest { s_optimismValidator.validate(0, 0, 0, 0); } - /// @notice it post sequencer offline - function test_PostSequencerOffline() public { + /// @notice it posts sequencer offline + function test_Validate_PostSequencerOffline() public { // Gives access to the s_eoaValidator s_optimismValidator.addAccess(s_eoaValidator); diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainForwarder.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainForwarder.t.sol index b0ef7df22c1..0025c6b9937 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainForwarder.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainForwarder.t.sol @@ -54,7 +54,6 @@ contract ScrollCrossDomainForwarder_Forward is ScrollCrossDomainForwarderTest { /// @notice it should be callable by crossdomain messenger address / L1 owner function test_Forward() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Defines the cross domain message to send @@ -74,7 +73,6 @@ contract ScrollCrossDomainForwarder_Forward is ScrollCrossDomainForwarderTest { /// @notice it should revert when contract call reverts function test_ForwardRevert() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Sends an invalid message @@ -106,7 +104,6 @@ contract ScrollCrossDomainForwarder_TransferL1Ownership is ScrollCrossDomainForw /// @notice it should be callable by current L1 owner function test_CallableByL1Owner() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Defines the cross domain message to send @@ -124,7 +121,6 @@ contract ScrollCrossDomainForwarder_TransferL1Ownership is ScrollCrossDomainForw /// @notice it should be callable by current L1 owner to zero address function test_CallableByL1OwnerOrZeroAddress() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Defines the cross domain message to send @@ -144,7 +140,6 @@ contract ScrollCrossDomainForwarder_TransferL1Ownership is ScrollCrossDomainForw contract ScrollCrossDomainForwarder_AcceptL1Ownership is ScrollCrossDomainForwarderTest { /// @notice it should not be callable by non pending-owners function test_NotCallableByNonPendingOwners() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Sends the message @@ -159,7 +154,6 @@ contract ScrollCrossDomainForwarder_AcceptL1Ownership is ScrollCrossDomainForwar /// @notice it should be callable by pending L1 owner function test_CallableByPendingL1Owner() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Request ownership transfer diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainGovernor.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainGovernor.t.sol index 5eefaddab70..a2523e5feb6 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainGovernor.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollCrossDomainGovernor.t.sol @@ -58,7 +58,6 @@ contract ScrollCrossDomainGovernor_Forward is ScrollCrossDomainGovernorTest { /// @notice it should be callable by crossdomain messenger address / L1 owner function test_Forward() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Defines the cross domain message to send @@ -78,7 +77,6 @@ contract ScrollCrossDomainGovernor_Forward is ScrollCrossDomainGovernorTest { /// @notice it should revert when contract call reverts function test_ForwardRevert() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Sends an invalid message @@ -93,7 +91,6 @@ contract ScrollCrossDomainGovernor_Forward is ScrollCrossDomainGovernorTest { /// @notice it should be callable by L2 owner function test_CallableByL2Owner() public { - // Sets msg.sender and tx.origin vm.startPrank(s_l1OwnerAddr); // Defines the cross domain message to send @@ -120,7 +117,6 @@ contract ScrollCrossDomainGovernor_ForwardDelegate is ScrollCrossDomainGovernorT /// @notice it should be callable by crossdomain messenger address / L1 owner function test_CallableByCrossDomainMessengerAddressOrL1Owner() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Sends the message @@ -141,7 +137,6 @@ contract ScrollCrossDomainGovernor_ForwardDelegate is ScrollCrossDomainGovernorT /// @notice it should be callable by L2 owner function test_CallableByL2Owner() public { - // Sets msg.sender and tx.origin vm.startPrank(s_l1OwnerAddr); // Sends the message @@ -162,7 +157,6 @@ contract ScrollCrossDomainGovernor_ForwardDelegate is ScrollCrossDomainGovernorT /// @notice it should revert batch when one call fails function test_RevertsBatchWhenOneCallFails() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Sends an invalid message (empty transaction data is not allowed) @@ -184,7 +178,6 @@ contract ScrollCrossDomainGovernor_ForwardDelegate is ScrollCrossDomainGovernorT /// @notice it should bubble up revert when contract call reverts function test_BubbleUpRevert() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Sends an invalid message (empty transaction data is not allowed) @@ -220,7 +213,6 @@ contract ScrollCrossDomainGovernor_TransferL1Ownership is ScrollCrossDomainGover /// @notice it should be callable by current L1 owner function test_CallableByL1Owner() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Defines the cross domain message to send @@ -238,7 +230,6 @@ contract ScrollCrossDomainGovernor_TransferL1Ownership is ScrollCrossDomainGover /// @notice it should be callable by current L1 owner to zero address function test_CallableByL1OwnerOrZeroAddress() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Defines the cross domain message to send @@ -258,7 +249,6 @@ contract ScrollCrossDomainGovernor_TransferL1Ownership is ScrollCrossDomainGover contract ScrollCrossDomainGovernor_AcceptL1Ownership is ScrollCrossDomainGovernorTest { /// @notice it should not be callable by non pending-owners function test_NotCallableByNonPendingOwners() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Sends the message @@ -273,7 +263,6 @@ contract ScrollCrossDomainGovernor_AcceptL1Ownership is ScrollCrossDomainGoverno /// @notice it should be callable by pending L1 owner function test_CallableByPendingL1Owner() public { - // Sets msg.sender and tx.origin vm.startPrank(s_strangerAddr); // Request ownership transfer diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollSequencerUptimeFeed.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollSequencerUptimeFeed.t.sol index 5e4d8a7a20f..1ad4bfd8119 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollSequencerUptimeFeed.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollSequencerUptimeFeed.t.sol @@ -4,18 +4,30 @@ pragma solidity 0.8.24; import {MockScrollL1CrossDomainMessenger} from "../../mocks/scroll/MockScrollL1CrossDomainMessenger.sol"; import {MockScrollL2CrossDomainMessenger} from "../../mocks/scroll/MockScrollL2CrossDomainMessenger.sol"; import {ScrollSequencerUptimeFeed} from "../../../scroll/ScrollSequencerUptimeFeed.sol"; -import {BaseSequencerUptimeFeed} from "../../../shared/BaseSequencerUptimeFeed.sol"; -import {FeedConsumer} from "../../../../tests/FeedConsumer.sol"; +import {BaseSequencerUptimeFeed} from "../../../base/BaseSequencerUptimeFeed.sol"; import {L2EPTest} from "../L2EPTest.t.sol"; -contract ScrollSequencerUptimeFeedTest is L2EPTest { +contract ScrollSequencerUptimeFeedTestWrapper is ScrollSequencerUptimeFeed { + constructor( + address l1SenderAddress, + address l2CrossDomainMessengerAddr, + bool initialStatus + ) ScrollSequencerUptimeFeed(l1SenderAddress, l2CrossDomainMessengerAddr, initialStatus) {} + + /// @notice It exposes the internal _validateSender function for testing + function validateSenderTestWrapper(address l1Sender) external view { + super._validateSender(l1Sender); + } +} + +contract ScrollSequencerUptimeFeed_Setup is L2EPTest { /// Constants uint256 internal constant GAS_USED_DEVIATION = 100; /// L2EP contracts MockScrollL1CrossDomainMessenger internal s_mockScrollL1CrossDomainMessenger; MockScrollL2CrossDomainMessenger internal s_mockScrollL2CrossDomainMessenger; - ScrollSequencerUptimeFeed internal s_scrollSequencerUptimeFeed; + ScrollSequencerUptimeFeedTestWrapper internal s_scrollSequencerUptimeFeed; /// Events event UpdateIgnored(bool latestStatus, uint64 latestTimestamp, bool incomingStatus, uint64 incomingTimestamp); @@ -27,7 +39,7 @@ contract ScrollSequencerUptimeFeedTest is L2EPTest { // Deploys contracts s_mockScrollL1CrossDomainMessenger = new MockScrollL1CrossDomainMessenger(); s_mockScrollL2CrossDomainMessenger = new MockScrollL2CrossDomainMessenger(); - s_scrollSequencerUptimeFeed = new ScrollSequencerUptimeFeed( + s_scrollSequencerUptimeFeed = new ScrollSequencerUptimeFeedTestWrapper( s_l1OwnerAddr, address(s_mockScrollL2CrossDomainMessenger), false @@ -38,14 +50,13 @@ contract ScrollSequencerUptimeFeedTest is L2EPTest { } } -contract ScrollSequencerUptimeFeed_Constructor is ScrollSequencerUptimeFeedTest { - /// @notice it should have been deployed with the correct initial state - function test_InitialState() public { +contract ScrollSequencerUptimeFeed_Constructor is ScrollSequencerUptimeFeed_Setup { + /// @notice Reverts when L2 Cross Domain Messenger address is invalid + function test_Constructor_RevertWhen_InvalidL2XDomainMessenger() public { // L2 cross domain messenger address must not be the zero address vm.expectRevert(ScrollSequencerUptimeFeed.ZeroAddress.selector); new ScrollSequencerUptimeFeed(s_l1OwnerAddr, address(0), false); - // Sets msg.sender and tx.origin to a valid address vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); // Checks L1 sender @@ -57,269 +68,50 @@ contract ScrollSequencerUptimeFeed_Constructor is ScrollSequencerUptimeFeedTest assertEq(roundId, 1); assertEq(answer, 0); } -} - -contract ScrollSequencerUptimeFeed_UpdateStatus is ScrollSequencerUptimeFeedTest { - /// @notice it should revert if called by an address that is not the L2 Cross Domain Messenger - function test_RevertIfNotL2CrossDomainMessengerAddr() public { - // Sets msg.sender and tx.origin to an unauthorized address - vm.startPrank(s_strangerAddr, s_strangerAddr); - - // Tries to update the status from an unauthorized account - vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(1)); - } - - /// @notice it should revert if called by an address that is not the L2 Cross Domain Messenger and is not the L1 sender - function test_RevertIfNotL2CrossDomainMessengerAddrAndNotL1SenderAddr() public { - // Sets msg.sender and tx.origin to an unauthorized address - vm.startPrank(s_strangerAddr, s_strangerAddr); - - // Sets mock sender in mock L2 messenger contract - s_mockScrollL2CrossDomainMessenger.setSender(s_strangerAddr); - - // Tries to update the status from an unauthorized account - vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(1)); - } - - /// @notice it should update status when status has not changed and incoming timestamp is the same as latest - function test_UpdateStatusWhenNoChange() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Fetches the latest timestamp - uint256 timestamp = s_scrollSequencerUptimeFeed.latestTimestamp(); - - // Submits a status update - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_scrollSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_scrollSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Stores the current round data before updating it - ( - uint80 roundIdBeforeUpdate, - int256 answerBeforeUpdate, - uint256 startedAtBeforeUpdate, - , - uint80 answeredInRoundBeforeUpdate - ) = s_scrollSequencerUptimeFeed.latestRoundData(); - - // Submit another status update with the same status - vm.expectEmit(); - emit RoundUpdated(1, uint64(block.timestamp)); - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(timestamp + 200)); - assertEq(s_scrollSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_scrollSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Stores the current round data after updating it - ( - uint80 roundIdAfterUpdate, - int256 answerAfterUpdate, - uint256 startedAtAfterUpdate, - uint256 updatedAtAfterUpdate, - uint80 answeredInRoundAfterUpdate - ) = s_scrollSequencerUptimeFeed.latestRoundData(); - - // Verifies the latest round data has been properly updated - assertEq(roundIdAfterUpdate, roundIdBeforeUpdate); - assertEq(answerAfterUpdate, answerBeforeUpdate); - assertEq(startedAtAfterUpdate, startedAtBeforeUpdate); - assertEq(answeredInRoundAfterUpdate, answeredInRoundBeforeUpdate); - assertEq(updatedAtAfterUpdate, block.timestamp); - } - - /// @notice it should update status when status has changed and incoming timestamp is newer than the latest - function test_UpdateStatusWhenStatusChangeAndTimeChange() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Submits a status update - uint256 timestamp = s_scrollSequencerUptimeFeed.latestTimestamp(); - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_scrollSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_scrollSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Submit another status update, different status, newer timestamp should update - timestamp = timestamp + 200; - vm.expectEmit(); - emit AnswerUpdated(0, 3, timestamp); - s_scrollSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); - assertEq(s_scrollSequencerUptimeFeed.latestAnswer(), 0); - assertEq(s_scrollSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - } - - /// @notice it should update status when status has changed and incoming timestamp is the same as latest - function test_UpdateStatusWhenStatusChangeAndNoTimeChange() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Fetches the latest timestamp - uint256 timestamp = s_scrollSequencerUptimeFeed.latestTimestamp(); - - // Submits a status update - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_scrollSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_scrollSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Submit another status update, different status, same timestamp should update - vm.expectEmit(); - emit AnswerUpdated(0, 3, timestamp); - s_scrollSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); - assertEq(s_scrollSequencerUptimeFeed.latestAnswer(), 0); - assertEq(s_scrollSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - } - - /// @notice it should ignore out-of-order updates - function test_IgnoreOutOfOrderUpdates() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - - // Submits a status update - uint256 timestamp = s_scrollSequencerUptimeFeed.latestTimestamp() + 10000; - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_scrollSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_scrollSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Update with different status, but stale timestamp, should be ignored - timestamp = timestamp - 1000; - vm.expectEmit(false, false, false, false); - emit UpdateIgnored(true, 0, true, 0); // arguments are dummy values - // TODO: how can we check that an AnswerUpdated event was NOT emitted - s_scrollSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); - } -} - -contract ScrollSequencerUptimeFeed_AggregatorV3Interface is ScrollSequencerUptimeFeedTest { - /// @notice it should return valid answer from getRoundData and latestRoundData - function test_AggregatorV3Interface() public { - // Sets msg.sender and tx.origin to a valid address - address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); - vm.startPrank(l2MessengerAddr, l2MessengerAddr); - // Defines helper variables - uint80 roundId; - int256 answer; - uint256 startedAt; - uint256 updatedAt; - uint80 answeredInRound; - - // Checks initial state - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_scrollSequencerUptimeFeed.latestRoundData(); - assertEq(roundId, 1); - assertEq(answer, 0); - assertEq(answeredInRound, roundId); - assertEq(startedAt, updatedAt); - - // Submits status update with different status and newer timestamp, should update - uint256 timestamp = startedAt + 1000; - s_scrollSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_scrollSequencerUptimeFeed.getRoundData(2); - assertEq(roundId, 2); - assertEq(answer, 1); - assertEq(answeredInRound, roundId); - assertEq(startedAt, timestamp); - assertLe(updatedAt, startedAt); + /// @notice Tests initial state with valid L2 Cross Domain Messenger + function test_Constructor_InitialState_WhenValidL2XDomainMessenger() public { + vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); + ScrollSequencerUptimeFeed scrollSequencerUptimeFeed = new ScrollSequencerUptimeFeed( + s_l1OwnerAddr, + address(s_mockScrollL2CrossDomainMessenger), + false + ); - // Saves round 2 data - uint80 roundId2 = roundId; - int256 answer2 = answer; - uint256 startedAt2 = startedAt; - uint256 updatedAt2 = updatedAt; - uint80 answeredInRound2 = answeredInRound; + // Checks L1 sender + address actualL1Addr = scrollSequencerUptimeFeed.l1Sender(); + assertEq(actualL1Addr, s_l1OwnerAddr); - // Checks that last round is still returning the correct data - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_scrollSequencerUptimeFeed.getRoundData(1); + // Checks latest round data + (uint80 roundId, int256 answer, , , ) = scrollSequencerUptimeFeed.latestRoundData(); assertEq(roundId, 1); assertEq(answer, 0); - assertEq(answeredInRound, roundId); - assertEq(startedAt, updatedAt); - - // Assert latestRoundData corresponds to latest round id - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_scrollSequencerUptimeFeed.latestRoundData(); - assertEq(roundId2, roundId); - assertEq(answer2, answer); - assertEq(startedAt2, startedAt); - assertEq(updatedAt2, updatedAt); - assertEq(answeredInRound2, answeredInRound); - } - - /// @notice it should revert from #getRoundData when round does not yet exist (future roundId) - function test_RevertGetRoundDataWhenRoundDoesNotExistYet() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); - - // Gets data from a round that has not happened yet - vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); - s_scrollSequencerUptimeFeed.getRoundData(2); - } - - /// @notice it should revert from #getAnswer when round does not yet exist (future roundId) - function test_RevertGetAnswerWhenRoundDoesNotExistYet() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); - - // Gets data from a round that has not happened yet - vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); - s_scrollSequencerUptimeFeed.getAnswer(2); - } - - /// @notice it should revert from #getTimestamp when round does not yet exist (future roundId) - function test_RevertGetTimestampWhenRoundDoesNotExistYet() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); - - // Gets data from a round that has not happened yet - vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); - s_scrollSequencerUptimeFeed.getTimestamp(2); } } -contract ScrollSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions is ScrollSequencerUptimeFeedTest { - /// @notice it should disallow reads on AggregatorV2V3Interface functions when consuming contract is not whitelisted - function test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() public { - // Deploys a FeedConsumer contract - FeedConsumer feedConsumer = new FeedConsumer(address(s_scrollSequencerUptimeFeed)); - - // Sanity - consumer is not whitelisted - assertEq(s_scrollSequencerUptimeFeed.checkEnabled(), true); - assertEq(s_scrollSequencerUptimeFeed.hasAccess(address(feedConsumer), abi.encode("")), false); +contract ScrollSequencerUptimeFeed_ValidateSender is ScrollSequencerUptimeFeed_Setup { + /// @notice Reverts when sender is not L2 Cross Domain Messenger address + function test_ValidateSender_RevertWhen_SenderIsNotL2CrossDomainMessengerAddr() public { + vm.startPrank(s_strangerAddr); - // Asserts reads are not possible from consuming contract - vm.expectRevert("No access"); - feedConsumer.latestAnswer(); - vm.expectRevert("No access"); - feedConsumer.latestRoundData(); + vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); + s_scrollSequencerUptimeFeed.validateSenderTestWrapper(s_l1OwnerAddr); } - /// @notice it should allow reads on AggregatorV2V3Interface functions when consuming contract is whitelisted - function test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() public { - // Deploys a FeedConsumer contract - FeedConsumer feedConsumer = new FeedConsumer(address(s_scrollSequencerUptimeFeed)); + /// @notice Reverts when L1 Cross Domain Messenger address is not L1 sender address + function test_ValidateSender_RevertWhen_L1CrossDomainMessengerAddrIsNotL1SenderAddr() public { + address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); + vm.startPrank(l2MessengerAddr); - // Whitelist consumer - s_scrollSequencerUptimeFeed.addAccess(address(feedConsumer)); + vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); + s_scrollSequencerUptimeFeed.validateSenderTestWrapper(s_strangerAddr); + } - // Sanity - consumer is whitelisted - assertEq(s_scrollSequencerUptimeFeed.checkEnabled(), true); - assertEq(s_scrollSequencerUptimeFeed.hasAccess(address(feedConsumer), abi.encode("")), true); + /// @notice Updates status when status changes and incoming timestamp is the same as latest + function test_ValidateSender_UpdateStatusWhen_StatusChangeAndNoTimeChange() public { + address l2MessengerAddr = address(s_mockScrollL2CrossDomainMessenger); + vm.startPrank(l2MessengerAddr); - // Asserts reads are possible from consuming contract - (uint80 roundId, int256 answer, , , ) = feedConsumer.latestRoundData(); - assertEq(feedConsumer.latestAnswer(), 0); - assertEq(roundId, 1); - assertEq(answer, 0); + s_scrollSequencerUptimeFeed.validateSenderTestWrapper(s_l1OwnerAddr); } } diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollValidator.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollValidator.t.sol index 1a0bcc856f2..b7708889100 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollValidator.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/scroll/ScrollValidator.t.sol @@ -10,9 +10,9 @@ import {ScrollSequencerUptimeFeed} from "../../../scroll/ScrollSequencerUptimeFe import {ScrollValidator} from "../../../scroll/ScrollValidator.sol"; import {L2EPTest} from "../L2EPTest.t.sol"; -contract ScrollValidatorTest is L2EPTest { +contract ScrollValidator_Setup is L2EPTest { /// Helper constants - address internal constant L2_SEQ_STATUS_RECORDER_ADDRESS = 0x491B1dDA0A8fa069bbC1125133A975BF4e85a91b; + address internal immutable L2_SEQ_STATUS_RECORDER_ADDRESS = makeAddr("L2_SEQ_STATUS_RECORDER_ADDRESS"); uint32 internal constant INIT_GAS_LIMIT = 1900000; /// L2EP contracts @@ -53,26 +53,31 @@ contract ScrollValidatorTest is L2EPTest { } } -contract ScrollValidator_SetGasLimit is ScrollValidatorTest { - /// @notice it correctly updates the gas limit - function test_CorrectlyUpdatesTheGasLimit() public { - uint32 newGasLimit = 2000000; - assertEq(s_scrollValidator.getGasLimit(), INIT_GAS_LIMIT); - s_scrollValidator.setGasLimit(newGasLimit); - assertEq(s_scrollValidator.getGasLimit(), newGasLimit); +contract ScrollValidator_Constructor is ScrollValidator_Setup { + /// @notice Reverts when L1 message queue address is invalid + function test_Constructor_RevertWhen_InvalidL1MessageQueueAddress() public { + vm.startPrank(s_l1OwnerAddr); + + vm.expectRevert("Invalid L1 message queue address"); + new ScrollValidator( + address(s_mockScrollL1CrossDomainMessenger), + address(s_scrollSequencerUptimeFeed), + address(0), + INIT_GAS_LIMIT + ); } } -contract ScrollValidator_Validate is ScrollValidatorTest { - /// @notice it reverts if called by account with no access - function test_RevertsIfCalledByAnAccountWithNoAccess() public { +contract ScrollValidator_Validate is ScrollValidator_Setup { + /// @notice Reverts if called by an account with no access + function test_Validate_RevertWhen_CalledByAccountWithNoAccess() public { vm.startPrank(s_strangerAddr); vm.expectRevert("No access"); s_scrollValidator.validate(0, 0, 1, 1); } - /// @notice it posts sequencer status when there is not status change - function test_PostSequencerStatusWhenThereIsNotStatusChange() public { + /// @notice Posts sequencer status when there is no status change + function test_Validate_PostSequencerStatus_NoStatusChange() public { // Gives access to the s_eoaValidator s_scrollValidator.addAccess(s_eoaValidator); @@ -96,8 +101,8 @@ contract ScrollValidator_Validate is ScrollValidatorTest { s_scrollValidator.validate(0, 0, 0, 0); } - /// @notice it post sequencer offline - function test_PostSequencerOffline() public { + /// @notice Posts sequencer offline status + function test_Validate_PostSequencerOffline() public { // Gives access to the s_eoaValidator s_scrollValidator.addAccess(s_eoaValidator); diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/shared/BaseSequencerUptimeFeed.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/shared/BaseSequencerUptimeFeed.t.sol new file mode 100644 index 00000000000..20553e33bab --- /dev/null +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/shared/BaseSequencerUptimeFeed.t.sol @@ -0,0 +1,377 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import {Vm} from "forge-std/Test.sol"; +import {AddressAliasHelper} from "../../../../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol"; +import {BaseSequencerUptimeFeed} from "../../../base/BaseSequencerUptimeFeed.sol"; +import {MockBaseSequencerUptimeFeed} from "../../../test/mocks/MockBaseSequencerUptimeFeed.sol"; +import {FeedConsumer} from "../../../../tests/FeedConsumer.sol"; +import {L2EPTest} from "../L2EPTest.t.sol"; + +contract BaseSequencerUptimeFeed_Setup is L2EPTest { + /// Helper Variables + address internal s_aliasedL1OwnerAddress = AddressAliasHelper.applyL1ToL2Alias(s_l1OwnerAddr); + + /// L2EP contracts + BaseSequencerUptimeFeed internal s_sequencerUptimeFeed; + + /// Events + event UpdateIgnored(bool latestStatus, uint64 latestTimestamp, bool incomingStatus, uint64 incomingTimestamp); + event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt); + event RoundUpdated(int256 status, uint64 updatedAt); + event L1SenderTransferred(address indexed from, address indexed to); + + /// Setup + function setUp() public { + // Deploys contracts + s_sequencerUptimeFeed = new MockBaseSequencerUptimeFeed(s_l1OwnerAddr, false, true); + } +} + +contract BaseSequencerUptimeFeed_Constructor is BaseSequencerUptimeFeed_Setup { + /// @notice Tests initial state of the contract + function test_Constructor_InitialState() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); + + // Checks L1 sender + address actualL1Addr = s_sequencerUptimeFeed.l1Sender(); + assertEq(actualL1Addr, s_l1OwnerAddr); + + // Checks latest round data + (uint80 roundId, int256 answer, , , ) = s_sequencerUptimeFeed.latestRoundData(); + assertEq(roundId, 1); + assertEq(answer, 0); + } +} + +contract BaseSequencerUptimeFeed_transferL1Sender is BaseSequencerUptimeFeed_Setup { + /// @notice Tests transferring L1 sender + function test_transferL1Sender_CorrectlyTransfersL1Sender() public { + address initialSender = address(0); + address newSender = makeAddr("newSender"); + + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); + + MockBaseSequencerUptimeFeed sequencerUptimeFeed = new MockBaseSequencerUptimeFeed(initialSender, false, true); + + assertEq(sequencerUptimeFeed.l1Sender(), initialSender); + + // Transfers the L1 sender + vm.expectEmit(); + emit L1SenderTransferred(initialSender, newSender); + sequencerUptimeFeed.transferL1Sender(newSender); + assertEq(sequencerUptimeFeed.l1Sender(), newSender); + + vm.recordLogs(); + // Transfers to the same L1 sender should not emit an event + sequencerUptimeFeed.transferL1Sender(newSender); + assertEq(vm.getRecordedLogs().length, 0); + } + + /// @notice Reverts if called by an unauthorized account + function test_transferL1Sender_RevertWhen_CalledByUnauthorizedAccount() public { + address newSender = makeAddr("newSender"); + + // Sets msg.sender and tx.origin to an unauthorized address + vm.startPrank(s_strangerAddr, s_strangerAddr); + + vm.expectRevert("Only callable by owner"); + s_sequencerUptimeFeed.transferL1Sender(newSender); + } +} + +contract BaseSequencerUptimeFeed_UpdateStatus is BaseSequencerUptimeFeed_Setup { + /// @notice Reverts if called by an unauthorized account + function test_updateStatus_RevertWhen_NotL2CrossDomainMessengerAddr() public { + // Sets msg.sender and tx.origin to an unauthorized address + vm.startPrank(s_strangerAddr, s_strangerAddr); + + BaseSequencerUptimeFeed s_sequencerUptimeFeedFailSenderCheck = new MockBaseSequencerUptimeFeed( + s_l1OwnerAddr, + false, + false + ); + + // Tries to update the status from an unauthorized account + vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); + s_sequencerUptimeFeedFailSenderCheck.updateStatus(true, uint64(1)); + } + + /// @notice Updates status when status has not changed and incoming timestamp is the same as latest + function test_updateStatus_UpdateWhen_NoStatusChangeSameTimestamp() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); + + // Fetches the latest timestamp + uint256 timestamp = s_sequencerUptimeFeed.latestTimestamp(); + + // Submits a status update + vm.expectEmit(); + emit AnswerUpdated(1, 2, timestamp); + s_sequencerUptimeFeed.updateStatus(true, uint64(timestamp)); + assertEq(s_sequencerUptimeFeed.latestAnswer(), 1); + assertEq(s_sequencerUptimeFeed.latestRound(), 2); + assertEq(s_sequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + + // Stores the current round data before updating it + ( + uint80 roundIdBeforeUpdate, + int256 answerBeforeUpdate, + uint256 startedAtBeforeUpdate, + , + uint80 answeredInRoundBeforeUpdate + ) = s_sequencerUptimeFeed.latestRoundData(); + + // Submit another status update with the same status + vm.expectEmit(); + emit RoundUpdated(1, uint64(block.timestamp)); + s_sequencerUptimeFeed.updateStatus(true, uint64(timestamp + 200)); + assertEq(s_sequencerUptimeFeed.latestAnswer(), 1); + assertEq(s_sequencerUptimeFeed.latestRound(), 2); + assertEq(s_sequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + + // Stores the current round data after updating it + ( + uint80 roundIdAfterUpdate, + int256 answerAfterUpdate, + uint256 startedAtAfterUpdate, + uint256 updatedAtAfterUpdate, + uint80 answeredInRoundAfterUpdate + ) = s_sequencerUptimeFeed.latestRoundData(); + + // Verifies the latest round data has been properly updated + assertEq(roundIdAfterUpdate, roundIdBeforeUpdate); + assertEq(answerAfterUpdate, answerBeforeUpdate); + assertEq(startedAtAfterUpdate, startedAtBeforeUpdate); + assertEq(answeredInRoundAfterUpdate, answeredInRoundBeforeUpdate); + assertEq(updatedAtAfterUpdate, block.timestamp); + } + + /// @notice Updates status when status has changed and incoming timestamp is newer than the latest + function test_updateStatus_UpdateWhen_StatusChangeAndTimeChange() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); + + // Submits a status update + uint256 timestamp = s_sequencerUptimeFeed.latestTimestamp(); + vm.expectEmit(); + emit AnswerUpdated(1, 2, timestamp); + s_sequencerUptimeFeed.updateStatus(true, uint64(timestamp)); + assertEq(s_sequencerUptimeFeed.latestAnswer(), 1); + assertEq(s_sequencerUptimeFeed.latestRound(), 2); + assertEq(s_sequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + + // Submit another status update, different status, newer timestamp should update + timestamp = timestamp + 200; + vm.expectEmit(); + emit AnswerUpdated(0, 3, timestamp); + s_sequencerUptimeFeed.updateStatus(false, uint64(timestamp)); + assertEq(s_sequencerUptimeFeed.latestAnswer(), 0); + assertEq(s_sequencerUptimeFeed.latestRound(), 3); + assertEq(s_sequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + } + + /// @notice Updates status when status has changed and incoming timestamp is the same as latest + function test_updateStatus_UpdateWhen_StatusChangeAndNoTimeChange() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); + + // Fetches the latest timestamp + uint256 timestamp = s_sequencerUptimeFeed.latestTimestamp(); + + // Submits a status update + vm.expectEmit(); + emit AnswerUpdated(1, 2, timestamp); + s_sequencerUptimeFeed.updateStatus(true, uint64(timestamp)); + assertEq(s_sequencerUptimeFeed.latestAnswer(), 1); + assertEq(s_sequencerUptimeFeed.latestRound(), 2); + assertEq(s_sequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + + // Submit another status update, different status, same timestamp should update + vm.expectEmit(); + emit AnswerUpdated(0, 3, timestamp); + s_sequencerUptimeFeed.updateStatus(false, uint64(timestamp)); + assertEq(s_sequencerUptimeFeed.latestAnswer(), 0); + assertEq(s_sequencerUptimeFeed.latestRound(), 3); + assertEq(s_sequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + } + + /// @notice Ignores out-of-order updates + function test_updateStatus_IgnoreOutOfOrderUpdates() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); + + // Submits a status update + uint256 timestamp = s_sequencerUptimeFeed.latestTimestamp() + 10000; + vm.expectEmit(); + emit AnswerUpdated(1, 2, timestamp); + s_sequencerUptimeFeed.updateStatus(true, uint64(timestamp)); + assertEq(s_sequencerUptimeFeed.latestAnswer(), 1); + assertEq(s_sequencerUptimeFeed.latestRound(), 2); + assertEq(s_sequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); + + // Update with different status, but stale timestamp, should be ignored + timestamp = timestamp - 1000; + vm.expectEmit(false, false, false, false); + emit UpdateIgnored(true, 0, true, 0); // arguments are dummy values + + vm.recordLogs(); + + // Tries to update with stale timestamp + s_sequencerUptimeFeed.updateStatus(false, uint64(timestamp)); + + Vm.Log[] memory entries = vm.getRecordedLogs(); + + assertEq(entries.length, 1); + assertEq(entries[0].topics[0], keccak256("UpdateIgnored(bool,uint64,bool,uint64)")); + } +} + +contract BaseSequencerUptimeFeed_AggregatorV3Interface is BaseSequencerUptimeFeed_Setup { + /// @notice Returns valid answer from getRoundData and latestRoundData + function test_AggregatorV3Interface_ReturnsValidData() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); + + // Defines helper variables + uint80 roundId; + int256 answer; + uint256 startedAt; + uint256 updatedAt; + uint80 answeredInRound; + + // Checks initial state + (roundId, answer, startedAt, updatedAt, answeredInRound) = s_sequencerUptimeFeed.latestRoundData(); + assertEq(roundId, 1); + assertEq(answer, 0); + assertEq(answeredInRound, roundId); + assertEq(startedAt, updatedAt); + + // Submits status update with different status and newer timestamp, should update + uint256 timestamp = startedAt + 1000; + s_sequencerUptimeFeed.updateStatus(true, uint64(timestamp)); + (roundId, answer, startedAt, updatedAt, answeredInRound) = s_sequencerUptimeFeed.getRoundData(2); + assertEq(roundId, 2); + assertEq(answer, 1); + assertEq(answeredInRound, roundId); + assertEq(startedAt, timestamp); + assertLe(updatedAt, startedAt); + + // Saves round 2 data + uint80 roundId2 = roundId; + int256 answer2 = answer; + uint256 startedAt2 = startedAt; + uint256 updatedAt2 = updatedAt; + uint80 answeredInRound2 = answeredInRound; + + // Checks that last round is still returning the correct data + (roundId, answer, startedAt, updatedAt, answeredInRound) = s_sequencerUptimeFeed.getRoundData(1); + assertEq(roundId, 1); + assertEq(answer, 0); + assertEq(answeredInRound, roundId); + assertEq(startedAt, updatedAt); + + // Assert latestRoundData corresponds to latest round id + (roundId, answer, startedAt, updatedAt, answeredInRound) = s_sequencerUptimeFeed.latestRoundData(); + assertEq(roundId2, roundId); + assertEq(answer2, answer); + assertEq(startedAt2, startedAt); + assertEq(updatedAt2, updatedAt); + assertEq(answeredInRound2, answeredInRound); + } + + /// @notice Reverts when getRoundData is called for a round that does not exist yet + function test_getRoundData_RevertWhen_RoundDoesNotExist() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); + + // Gets data from a round that has not happened yet + vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); + s_sequencerUptimeFeed.getRoundData(2); + } + + /// @notice Returns the getAnswer for the latest round + function test_getAnswer_ReturnsValidAnswer() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); + + uint256 startedAt; + (, , startedAt, , ) = s_sequencerUptimeFeed.latestRoundData(); + + s_sequencerUptimeFeed.updateStatus(true, uint64(startedAt + 1000)); + + assertEq(0, s_sequencerUptimeFeed.getAnswer(1)); + } + + /// @notice Reverts when getAnswer is called for a round that does not exist yet + function test_getAnswer_RevertWhen_RoundDoesNotExist() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); + + // Gets data from a round that has not happened yet + vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); + s_sequencerUptimeFeed.getAnswer(2); + } + + /// @notice Returns the getTimestamp for the latest round + function test_getTimestamp_ReturnsValidTimestamp() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); + + uint256 startedAt; + (, , startedAt, , ) = s_sequencerUptimeFeed.latestRoundData(); + + s_sequencerUptimeFeed.updateStatus(true, uint64(startedAt + 1000)); + + assertEq(startedAt, s_sequencerUptimeFeed.getTimestamp(1)); + } + + /// @notice Reverts when getTimestamp is called for a round that does not exist yet + function test_getTimestamp_RevertWhen_RoundDoesNotExist() public { + // Sets msg.sender and tx.origin to a valid address + vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); + + // Gets data from a round that has not happened yet + vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); + s_sequencerUptimeFeed.getTimestamp(2); + } +} + +contract BaseSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions is BaseSequencerUptimeFeed_Setup { + /// @notice Disallows reads on AggregatorV2V3Interface functions when consuming contract is not whitelisted + function test_ProtectReads_DisallowWhen_NotWhitelisted() public { + // Deploys a FeedConsumer contract + FeedConsumer feedConsumer = new FeedConsumer(address(s_sequencerUptimeFeed)); + + // Sanity - consumer is not whitelisted + assertEq(s_sequencerUptimeFeed.checkEnabled(), true); + assertEq(s_sequencerUptimeFeed.hasAccess(address(feedConsumer), abi.encode("")), false); + + // Asserts reads are not possible from consuming contract + vm.expectRevert("No access"); + feedConsumer.latestAnswer(); + vm.expectRevert("No access"); + feedConsumer.latestRoundData(); + } + + /// @notice Allows reads on AggregatorV2V3Interface functions when consuming contract is whitelisted + function test_ProtectReads_AllowWhen_Whitelisted() public { + // Deploys a FeedConsumer contract + FeedConsumer feedConsumer = new FeedConsumer(address(s_sequencerUptimeFeed)); + + // Whitelist consumer + s_sequencerUptimeFeed.addAccess(address(feedConsumer)); + + // Sanity - consumer is whitelisted + assertEq(s_sequencerUptimeFeed.checkEnabled(), true); + assertEq(s_sequencerUptimeFeed.hasAccess(address(feedConsumer), abi.encode("")), true); + + // Asserts reads are possible from consuming contract + (uint80 roundId, int256 answer, , , ) = feedConsumer.latestRoundData(); + assertEq(feedConsumer.latestAnswer(), 0); + assertEq(roundId, 1); + assertEq(answer, 0); + } +} diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/shared/BaseValidator.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/shared/BaseValidator.t.sol new file mode 100644 index 00000000000..4b0868c71b3 --- /dev/null +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/shared/BaseValidator.t.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import {BaseValidator} from "../../../base/BaseValidator.sol"; +import {MockBaseValidator} from "../../mocks/MockBaseValidator.sol"; +import {L2EPTest} from "../L2EPTest.t.sol"; + +contract BaseValidator_Setup is L2EPTest { + address internal immutable L2_SEQ_STATUS_RECORDER_ADDRESS = makeAddr("L2_SEQ_STATUS_RECORDER_ADDRESS"); + address internal immutable DUMMY_L1_XDOMAIN_MSNGR_ADDR = makeAddr("DUMMY_L1_XDOMAIN_MSNGR_ADDR"); + address internal immutable DUMMY_L2_UPTIME_FEED_ADDR = makeAddr("DUMMY_L2_UPTIME_FEED_ADDR"); + uint32 internal constant INIT_GAS_LIMIT = 1900000; + + BaseValidator internal s_baseValidator; + + /// Fake event that will get emitted when `requestL2TransactionDirect` is called + /// Definition is taken from MockZKSyncL1Bridge + event SentMessage(address indexed sender, bytes message); + + /// Setup + function setUp() public { + s_baseValidator = new MockBaseValidator( + DUMMY_L1_XDOMAIN_MSNGR_ADDR, + L2_SEQ_STATUS_RECORDER_ADDRESS, + INIT_GAS_LIMIT + ); + } +} + +contract BaseValidator_Constructor is BaseValidator_Setup { + /// @notice Reverts when L1 bridge address is zero + function test_Constructor_RevertWhen_L1BridgeAddressIsZero() public { + vm.expectRevert(BaseValidator.L1CrossDomainMessengerAddressZero.selector); + new MockBaseValidator(address(0), DUMMY_L2_UPTIME_FEED_ADDR, INIT_GAS_LIMIT); + } + + /// @notice Reverts when L2 Uptime feed address is zero + function test_Constructor_RevertWhen_L2UptimeFeedAddressIsZero() public { + vm.expectRevert(BaseValidator.L2UptimeFeedAddrZero.selector); + new MockBaseValidator(DUMMY_L1_XDOMAIN_MSNGR_ADDR, address(0), INIT_GAS_LIMIT); + } +} + +contract BaseValidator_GetAndSetGasLimit is BaseValidator_Setup { + /// @notice Verifies the correct retrieval and update of the gas limit + function test_GetAndSetGasLimit_CorrectlyHandlesGasLimit() public { + assertEq(s_baseValidator.getGasLimit(), INIT_GAS_LIMIT); + + uint32 newGasLimit = INIT_GAS_LIMIT + 1; + + vm.expectEmit(); + emit BaseValidator.GasLimitUpdated(newGasLimit); + s_baseValidator.setGasLimit(newGasLimit); + + assertEq(s_baseValidator.getGasLimit(), newGasLimit); + } +} diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncSequencerUptimeFeed.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncSequencerUptimeFeed.t.sol index 5b319d32407..8e9c387c875 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncSequencerUptimeFeed.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncSequencerUptimeFeed.t.sol @@ -3,289 +3,50 @@ pragma solidity ^0.8.24; import {AddressAliasHelper} from "../../../../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol"; import {ZKSyncSequencerUptimeFeed} from "../../../zksync/ZKSyncSequencerUptimeFeed.sol"; -import {BaseSequencerUptimeFeed} from "../../../shared/BaseSequencerUptimeFeed.sol"; -import {FeedConsumer} from "../../../../tests/FeedConsumer.sol"; +import {BaseSequencerUptimeFeed} from "../../../base/BaseSequencerUptimeFeed.sol"; import {L2EPTest} from "../L2EPTest.t.sol"; -contract ZKSyncSequencerUptimeFeedTest is L2EPTest { +contract ZKSyncSequencerUptimeFeed_TestWrapper is ZKSyncSequencerUptimeFeed { + constructor(address l1SenderAddress, bool initialStatus) ZKSyncSequencerUptimeFeed(l1SenderAddress, initialStatus) {} + + /// @notice Exposes the internal _validateSender function for testing + function validateSenderTestWrapper(address l1Sender) external view { + super._validateSender(l1Sender); + } +} + +contract ZKSyncSequencerUptimeFeed_Setup is L2EPTest { /// Helper Variables - address internal s_aliasedL1OwnerAddress = AddressAliasHelper.applyL1ToL2Alias(s_l1OwnerAddr); + address internal l1SenderAddress = address(5); + address internal s_aliasedL1SenderAddress = AddressAliasHelper.applyL1ToL2Alias(l1SenderAddress); /// L2EP contracts - ZKSyncSequencerUptimeFeed internal s_zksyncSequencerUptimeFeed; - - /// Events - event UpdateIgnored(bool latestStatus, uint64 latestTimestamp, bool incomingStatus, uint64 incomingTimestamp); - event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt); - event RoundUpdated(int256 status, uint64 updatedAt); + ZKSyncSequencerUptimeFeed_TestWrapper internal s_zksyncSequencerUptimeFeed; /// Setup function setUp() public { // Deploys contracts - s_zksyncSequencerUptimeFeed = new ZKSyncSequencerUptimeFeed(s_l1OwnerAddr, false); - } -} - -contract ZKSyncSequencerUptimeFeed_Constructor is ZKSyncSequencerUptimeFeedTest { - /// @notice it should have been deployed with the correct initial state - function test_InitialState() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); - - // Checks L1 sender - address actualL1Addr = s_zksyncSequencerUptimeFeed.l1Sender(); - assertEq(actualL1Addr, s_l1OwnerAddr); - - // Checks latest round data - (uint80 roundId, int256 answer, , , ) = s_zksyncSequencerUptimeFeed.latestRoundData(); - assertEq(roundId, 1); - assertEq(answer, 0); + s_zksyncSequencerUptimeFeed = new ZKSyncSequencerUptimeFeed_TestWrapper(l1SenderAddress, false); } } -contract ZKSyncSequencerUptimeFeed_UpdateStatus is ZKSyncSequencerUptimeFeedTest { - /// @notice it should revert if called by an unauthorized account - function test_RevertIfNotL2CrossDomainMessengerAddr() public { - // Sets msg.sender and tx.origin to an unauthorized address - vm.startPrank(s_strangerAddr, s_strangerAddr); +contract ZKSyncSequencerUptimeFeed_ValidateSender is ZKSyncSequencerUptimeFeed_Setup { + /// @notice Reverts when pass is not valid + function test_ValidateSender_RevertWhen_PassIsNotValid() public { + // Sets msg.sender and tx.origin to an authorized address + vm.startPrank(s_aliasedL1SenderAddress, s_aliasedL1SenderAddress); // Tries to update the status from an unauthorized account vm.expectRevert(BaseSequencerUptimeFeed.InvalidSender.selector); - s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(1)); - } - - /// @notice it should update status when status has not changed and incoming timestamp is the same as latest - function test_UpdateStatusWhenNoChange() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); - - // Fetches the latest timestamp - uint256 timestamp = s_zksyncSequencerUptimeFeed.latestTimestamp(); - - // Submits a status update - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Stores the current round data before updating it - ( - uint80 roundIdBeforeUpdate, - int256 answerBeforeUpdate, - uint256 startedAtBeforeUpdate, - , - uint80 answeredInRoundBeforeUpdate - ) = s_zksyncSequencerUptimeFeed.latestRoundData(); - - // Submit another status update with the same status - vm.expectEmit(); - emit RoundUpdated(1, uint64(block.timestamp)); - s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(timestamp + 200)); - assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Stores the current round data after updating it - ( - uint80 roundIdAfterUpdate, - int256 answerAfterUpdate, - uint256 startedAtAfterUpdate, - uint256 updatedAtAfterUpdate, - uint80 answeredInRoundAfterUpdate - ) = s_zksyncSequencerUptimeFeed.latestRoundData(); - - // Verifies the latest round data has been properly updated - assertEq(roundIdAfterUpdate, roundIdBeforeUpdate); - assertEq(answerAfterUpdate, answerBeforeUpdate); - assertEq(startedAtAfterUpdate, startedAtBeforeUpdate); - assertEq(answeredInRoundAfterUpdate, answeredInRoundBeforeUpdate); - assertEq(updatedAtAfterUpdate, block.timestamp); - } - - /// @notice it should update status when status has changed and incoming timestamp is newer than the latest - function test_UpdateStatusWhenStatusChangeAndTimeChange() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); - - // Submits a status update - uint256 timestamp = s_zksyncSequencerUptimeFeed.latestTimestamp(); - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Submit another status update, different status, newer timestamp should update - timestamp = timestamp + 200; - vm.expectEmit(); - emit AnswerUpdated(0, 3, timestamp); - s_zksyncSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); - assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 0); - assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - } - - /// @notice it should update status when status has changed and incoming timestamp is the same as latest - function test_UpdateStatusWhenStatusChangeAndNoTimeChange() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); - - // Fetches the latest timestamp - uint256 timestamp = s_zksyncSequencerUptimeFeed.latestTimestamp(); - - // Submits a status update - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Submit another status update, different status, same timestamp should update - vm.expectEmit(); - emit AnswerUpdated(0, 3, timestamp); - s_zksyncSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); - assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 0); - assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - } - - /// @notice it should ignore out-of-order updates - function test_IgnoreOutOfOrderUpdates() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); - - // Submits a status update - uint256 timestamp = s_zksyncSequencerUptimeFeed.latestTimestamp() + 10000; - vm.expectEmit(); - emit AnswerUpdated(1, 2, timestamp); - s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - assertEq(s_zksyncSequencerUptimeFeed.latestAnswer(), 1); - assertEq(s_zksyncSequencerUptimeFeed.latestTimestamp(), uint64(timestamp)); - - // Update with different status, but stale timestamp, should be ignored - timestamp = timestamp - 1000; - vm.expectEmit(false, false, false, false); - emit UpdateIgnored(true, 0, true, 0); // arguments are dummy values - // TODO: how can we check that an AnswerUpdated event was NOT emitted - s_zksyncSequencerUptimeFeed.updateStatus(false, uint64(timestamp)); - } -} - -contract ZKSyncSequencerUptimeFeed_AggregatorV3Interface is ZKSyncSequencerUptimeFeedTest { - /// @notice it should return valid answer from getRoundData and latestRoundData - function test_AggregatorV3Interface() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_aliasedL1OwnerAddress, s_aliasedL1OwnerAddress); - - // Defines helper variables - uint80 roundId; - int256 answer; - uint256 startedAt; - uint256 updatedAt; - uint80 answeredInRound; - - // Checks initial state - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_zksyncSequencerUptimeFeed.latestRoundData(); - assertEq(roundId, 1); - assertEq(answer, 0); - assertEq(answeredInRound, roundId); - assertEq(startedAt, updatedAt); - - // Submits status update with different status and newer timestamp, should update - uint256 timestamp = startedAt + 1000; - s_zksyncSequencerUptimeFeed.updateStatus(true, uint64(timestamp)); - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_zksyncSequencerUptimeFeed.getRoundData(2); - assertEq(roundId, 2); - assertEq(answer, 1); - assertEq(answeredInRound, roundId); - assertEq(startedAt, timestamp); - assertLe(updatedAt, startedAt); - - // Saves round 2 data - uint80 roundId2 = roundId; - int256 answer2 = answer; - uint256 startedAt2 = startedAt; - uint256 updatedAt2 = updatedAt; - uint80 answeredInRound2 = answeredInRound; - - // Checks that last round is still returning the correct data - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_zksyncSequencerUptimeFeed.getRoundData(1); - assertEq(roundId, 1); - assertEq(answer, 0); - assertEq(answeredInRound, roundId); - assertEq(startedAt, updatedAt); - - // Assert latestRoundData corresponds to latest round id - (roundId, answer, startedAt, updatedAt, answeredInRound) = s_zksyncSequencerUptimeFeed.latestRoundData(); - assertEq(roundId2, roundId); - assertEq(answer2, answer); - assertEq(startedAt2, startedAt); - assertEq(updatedAt2, updatedAt); - assertEq(answeredInRound2, answeredInRound); - } - - /// @notice it should revert from #getRoundData when round does not yet exist (future roundId) - function test_RevertGetRoundDataWhenRoundDoesNotExistYet() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); - - // Gets data from a round that has not happened yet - vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); - s_zksyncSequencerUptimeFeed.getRoundData(2); - } - - /// @notice it should revert from #getAnswer when round does not yet exist (future roundId) - function test_RevertGetAnswerWhenRoundDoesNotExistYet() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); - - // Gets data from a round that has not happened yet - vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); - s_zksyncSequencerUptimeFeed.getAnswer(2); - } - - /// @notice it should revert from #getTimestamp when round does not yet exist (future roundId) - function test_RevertGetTimestampWhenRoundDoesNotExistYet() public { - // Sets msg.sender and tx.origin to a valid address - vm.startPrank(s_l1OwnerAddr, s_l1OwnerAddr); - - // Gets data from a round that has not happened yet - vm.expectRevert(BaseSequencerUptimeFeed.NoDataPresent.selector); - s_zksyncSequencerUptimeFeed.getTimestamp(2); + s_zksyncSequencerUptimeFeed.validateSenderTestWrapper(address(6)); } -} - -contract ZKSyncSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions is ZKSyncSequencerUptimeFeedTest { - /// @notice it should disallow reads on AggregatorV2V3Interface functions when consuming contract is not whitelisted - function test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() public { - // Deploys a FeedConsumer contract - FeedConsumer feedConsumer = new FeedConsumer(address(s_zksyncSequencerUptimeFeed)); - - // Sanity - consumer is not whitelisted - assertEq(s_zksyncSequencerUptimeFeed.checkEnabled(), true); - assertEq(s_zksyncSequencerUptimeFeed.hasAccess(address(feedConsumer), abi.encode("")), false); - - // Asserts reads are not possible from consuming contract - vm.expectRevert("No access"); - feedConsumer.latestAnswer(); - vm.expectRevert("No access"); - feedConsumer.latestRoundData(); - } - - /// @notice it should allow reads on AggregatorV2V3Interface functions when consuming contract is whitelisted - function test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() public { - // Deploys a FeedConsumer contract - FeedConsumer feedConsumer = new FeedConsumer(address(s_zksyncSequencerUptimeFeed)); - - // Whitelist consumer - s_zksyncSequencerUptimeFeed.addAccess(address(feedConsumer)); - // Sanity - consumer is whitelisted - assertEq(s_zksyncSequencerUptimeFeed.checkEnabled(), true); - assertEq(s_zksyncSequencerUptimeFeed.hasAccess(address(feedConsumer), abi.encode("")), true); + /// @notice Passes when sender is valid + function test_ValidateSender_SuccessWhen_SenderIsValid() public { + // Sets msg.sender and tx.origin to an authorized address + vm.startPrank(s_aliasedL1SenderAddress, s_aliasedL1SenderAddress); - // Asserts reads are possible from consuming contract - (uint80 roundId, int256 answer, , , ) = feedConsumer.latestRoundData(); - assertEq(feedConsumer.latestAnswer(), 0); - assertEq(roundId, 1); - assertEq(answer, 0); + // Tries to update the status from an authorized account + s_zksyncSequencerUptimeFeed.validateSenderTestWrapper(l1SenderAddress); } } diff --git a/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncValidator.t.sol b/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncValidator.t.sol index 1a0f16d6ae0..e36a2732c27 100644 --- a/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncValidator.t.sol +++ b/contracts/src/v0.8/l2ep/test/v1_0_0/zksync/ZKSyncValidator.t.sol @@ -4,13 +4,13 @@ pragma solidity ^0.8.24; import {MockBridgehub} from "../../mocks/zksync/MockZKSyncL1Bridge.sol"; import {ISequencerUptimeFeed} from "../../../interfaces/ISequencerUptimeFeed.sol"; import {ZKSyncValidator} from "../../../zksync/ZKSyncValidator.sol"; -import {BaseValidator} from "../../../shared/BaseValidator.sol"; +import {BaseValidator} from "../../../base/BaseValidator.sol"; import {L2EPTest} from "../L2EPTest.t.sol"; -contract ZKSyncValidatorTest is L2EPTest { - address internal constant L2_SEQ_STATUS_RECORDER_ADDRESS = address(0x491B1dDA0A8fa069bbC1125133A975BF4e85a91b); - address internal constant DUMMY_L1_XDOMAIN_MSNGR_ADDR = address(0xa04Fc18f012B1a5A8231c7Ee4b916Dd6dbd271b6); - address internal constant DUMMY_L2_UPTIME_FEED_ADDR = address(0xFe31891940A2e5f04B76eD8bD1038E44127d1512); +contract ZKSyncValidator_Setup is L2EPTest { + address internal immutable L2_SEQ_STATUS_RECORDER_ADDRESS = makeAddr("L2_SEQ_STATUS_RECORDER_ADDRESS"); + address internal immutable DUMMY_L1_XDOMAIN_MSNGR_ADDR = makeAddr("DUMMY_L1_XDOMAIN_MSNGR_ADDR"); + address internal immutable DUMMY_L2_UPTIME_FEED_ADDR = makeAddr("DUMMY_L2_UPTIME_FEED_ADDR"); uint32 internal constant INIT_GAS_PER_PUBDATA_BYTE_LIMIT = 800; uint32 internal constant INIT_GAS_LIMIT = 1900000; uint32 internal constant MAIN_NET_CHAIN_ID = 300; @@ -38,9 +38,9 @@ contract ZKSyncValidatorTest is L2EPTest { } } -contract ZKSyncValidator_Constructor is ZKSyncValidatorTest { - /// @notice it correctly validates that the chain id is valid - function test_ConstructingRevertedWithInvalidChainId() public { +contract ZKSyncValidator_Constructor is ZKSyncValidator_Setup { + /// @notice Reverts when chain ID is invalid + function test_Constructor_RevertWhen_ChainIdIsInvalid() public { vm.expectRevert(ZKSyncValidator.InvalidChainID.selector); new ZKSyncValidator( DUMMY_L1_XDOMAIN_MSNGR_ADDR, @@ -51,8 +51,8 @@ contract ZKSyncValidator_Constructor is ZKSyncValidatorTest { ); } - /// @notice it correctly validates that the L1 bridge address is not zero - function test_ConstructingRevertedWithZeroL1BridgeAddress() public { + /// @notice Reverts when L1 bridge address is zero + function test_Constructor_RevertWhen_L1BridgeAddressIsZero() public { vm.expectRevert(BaseValidator.L1CrossDomainMessengerAddressZero.selector); new ZKSyncValidator( address(0), @@ -63,8 +63,8 @@ contract ZKSyncValidator_Constructor is ZKSyncValidatorTest { ); } - /// @notice it correctly validates that the L2 Uptime feed address is not zero - function test_ConstructingRevertedWithZeroL2UpdateFeedAddress() public { + /// @notice Reverts when L2 update feed address is zero + function test_Constructor_RevertWhen_L2UpdateFeedAddressIsZero() public { vm.expectRevert(BaseValidator.L2UptimeFeedAddrZero.selector); new ZKSyncValidator( DUMMY_L1_XDOMAIN_MSNGR_ADDR, @@ -76,9 +76,9 @@ contract ZKSyncValidator_Constructor is ZKSyncValidatorTest { } } -contract ZKSyncValidator_GetSetL2GasPerPubdataByteLimit is ZKSyncValidatorTest { - /// @notice it correctly updates the gas limit per pubdata byte - function test_CorrectlyGetsAndUpdatesTheGasPerPubdataByteLimit() public { +contract ZKSyncValidator_GetSetL2GasPerPubdataByteLimit is ZKSyncValidator_Setup { + /// @notice Correctly gets and updates the gas per pubdata byte limit + function test_GetSetL2GasPerPubdataByteLimit_CorrectlyHandlesGasPerPubdataByteLimit() public { assertEq(s_zksyncValidator.getL2GasPerPubdataByteLimit(), INIT_GAS_PER_PUBDATA_BYTE_LIMIT); uint32 newGasPerPubDataByteLimit = 2000000; @@ -87,23 +87,23 @@ contract ZKSyncValidator_GetSetL2GasPerPubdataByteLimit is ZKSyncValidatorTest { } } -contract ZKSyncValidator_GetChainId is ZKSyncValidatorTest { - /// @notice it correctly gets the chain id - function test_CorrectlyGetsTheChainId() public { +contract ZKSyncValidator_GetChainId is ZKSyncValidator_Setup { + /// @notice Correctly gets the chain ID + function test_GetChainId_CorrectlyGetsTheChainId() public view { assertEq(s_zksyncValidator.getChainId(), MAIN_NET_CHAIN_ID); } } -contract ZKSyncValidator_Validate is ZKSyncValidatorTest { - /// @notice it reverts if called by account with no access - function test_RevertsIfCalledByAnAccountWithNoAccess() public { +contract ZKSyncValidator_Validate is ZKSyncValidator_Setup { + /// @notice Reverts if called by an account with no access + function test_Validate_RevertWhen_CalledByAccountWithNoAccess() public { vm.startPrank(s_strangerAddr); vm.expectRevert("No access"); s_zksyncValidator.validate(0, 0, 1, 1); } - /// @notice it posts sequencer status when there is not status change - function test_PostSequencerStatusWhenThereIsNotStatusChange() public { + /// @notice Posts sequencer status when there is no status change + function test_Validate_PostSequencerStatus_NoStatusChange() public { // Gives access to the s_eoaValidator s_zksyncValidator.addAccess(s_eoaValidator); @@ -126,8 +126,8 @@ contract ZKSyncValidator_Validate is ZKSyncValidatorTest { s_zksyncValidator.validate(0, 0, 0, 0); } - /// @notice it post sequencer offline - function test_PostSequencerOffline() public { + /// @notice Posts sequencer offline status + function test_Validate_PostSequencerOffline() public { // Gives access to the s_eoaValidator s_zksyncValidator.addAccess(s_eoaValidator); diff --git a/contracts/src/v0.8/l2ep/zksync/ZKSyncSequencerUptimeFeed.sol b/contracts/src/v0.8/l2ep/zksync/ZKSyncSequencerUptimeFeed.sol index cb520d2d0ac..e464cc7407d 100644 --- a/contracts/src/v0.8/l2ep/zksync/ZKSyncSequencerUptimeFeed.sol +++ b/contracts/src/v0.8/l2ep/zksync/ZKSyncSequencerUptimeFeed.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -import {BaseSequencerUptimeFeed} from "../shared/BaseSequencerUptimeFeed.sol"; +import {BaseSequencerUptimeFeed} from "../base/BaseSequencerUptimeFeed.sol"; import {AddressAliasHelper} from "../../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol"; diff --git a/contracts/src/v0.8/l2ep/zksync/ZKSyncValidator.sol b/contracts/src/v0.8/l2ep/zksync/ZKSyncValidator.sol index 10f68ce286d..39ba0cd839a 100644 --- a/contracts/src/v0.8/l2ep/zksync/ZKSyncValidator.sol +++ b/contracts/src/v0.8/l2ep/zksync/ZKSyncValidator.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.19; import {ISequencerUptimeFeed} from "./../interfaces/ISequencerUptimeFeed.sol"; -import {BaseValidator} from "../shared/BaseValidator.sol"; +import {BaseValidator} from "../base/BaseValidator.sol"; import {IBridgehub, L2TransactionRequestDirect} from "@zksync/contracts/l1-contracts/contracts/bridgehub/IBridgehub.sol"; diff --git a/contracts/src/v0.8/shared/token/ERC20/BurnMintERC20.sol b/contracts/src/v0.8/shared/token/ERC20/BurnMintERC20.sol index 946a6623b49..ea11dc08798 100644 --- a/contracts/src/v0.8/shared/token/ERC20/BurnMintERC20.sol +++ b/contracts/src/v0.8/shared/token/ERC20/BurnMintERC20.sol @@ -13,7 +13,6 @@ import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/ut /// @notice A basic ERC20 compatible token contract with burn and minting roles. /// @dev The total supply can be limited during deployment. -/// @dev This contract has not been audited and is not yet approved for production use. contract BurnMintERC20 is IBurnMintERC20, IGetCCIPAdmin, IERC165, ERC20Burnable, AccessControl { error MaxSupplyExceeded(uint256 supplyAfterMint); error InvalidRecipient(address recipient); @@ -153,7 +152,7 @@ contract BurnMintERC20 is IBurnMintERC20, IGetCCIPAdmin, IERC165, ERC20Burnable, /// @dev only the owner can call this function, NOT the current ccipAdmin, and 1-step ownership transfer is used. /// @param newAdmin The address to transfer the CCIPAdmin role to. Setting to address(0) is a valid way to revoke /// the role - function setCCIPAdmin(address newAdmin) public onlyRole(DEFAULT_ADMIN_ROLE) { + function setCCIPAdmin(address newAdmin) external onlyRole(DEFAULT_ADMIN_ROLE) { address currentAdmin = s_ccipAdmin; s_ccipAdmin = newAdmin; diff --git a/contracts/src/v0.8/workflow/dev/WorkflowRegistry.sol b/contracts/src/v0.8/workflow/dev/WorkflowRegistry.sol index 0e6ae3450ac..2454374b2fb 100644 --- a/contracts/src/v0.8/workflow/dev/WorkflowRegistry.sol +++ b/contracts/src/v0.8/workflow/dev/WorkflowRegistry.sol @@ -43,6 +43,8 @@ contract WorkflowRegistry is Ownable2StepMsgSender, ITypeAndVersion { /// @dev Mapping to track workflows by secretsURL hash (owner + secretsURL). /// This is used to find all workflows that have the same secretsURL when a force secrets update event is requested. mapping(bytes32 secretsURLHash => EnumerableSet.Bytes32Set workflowKeys) private s_secretsHashToWorkflows; + /// @dev Keep track of all workflowIDs to ensure uniqueness. + mapping(bytes32 workflowID => bool inUse) private s_workflowIDs; /// @dev List of all authorized EOAs/contracts allowed to access this contract's state functions. All view functions are open access. EnumerableSet.AddressSet private s_authorizedAddresses; @@ -203,13 +205,15 @@ contract WorkflowRegistry is Ownable2StepMsgSender, ITypeAndVersion { ) external registryNotLocked { _validatePermissions(donID, msg.sender); _validateWorkflowName(bytes(workflowName).length); - _validateWorkflowMetadata(workflowID, bytes(binaryURL).length, bytes(configURL).length, bytes(secretsURL).length); + _validateWorkflowURLs(bytes(binaryURL).length, bytes(configURL).length, bytes(secretsURL).length); bytes32 workflowKey = computeHashKey(msg.sender, workflowName); if (s_workflows[workflowKey].owner != address(0)) { revert WorkflowAlreadyRegistered(); } + _requireUniqueWorkflowID(workflowID); + // Create new workflow entry s_workflows[workflowKey] = WorkflowMetadata({ workflowID: workflowID, @@ -272,7 +276,7 @@ contract WorkflowRegistry is Ownable2StepMsgSender, ITypeAndVersion { string calldata configURL, string calldata secretsURL ) external registryNotLocked { - _validateWorkflowMetadata(newWorkflowID, bytes(binaryURL).length, bytes(configURL).length, bytes(secretsURL).length); + _validateWorkflowURLs(bytes(binaryURL).length, bytes(configURL).length, bytes(secretsURL).length); WorkflowMetadata storage workflow = _getWorkflowFromStorage(msg.sender, workflowKey); @@ -295,6 +299,12 @@ contract WorkflowRegistry is Ownable2StepMsgSender, ITypeAndVersion { revert WorkflowContentNotUpdated(); } + // Ensure the new workflowID is unique + _requireUniqueWorkflowID(newWorkflowID); + + // Free the old workflowID + s_workflowIDs[currentWorkflowID] = false; + // Update all fields that have changed and the relevant sets workflow.workflowID = newWorkflowID; if (!sameBinaryURL) { @@ -387,6 +397,9 @@ contract WorkflowRegistry is Ownable2StepMsgSender, ITypeAndVersion { revert AddressNotAuthorized(msg.sender); } + // Release the workflowID for reuse + s_workflowIDs[workflow.workflowID] = false; + // Remove the workflow from the owner and DON mappings s_ownerWorkflowKeys[msg.sender].remove(workflowKey); s_donWorkflowKeys[workflow.donID].remove(workflowKey); @@ -508,6 +521,20 @@ contract WorkflowRegistry is Ownable2StepMsgSender, ITypeAndVersion { return workflow; } + /// @notice Ensures the given workflowID is unique and marks it as used. + /// @param workflowID The workflowID to validate and consume. + function _requireUniqueWorkflowID( + bytes32 workflowID + ) internal { + if (workflowID == bytes32(0)) revert InvalidWorkflowID(); + + if (s_workflowIDs[workflowID]) { + revert WorkflowIDAlreadyExists(); + } + + s_workflowIDs[workflowID] = true; + } + // ================================================================ // | Workflow Queries | // ================================================================ @@ -636,16 +663,12 @@ contract WorkflowRegistry is Ownable2StepMsgSender, ITypeAndVersion { // | Validation | // ================================================================ - /// @dev Internal function to validate the metadata for a workflow. - /// @param workflowID The unique identifier for the workflow. - function _validateWorkflowMetadata( - bytes32 workflowID, + /// @dev Internal function to validate the urls for a workflow. + function _validateWorkflowURLs( uint256 binaryURLLength, uint256 configURLLength, uint256 secretsURLLength ) internal pure { - if (workflowID == bytes32(0)) revert InvalidWorkflowID(); - if (binaryURLLength > MAX_URL_LENGTH) { revert URLTooLong(binaryURLLength, MAX_URL_LENGTH); } diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.registerWorkflow.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.registerWorkflow.t.sol index 426fbfcc502..859437196cd 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.registerWorkflow.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.registerWorkflow.t.sol @@ -138,6 +138,35 @@ contract WorkflowRegistry_registerWorkflow is WorkflowRegistrySetup { ); } + // whenTheCallerIsAnAuthorizedAddress whenTheRegistryIsNotLocked whenTheDonIDIsAllowed + function test_RevertWhen_TheWorkflowIDIsAlreadyInUsedByAnotherWorkflow() external { + vm.startPrank(s_authorizedAddress); + + // Register a valid workflow first + s_registry.registerWorkflow( + s_validWorkflowName, + s_validWorkflowID, + s_allowedDonID, + WorkflowRegistry.WorkflowStatus.ACTIVE, + s_validBinaryURL, + s_validConfigURL, + s_validSecretsURL + ); + + vm.expectRevert(WorkflowRegistry.WorkflowIDAlreadyExists.selector); + s_registry.registerWorkflow( + "ValidWorkflow2", + s_validWorkflowID, + s_allowedDonID, + WorkflowRegistry.WorkflowStatus.ACTIVE, + s_validBinaryURL, + s_validConfigURL, + s_validSecretsURL + ); + + vm.stopPrank(); + } + // whenTheCallerIsAnAuthorizedAddress whenTheRegistryIsNotLocked whenTheDonIDIsAllowed function test_RevertWhen_TheWorkflowNameIsAlreadyUsedByTheOwner() external { vm.startPrank(s_authorizedAddress); diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.registerWorkflow.tree b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.registerWorkflow.tree index 75cdf940575..eabbf58d464 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.registerWorkflow.tree +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.registerWorkflow.tree @@ -18,6 +18,8 @@ WorkflowRegistry.registerWorkflow │ └── it should revert ├── when the workflowID is invalid │ └── it should revert + ├── when the workflowID is already in used by another workflow + │ └── it should revert ├── when the workflow name is already used by the owner │ └── it should revert └── when the workflow inputs are all valid diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.updateWorkflow.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.updateWorkflow.t.sol index 5058512ba7b..4082874a91e 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.updateWorkflow.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.updateWorkflow.t.sol @@ -158,6 +158,32 @@ contract WorkflowRegistry_updateWorkflow is WorkflowRegistrySetup { s_registry.updateWorkflow(s_validWorkflowKey, bytes32(0), s_validBinaryURL, s_validConfigURL, s_newValidSecretsURL); } + // whenTheCallerIsAnAuthorizedAddress whenTheRegistryIsNotLocked whenTheDonIDIsAllowed whenTheCallerIsTheWorkflowOwner + function test_RevertWhen_TheWorkflowIDIsAlreadyInUsedByAnotherWorkflow() external { + // Register a workflow first + _registerValidWorkflow(); + + // Register another workflow with another workflow ID + vm.startPrank(s_authorizedAddress); + s_registry.registerWorkflow( + "ValidWorkflow2", + s_newValidWorkflowID, + s_allowedDonID, + WorkflowRegistry.WorkflowStatus.ACTIVE, + s_validBinaryURL, + s_validConfigURL, + s_validSecretsURL + ); + + // Update the workflow with a workflow ID that is already in use by another workflow. + vm.expectRevert(WorkflowRegistry.WorkflowIDAlreadyExists.selector); + s_registry.updateWorkflow( + s_validWorkflowKey, s_newValidWorkflowID, s_validBinaryURL, s_validConfigURL, s_newValidSecretsURL + ); + + vm.stopPrank(); + } + // whenTheCallerIsAnAuthorizedAddress whenTheRegistryIsNotLocked whenTheDonIDIsAllowed whenTheCallerIsTheWorkflowOwner function test_WhenTheWorkflowInputsAreAllValid() external { // Register a workflow first. diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.updateWorkflow.tree b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.updateWorkflow.tree index 0d4da7cb32e..9b8243a8672 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.updateWorkflow.tree +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.updateWorkflow.tree @@ -25,6 +25,8 @@ WorkflowRegistry.updateWorkflow │ └── it should revert ├── when the workflowID is invalid │ └── it should revert + ├── when the workflowID is already in used by another workflow + │ └── it should revert └── when the workflow inputs are all valid ├── it should update the existing workflow in s_workflows with the new values ├── it should emit {WorkflowUpdatedV1} diff --git a/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go b/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go index 13d2b8f4d5c..ea52438edad 100644 --- a/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go +++ b/core/capabilities/ccip/ccip_integration_tests/integrationhelpers/integration_helpers.go @@ -8,6 +8,7 @@ import ( "fmt" "math/big" "sort" + "strconv" "testing" "time" @@ -137,7 +138,7 @@ func NewTestUniverse(ctx context.Context, t *testing.T, lggr logger.Logger) Test t.Cleanup(func() { require.NoError(t, lp.Close()) }) cr := NewReader(t, lp, headTracker, cl, ccAddress, configsevm.HomeChainReaderConfigRaw) - hcr := NewHomeChainReader(t, cr, ccAddress) + hcr := NewHomeChainReader(t, cr, ccAddress, strconv.Itoa(chainID)) return TestUniverse{ Transactor: transactor, Backend: backend, @@ -237,11 +238,22 @@ func (t *TestUniverse) AddCapability(p2pIDs [][32]byte) { } } -func NewHomeChainReader(t *testing.T, cr types.ContractReader, ccAddress common.Address) ccipreader.HomeChain { - hcr := ccipreader.NewHomeChainReader(cr, logger.TestLogger(t), 50*time.Millisecond, types.BoundContract{ - Address: ccAddress.String(), - Name: consts.ContractNameCCIPConfig, - }) +func NewHomeChainReader( + t *testing.T, + cr types.ContractReader, + ccAddress common.Address, + chainID string, +) ccipreader.HomeChain { + hcr := ccipreader.NewObservedHomeChainReader( + cr, + logger.TestLogger(t), + 50*time.Millisecond, + types.BoundContract{ + Address: ccAddress.String(), + Name: consts.ContractNameCCIPConfig, + }, + chainID, + ) require.NoError(t, hcr.Start(testutils.Context(t))) t.Cleanup(func() { require.NoError(t, hcr.Close()) }) diff --git a/core/capabilities/ccip/configs/evm/contract_reader.go b/core/capabilities/ccip/configs/evm/contract_reader.go index f4942943ec4..dca590094f8 100644 --- a/core/capabilities/ccip/configs/evm/contract_reader.go +++ b/core/capabilities/ccip/configs/evm/contract_reader.go @@ -89,6 +89,10 @@ var DestReaderConfig = evmrelaytypes.ChainReaderConfig{ ChainSpecificName: mustGetMethodName("getAllSourceChainConfigs", offrampABI), ReadType: evmrelaytypes.Method, }, + consts.MethodNameOffRampLatestConfigDetails: { + ChainSpecificName: mustGetMethodName("latestConfigDetails", offrampABI), + ReadType: evmrelaytypes.Method, + }, consts.EventNameCommitReportAccepted: { ChainSpecificName: mustGetEventName(consts.EventNameCommitReportAccepted, offrampABI), ReadType: evmrelaytypes.Event, diff --git a/core/capabilities/ccip/delegate.go b/core/capabilities/ccip/delegate.go index 09e3769627e..1af4f44cd4a 100644 --- a/core/capabilities/ccip/delegate.go +++ b/core/capabilities/ccip/delegate.go @@ -167,11 +167,12 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) (services return nil, fmt.Errorf("failed to get home chain contract reader: %w", err) } - hcr := ccipreaderpkg.NewHomeChainReader( + hcr := ccipreaderpkg.NewObservedHomeChainReader( homeChainContractReader, d.lggr.Named("HomeChainReader"), 100*time.Millisecond, ccipConfigBinding, + d.capabilityConfig.ExternalRegistry().ChainID(), ) // get the chain selector for the home chain diff --git a/core/capabilities/compute/cache.go b/core/capabilities/compute/cache.go index 7b7cd78aaab..dbcc42c1606 100644 --- a/core/capabilities/compute/cache.go +++ b/core/capabilities/compute/cache.go @@ -38,8 +38,9 @@ type moduleCache struct { timeout time.Duration evictAfterSize int - clock clockwork.Clock - onReaper chan struct{} + clock clockwork.Clock + reapTicker <-chan time.Time + onReaper chan struct{} } func newModuleCache(clock clockwork.Clock, tick, timeout time.Duration, evictAfterSize int) *moduleCache { @@ -49,6 +50,7 @@ func newModuleCache(clock clockwork.Clock, tick, timeout time.Duration, evictAft timeout: timeout, evictAfterSize: evictAfterSize, clock: clock, + reapTicker: clock.NewTicker(tick).Chan(), stopChan: make(chan struct{}), } } @@ -67,10 +69,9 @@ func (mc *moduleCache) close() { } func (mc *moduleCache) reapLoop() { - ticker := mc.clock.NewTicker(mc.tickInterval) for { select { - case <-ticker.Chan(): + case <-mc.reapTicker: mc.evictOlderThan(mc.timeout) if mc.onReaper != nil { mc.onReaper <- struct{}{} @@ -84,7 +85,7 @@ func (mc *moduleCache) reapLoop() { func (mc *moduleCache) add(id string, mod *module) { mc.mu.Lock() defer mc.mu.Unlock() - mod.lastFetchedAt = time.Now() + mod.lastFetchedAt = mc.clock.Now() mc.m[id] = mod moduleCacheAddition.Inc() } diff --git a/core/capabilities/compute/cache_test.go b/core/capabilities/compute/cache_test.go index 3b38cc23001..ad075f493b5 100644 --- a/core/capabilities/compute/cache_test.go +++ b/core/capabilities/compute/cache_test.go @@ -20,14 +20,17 @@ const ( binaryCmd = "core/capabilities/compute/test/simple/cmd" ) +// Verify that cache evicts an expired module. func TestCache(t *testing.T) { t.Parallel() clock := clockwork.NewFakeClock() tick := 1 * time.Second timeout := 1 * time.Second + reapTicker := make(chan time.Time) cache := newModuleCache(clock, tick, timeout, 0) cache.onReaper = make(chan struct{}, 1) + cache.reapTicker = reapTicker cache.start() defer cache.close() @@ -50,20 +53,24 @@ func TestCache(t *testing.T) { assert.Equal(t, got, mod) clock.Advance(15 * time.Second) + reapTicker <- time.Now() <-cache.onReaper _, ok = cache.get(id) assert.False(t, ok) } +// Verify that an expired module is not evicted because evictAfterSize is 1 func TestCache_EvictAfterSize(t *testing.T) { t.Parallel() ctx := tests.Context(t) clock := clockwork.NewFakeClock() tick := 1 * time.Second timeout := 1 * time.Second + reapTicker := make(chan time.Time) cache := newModuleCache(clock, tick, timeout, 1) cache.onReaper = make(chan struct{}, 1) + cache.reapTicker = reapTicker cache.start() defer cache.close() @@ -79,6 +86,7 @@ func TestCache_EvictAfterSize(t *testing.T) { module: hmod, } cache.add(id, mod) + assert.Len(t, cache.m, 1) got, ok := cache.get(id) assert.True(t, ok) @@ -86,6 +94,7 @@ func TestCache_EvictAfterSize(t *testing.T) { assert.Equal(t, got, mod) clock.Advance(15 * time.Second) + reapTicker <- time.Now() select { case <-ctx.Done(): return diff --git a/core/capabilities/launcher.go b/core/capabilities/launcher.go index 27c43fe0a53..98318853e2a 100644 --- a/core/capabilities/launcher.go +++ b/core/capabilities/launcher.go @@ -398,7 +398,8 @@ func (w *launcher) addToRegistryAndSetDispatcher(ctx context.Context, capability } var ( - defaultTargetRequestTimeout = time.Minute + // TODO: make this configurable + defaultTargetRequestTimeout = 8 * time.Minute ) func (w *launcher) exposeCapabilities(ctx context.Context, myPeerID p2ptypes.PeerID, don registrysyncer.DON, state *registrysyncer.LocalRegistry, remoteWorkflowDONs []registrysyncer.DON) error { diff --git a/core/capabilities/remote/executable/client.go b/core/capabilities/remote/executable/client.go index 9af32eb5f8e..776ddb692ad 100644 --- a/core/capabilities/remote/executable/client.go +++ b/core/capabilities/remote/executable/client.go @@ -41,6 +41,8 @@ var _ commoncap.ExecutableCapability = &client{} var _ types.Receiver = &client{} var _ services.Service = &client{} +const expiryCheckInterval = 30 * time.Second + func NewClient(remoteCapabilityInfo commoncap.CapabilityInfo, localDonInfo commoncap.DON, dispatcher types.Dispatcher, requestTimeout time.Duration, lggr logger.Logger) *client { return &client{ @@ -98,7 +100,11 @@ func (c *client) checkDispatcherReady() { } func (c *client) checkForExpiredRequests() { - ticker := time.NewTicker(c.requestTimeout) + tickerInterval := expiryCheckInterval + if c.requestTimeout < tickerInterval { + tickerInterval = c.requestTimeout + } + ticker := time.NewTicker(tickerInterval) defer ticker.Stop() for { select { @@ -116,7 +122,7 @@ func (c *client) expireRequests() { for messageID, req := range c.requestIDToCallerRequest { if req.Expired() { - req.Cancel(errors.New("request expired")) + req.Cancel(errors.New("request expired by executable client")) delete(c.requestIDToCallerRequest, messageID) } diff --git a/core/capabilities/remote/executable/client_test.go b/core/capabilities/remote/executable/client_test.go index 5c4da350b9e..0314f62b1b7 100644 --- a/core/capabilities/remote/executable/client_test.go +++ b/core/capabilities/remote/executable/client_test.go @@ -29,6 +29,7 @@ const ( ) func Test_Client_DonTopologies(t *testing.T) { + testutils.SkipFlakey(t, "https://smartcontract-it.atlassian.net/browse/CAPPL-363") ctx := testutils.Context(t) transmissionSchedule, err := values.NewMap(map[string]any{ @@ -87,6 +88,7 @@ func Test_Client_DonTopologies(t *testing.T) { } func Test_Client_TransmissionSchedules(t *testing.T) { + testutils.SkipFlakey(t, "https://smartcontract-it.atlassian.net/browse/CAPPL-363") ctx := testutils.Context(t) responseTest := func(t *testing.T, response commoncap.CapabilityResponse, responseError error) { diff --git a/core/capabilities/remote/executable/endtoend_test.go b/core/capabilities/remote/executable/endtoend_test.go index 4e78fead87e..5f445db4235 100644 --- a/core/capabilities/remote/executable/endtoend_test.go +++ b/core/capabilities/remote/executable/endtoend_test.go @@ -78,7 +78,7 @@ func Test_RemoteExecutionCapability_CapabilityError(t *testing.T) { methods = append(methods, func(ctx context.Context, caller commoncap.ExecutableCapability) { executeCapability(ctx, t, caller, transmissionSchedule, func(t *testing.T, responseCh commoncap.CapabilityResponse, responseError error) { - assert.Equal(t, "error executing request: failed to execute capability: an error", responseError.Error()) + assert.Equal(t, "error executing request: failed to execute capability", responseError.Error()) }) }) @@ -102,12 +102,12 @@ func Test_RemoteExecutableCapability_RandomCapabilityError(t *testing.T) { methods = append(methods, func(ctx context.Context, caller commoncap.ExecutableCapability) { executeCapability(ctx, t, caller, transmissionSchedule, func(t *testing.T, responseCh commoncap.CapabilityResponse, responseError error) { - assert.Equal(t, "error executing request: request expired", responseError.Error()) + assert.Equal(t, "error executing request: failed to execute capability", responseError.Error()) }) }) for _, method := range methods { - testRemoteExecutableCapability(ctx, t, capability, 10, 9, 10*time.Millisecond, 10, 9, 10*time.Minute, + testRemoteExecutableCapability(ctx, t, capability, 10, 9, 1*time.Second, 10, 9, 10*time.Minute, method) } } diff --git a/core/capabilities/remote/executable/request/server_request.go b/core/capabilities/remote/executable/request/server_request.go index a4662e93987..629622494a4 100644 --- a/core/capabilities/remote/executable/request/server_request.go +++ b/core/capabilities/remote/executable/request/server_request.go @@ -2,6 +2,7 @@ package request import ( "context" + "errors" "fmt" "sync" "time" @@ -48,6 +49,8 @@ type ServerRequest struct { lggr logger.Logger } +var errExternalErrorMsg = errors.New("failed to execute capability") + func NewServerRequest(capability capabilities.ExecutableCapability, method string, capabilityID string, capabilityDonID uint32, capabilityPeerID p2ptypes.PeerID, callingDon commoncap.DON, requestID string, @@ -228,20 +231,22 @@ func executeCapabilityRequest(ctx context.Context, lggr logger.Logger, capabilit payload []byte) ([]byte, error) { capabilityRequest, err := pb.UnmarshalCapabilityRequest(payload) if err != nil { - return nil, fmt.Errorf("failed to unmarshal capability request: %w", err) + lggr.Errorw("failed to unmarshal capability request", "err", err) + return nil, errExternalErrorMsg } lggr.Debugw("executing capability", "metadata", capabilityRequest.Metadata) capResponse, err := capability.Execute(ctx, capabilityRequest) if err != nil { - lggr.Debugw("received execution error", "workflowExecutionID", capabilityRequest.Metadata.WorkflowExecutionID, "error", err) - return nil, fmt.Errorf("failed to execute capability: %w", err) + lggr.Errorw("received execution error", "workflowExecutionID", capabilityRequest.Metadata.WorkflowExecutionID, "error", err) + return nil, errExternalErrorMsg } responsePayload, err := pb.MarshalCapabilityResponse(capResponse) if err != nil { - return nil, fmt.Errorf("failed to marshal capability response: %w", err) + lggr.Errorw("failed to marshal capability request", "err", err) + return nil, errExternalErrorMsg } lggr.Debugw("received execution results", "workflowExecutionID", capabilityRequest.Metadata.WorkflowExecutionID) diff --git a/core/capabilities/remote/executable/request/server_request_test.go b/core/capabilities/remote/executable/request/server_request_test.go index cbeec833a1f..ce539154d93 100644 --- a/core/capabilities/remote/executable/request/server_request_test.go +++ b/core/capabilities/remote/executable/request/server_request_test.go @@ -136,9 +136,9 @@ func Test_ServerRequest_MessageValidation(t *testing.T) { require.NoError(t, err) assert.Len(t, dispatcher.msgs, 2) assert.Equal(t, types.Error_INTERNAL_ERROR, dispatcher.msgs[0].Error) - assert.Equal(t, "failed to execute capability: an error", dispatcher.msgs[0].ErrorMsg) + assert.Equal(t, "failed to execute capability", dispatcher.msgs[0].ErrorMsg) assert.Equal(t, types.Error_INTERNAL_ERROR, dispatcher.msgs[1].Error) - assert.Equal(t, "failed to execute capability: an error", dispatcher.msgs[1].ErrorMsg) + assert.Equal(t, "failed to execute capability", dispatcher.msgs[1].ErrorMsg) }) t.Run("Execute capability", func(t *testing.T) { diff --git a/core/capabilities/remote/executable/server.go b/core/capabilities/remote/executable/server.go index b767a2d7030..d43c7ab5c41 100644 --- a/core/capabilities/remote/executable/server.go +++ b/core/capabilities/remote/executable/server.go @@ -87,7 +87,11 @@ func (r *server) Start(ctx context.Context) error { r.wg.Add(1) go func() { defer r.wg.Done() - ticker := time.NewTicker(r.requestTimeout) + tickerInterval := expiryCheckInterval + if r.requestTimeout < tickerInterval { + tickerInterval = r.requestTimeout + } + ticker := time.NewTicker(tickerInterval) defer ticker.Stop() r.lggr.Info("executable capability server started") for { @@ -118,7 +122,7 @@ func (r *server) expireRequests() { for requestID, executeReq := range r.requestIDToRequest { if executeReq.request.Expired() { - err := executeReq.request.Cancel(types.Error_TIMEOUT, "request expired") + err := executeReq.request.Cancel(types.Error_TIMEOUT, "request expired by executable server") if err != nil { r.lggr.Errorw("failed to cancel request", "request", executeReq, "err", err) } diff --git a/core/capabilities/triggers/logevent/trigger.go b/core/capabilities/triggers/logevent/trigger.go index 7ee76c6f44a..334c3c3f30e 100644 --- a/core/capabilities/triggers/logevent/trigger.go +++ b/core/capabilities/triggers/logevent/trigger.go @@ -67,6 +67,11 @@ func newLogEventTrigger(ctx context.Context, return nil, nil, err } + err = contractReader.Start(ctx) + if err != nil { + return nil, nil, err + } + // Get current block HEAD/tip of the blockchain to start polling from latestHead, err := relayer.LatestHead(ctx) if err != nil { diff --git a/core/chains/evm/client/errors.go b/core/chains/evm/client/errors.go index d47d97660b1..bde97185580 100644 --- a/core/chains/evm/client/errors.go +++ b/core/chains/evm/client/errors.go @@ -64,6 +64,7 @@ const ( ServiceUnavailable TerminallyStuck TooManyResults + ServiceTimeout ) type ClientErrors map[int]*regexp.Regexp @@ -160,7 +161,8 @@ 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]*$|network is unreachable|i/o timeout`), + ServiceUnavailable: regexp.MustCompile(`(: |^)502 Bad Gateway: [\s\S]*$|network is unreachable|i/o timeout|(: |^)503 Service Temporarily Unavailable(:|$)`), + ServiceTimeout: regexp.MustCompile(`(: |^)408 Request Timeout(:|$)`), } // Treasure @@ -240,7 +242,7 @@ var harmony = ClientErrors{ var zkSync = ClientErrors{ NonceTooLow: regexp.MustCompile(`(?:: |^)nonce too low\..+actual: \d*$`), NonceTooHigh: regexp.MustCompile(`(?:: |^)nonce too high\..+actual: \d*$`), - TerminallyUnderpriced: regexp.MustCompile(`(?:: |^)(max fee per gas less than block base fee|virtual machine entered unexpected state. please contact developers and provide transaction details that caused this error. Error description: The operator included transaction with an unacceptable gas price)$`), + TerminallyUnderpriced: regexp.MustCompile(`(?:: |^)(max fee per gas less than block base fee|virtual machine entered unexpected state. (?:P|p)lease contact developers and provide transaction details that caused this error. Error description: (?:The operator included transaction with an unacceptable gas price|Assertion error: Fair pubdata price too high))$`), InsufficientEth: regexp.MustCompile(`(?:: |^)(?:insufficient balance for transfer$|insufficient funds for gas + value)`), TxFeeExceedsCap: regexp.MustCompile(`(?:: |^)max priority fee per gas higher than max fee per gas$`), // intrinsic gas too low - gas limit less than 14700 @@ -398,6 +400,11 @@ func (s *SendError) IsServiceUnavailable(configErrors *ClientErrors) bool { return s.is(ServiceUnavailable, configErrors) || pkgerrors.Is(s.err, commonclient.ErroringNodeError) } +// IsServiceTimeout indicates if the error was caused by a service timeout +func (s *SendError) IsServiceTimeout(configErrors *ClientErrors) bool { + return s.is(ServiceTimeout, configErrors) +} + // IsTerminallyStuck indicates if a transaction was stuck without any chance of inclusion func (s *SendError) IsTerminallyStuckConfigError(configErrors *ClientErrors) bool { return s.is(TerminallyStuck, configErrors) @@ -619,6 +626,10 @@ func ClassifySendError(err error, clientErrors config.ClientErrors, lggr logger. lggr.Errorw(fmt.Sprintf("service unavailable while sending transaction %x", tx.Hash()), "err", sendError, "etx", tx) return commonclient.Retryable } + if sendError.IsServiceTimeout(configErrors) { + lggr.Errorw(fmt.Sprintf("service timed out while sending transaction %x", tx.Hash()), "err", sendError, "etx", tx) + return commonclient.Retryable + } if sendError.IsTimeout() { lggr.Errorw(fmt.Sprintf("timeout while sending transaction %x", tx.Hash()), "err", sendError, "etx", tx) return commonclient.Retryable @@ -666,7 +677,7 @@ var drpc = ClientErrors{ // Linkpool, Blockdaemon, and Chainstack all return "request timed out" if the log results are too large for them to process var defaultClient = ClientErrors{ - TooManyResults: regexp.MustCompile(`request timed out`), + TooManyResults: regexp.MustCompile(`request timed out|408 Request Timed Out`), } // JSON-RPC error codes which can indicate a refusal of the server to process an eth_getLogs request because the result set is too large diff --git a/core/chains/evm/client/errors_test.go b/core/chains/evm/client/errors_test.go index 7bdc87840d0..1f9aaa53365 100644 --- a/core/chains/evm/client/errors_test.go +++ b/core/chains/evm/client/errors_test.go @@ -172,6 +172,7 @@ func Test_Eth_Errors(t *testing.T) { {"intrinsic gas too low", true, "Klaytn"}, {"max fee per gas less than block base fee", true, "zkSync"}, {"virtual machine entered unexpected state. please contact developers and provide transaction details that caused this error. Error description: The operator included transaction with an unacceptable gas price", true, "zkSync"}, + {"failed to validate the transaction. reason: Validation revert: virtual machine entered unexpected state. Please contact developers and provide transaction details that caused this error. Error description: Assertion error: Fair pubdata price too high", true, "zkSync"}, {"client error terminally underpriced", true, "tomlConfig"}, {"gas price less than block base fee", true, "aStar"}, {"[Request ID: e4d09e44-19a4-4eb7-babe-270db4c2ebc9] Gas price '830000000000' is below configured minimum gas price '950000000000'", true, "hedera"}, @@ -244,6 +245,7 @@ func Test_Eth_Errors(t *testing.T) { {"network is unreachable", true, "Arbitrum"}, {"client error service unavailable", true, "tomlConfig"}, {"[Request ID: 825608a8-fd8a-4b5b-aea7-92999509306d] Error invoking RPC: [Request ID: 825608a8-fd8a-4b5b-aea7-92999509306d] Transaction execution returns a null value for transaction", true, "hedera"}, + {"call failed: 503 Service Temporarily Unavailable: \r\n503 Service Temporarily Unavailable\r\n\r\n

503 Service Temporarily Unavailable

\r\n\r\n\r\n", true, "Arbitrum"}, } for _, test := range tests { err = evmclient.NewSendErrorS(test.message) @@ -259,6 +261,20 @@ func Test_Eth_Errors(t *testing.T) { } }) + t.Run("IsServiceTimeout", func(t *testing.T) { + tests := []errorCase{ + {"call failed: 408 Request Timeout: {", true, "Arbitrum"}, + {"408 Request Timeout: {\"id\":303,\"jsonrpc\":\"2.0\",\"error\":{\"code\\\":-32009,\\\"message\\\":\\\"request timeout\\\"}}\",\"errVerbose\":\"408 Request Timeout:\n", true, "Arbitrum"}, + {"request timeout", false, "tomlConfig"}, + } + for _, test := range tests { + err = evmclient.NewSendErrorS(test.message) + assert.Equal(t, err.IsServiceTimeout(clientErrors), test.expect) + err = newSendErrorWrapped(test.message) + assert.Equal(t, err.IsServiceTimeout(clientErrors), test.expect) + } + }) + t.Run("IsTxFeeExceedsCap", func(t *testing.T) { tests := []errorCase{ {"tx fee (1.10 ether) exceeds the configured cap (1.00 ether)", true, "geth"}, diff --git a/core/chains/evm/config/toml/defaults/Ronin_Mainnet.toml b/core/chains/evm/config/toml/defaults/Ronin_Mainnet.toml new file mode 100644 index 00000000000..051c528e0f3 --- /dev/null +++ b/core/chains/evm/config/toml/defaults/Ronin_Mainnet.toml @@ -0,0 +1,11 @@ +ChainID = '2020' +FinalityTagEnabled = true +# Ronin produces blocks every 3 seconds +LogPollInterval = "3s" +NoNewHeadsThreshold = "3m" +LinkContractAddress = '0x3902228D6A3d2Dc44731fD9d45FeE6a61c722D0b' + +[GasEstimator] +# Ronin uses default gas price of 20 gwei https://docs.skymavis.com/mavis/mpc/guides/estimate-gas#overview +Mode = 'FeeHistory' +PriceMax = "1000 gwei" diff --git a/core/chains/evm/config/toml/defaults/Ronin_Saigon.toml b/core/chains/evm/config/toml/defaults/Ronin_Saigon.toml new file mode 100644 index 00000000000..48695a9ec08 --- /dev/null +++ b/core/chains/evm/config/toml/defaults/Ronin_Saigon.toml @@ -0,0 +1,11 @@ +ChainID = '2021' +FinalityTagEnabled = true +# Ronin produces blocks every 3 seconds +LogPollInterval = "3s" +NoNewHeadsThreshold = "3m" +LinkContractAddress = '0x5bB50A6888ee6a67E22afFDFD9513be7740F1c15' + +[GasEstimator] +# Ronin uses default gas price of 20 gwei https://docs.skymavis.com/mavis/mpc/guides/estimate-gas#overview +Mode = 'FeeHistory' +PriceMax = "1000 gwei" diff --git a/core/chains/evm/logpoller/helper_test.go b/core/chains/evm/logpoller/helper_test.go index 947a839521c..b8d849d7d83 100644 --- a/core/chains/evm/logpoller/helper_test.go +++ b/core/chains/evm/logpoller/helper_test.go @@ -118,11 +118,19 @@ func SetupTH(t testing.TB, opts logpoller.Opts) TestHarness { opts.PollPeriod = 1 * time.Hour } lp := logpoller.NewLogPoller(o, esc, lggr, headTracker, opts) + + pendingNonce, err := backend.Client().PendingNonceAt(testutils.Context(t), owner.From) + require.NoError(t, err) + + owner.Nonce = big.NewInt(0).SetUint64(pendingNonce) emitterAddress1, _, emitter1, err := log_emitter.DeployLogEmitter(owner, backend.Client()) require.NoError(t, err) + + owner.Nonce.Add(owner.Nonce, big.NewInt(1)) // Avoid race where DeployLogEmitter returns before PendingNonce has been incremented emitterAddress2, _, emitter2, err := log_emitter.DeployLogEmitter(owner, backend.Client()) require.NoError(t, err) backend.Commit() + owner.Nonce = nil // Just use pending nonce after this return TestHarness{ Lggr: lggr, diff --git a/core/gethwrappers/ccip/deployment_test/deployment_test.go b/core/gethwrappers/ccip/deployment_test/deployment_test.go index 02f00483651..162c0df1946 100644 --- a/core/gethwrappers/ccip/deployment_test/deployment_test.go +++ b/core/gethwrappers/ccip/deployment_test/deployment_test.go @@ -41,10 +41,11 @@ func TestDeployAllV1_6(t *testing.T) { // offramp _, _, _, err = offramp.DeployOffRamp(owner, chain, offramp.OffRampStaticConfig{ - ChainSelector: 1, - RmnRemote: common.HexToAddress("0x1"), - TokenAdminRegistry: common.HexToAddress("0x2"), - NonceManager: common.HexToAddress("0x3"), + ChainSelector: 1, + GasForCallExactCheck: 5_000, + RmnRemote: common.HexToAddress("0x1"), + TokenAdminRegistry: common.HexToAddress("0x2"), + NonceManager: common.HexToAddress("0x3"), }, offramp.OffRampDynamicConfig{ FeeQuoter: common.HexToAddress("0x4"), PermissionLessExecutionThresholdSeconds: uint32((8 * time.Hour).Seconds()), diff --git a/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go index def5c4bc258..884dc9e52e5 100644 --- a/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go @@ -81,8 +81,8 @@ type TokenPoolChainUpdate struct { } var BurnFromMintTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"localTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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: "0x6101006040523480156200001257600080fd5b5060405162004c6338038062004c63833981016040819052620000359162000918565b8484848484336000816200005c57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008f576200008f8162000206565b50506001600160a01b0385161580620000af57506001600160a01b038116155b80620000c257506001600160a01b038216155b15620000e1576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808616608081905290831660c0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa92505050801562000151575060408051601f3d908101601f191682019092526200014e9181019062000a3a565b60015b1562000192578060ff168560ff161462000190576040516332ad3e0760e11b815260ff8087166004830152821660248201526044015b60405180910390fd5b505b60ff841660a052600480546001600160a01b0319166001600160a01b038316179055825115801560e052620001dc57604080516000815260208101909152620001dc908462000280565b50620001fb935050506001600160a01b038716905030600019620003dd565b505050505062000b84565b336001600160a01b038216036200023057604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e051620002a1576040516335f4a7b360e01b815260040160405180910390fd5b60005b82518110156200032c576000838281518110620002c557620002c562000a58565b60209081029190910101519050620002df600282620004c3565b1562000322576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620002a4565b5060005b8151811015620003d857600082828151811062000351576200035162000a58565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200037d5750620003cf565b6200038a600282620004e3565b15620003cd576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000330565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa1580156200042f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000455919062000a6e565b62000461919062000a9e565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b17909152919250620004bd91869190620004fa16565b50505050565b6000620004da836001600160a01b038416620005cb565b90505b92915050565b6000620004da836001600160a01b038416620006cf565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000549906001600160a01b03851690849062000721565b805190915015620003d857808060200190518101906200056a919062000ab4565b620003d85760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000187565b60008181526001830160205260408120548015620006c4576000620005f260018362000adf565b8554909150600090620006089060019062000adf565b9050808214620006745760008660000182815481106200062c576200062c62000a58565b906000526020600020015490508087600001848154811062000652576200065262000a58565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000688576200068862000af5565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620004dd565b6000915050620004dd565b60008181526001830160205260408120546200071857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620004dd565b506000620004dd565b60606200073284846000856200073a565b949350505050565b6060824710156200079d5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000187565b600080866001600160a01b03168587604051620007bb919062000b31565b60006040518083038185875af1925050503d8060008114620007fa576040519150601f19603f3d011682016040523d82523d6000602084013e620007ff565b606091505b50909250905062000813878383876200081e565b979650505050505050565b60608315620008925782516000036200088a576001600160a01b0385163b6200088a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000187565b508162000732565b620007328383815115620008a95781518083602001fd5b8060405162461bcd60e51b815260040162000187919062000b4f565b6001600160a01b0381168114620008db57600080fd5b50565b805160ff81168114620008f057600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b8051620008f081620008c5565b600080600080600060a086880312156200093157600080fd5b85516200093e81620008c5565b945060206200094f878201620008de565b60408801519095506001600160401b03808211156200096d57600080fd5b818901915089601f8301126200098257600080fd5b815181811115620009975762000997620008f5565b8060051b604051601f19603f83011681018181108582111715620009bf57620009bf620008f5565b60405291825284820192508381018501918c831115620009de57600080fd5b938501935b8285101562000a0757620009f7856200090b565b84529385019392850192620009e3565b80985050505050505062000a1e606087016200090b565b915062000a2e608087016200090b565b90509295509295909350565b60006020828403121562000a4d57600080fd5b620004da82620008de565b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000a8157600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115620004dd57620004dd62000a88565b60006020828403121562000ac757600080fd5b8151801515811462000ad857600080fd5b9392505050565b81810381811115620004dd57620004dd62000a88565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000b2857818101518382015260200162000b0e565b50506000910152565b6000825162000b4581846020870162000b0b565b9190910192915050565b602081526000825180602084015262000b7081604085016020870162000b0b565b601f01601f19169190910160400192915050565b60805160a05160c05160e05161402e62000c356000396000818161054f01528181611d8201526127d30152600081816105290152818161189f015261206e0152600081816102e001528181610ba901528181611a4801528181611b0201528181611b3601528181611b6901528181611bce01528181611c270152611cc90152600081816102470152818161029c01528181610708015281816121f10152818161276901526129be015261402e6000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639a4575b911610104578063c0d78655116100a2578063dc0bd97111610071578063dc0bd97114610527578063e0351e131461054d578063e8a1da1714610573578063f2fde38b1461058657600080fd5b8063c0d78655146104d9578063c4bffe2b146104ec578063c75eea9c14610501578063cf7401f31461051457600080fd5b8063acfecf91116100de578063acfecf9114610426578063af58d59f14610439578063b0f479a1146104a8578063b7946580146104c657600080fd5b80639a4575b9146103d1578063a42a7b8b146103f1578063a7cd63b71461041157600080fd5b806354c8a4f31161017157806379ba50971161014b57806379ba5097146103855780637d54534e1461038d5780638926f54f146103a05780638da5cb5b146103b357600080fd5b806354c8a4f31461033f57806362ddd3c4146103545780636d3d1a581461036757600080fd5b8063240028e8116101ad578063240028e81461028c57806324f65ee7146102d9578063390775371461030a5780634c5ef0ed1461032c57600080fd5b806301ffc9a7146101d4578063181f5a77146101fc57806321df0da714610245575b600080fd5b6101e76101e236600461317e565b610599565b60405190151581526020015b60405180910390f35b6102386040518060400160405280601b81526020017f4275726e46726f6d4d696e74546f6b656e506f6f6c20312e352e31000000000081525081565b6040516101f39190613224565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e761029a366004613259565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101f3565b61031d610318366004613276565b61067e565b604051905181526020016101f3565b6101e761033a3660046132cf565b61084d565b61035261034d36600461339e565b610897565b005b6103526103623660046132cf565b610912565b60095473ffffffffffffffffffffffffffffffffffffffff16610267565b6103526109af565b61035261039b366004613259565b610a7d565b6101e76103ae36600461340a565b610afe565b60015473ffffffffffffffffffffffffffffffffffffffff16610267565b6103e46103df366004613425565b610b15565b6040516101f39190613460565b6104046103ff36600461340a565b610bee565b6040516101f391906134b7565b610419610d59565b6040516101f39190613539565b6103526104343660046132cf565b610d6a565b61044c61044736600461340a565b610e82565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610267565b6102386104d436600461340a565b610f57565b6103526104e7366004613259565b611007565b6104f46110e2565b6040516101f39190613593565b61044c61050f36600461340a565b61119a565b61035261052236600461371b565b61126c565b7f0000000000000000000000000000000000000000000000000000000000000000610267565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b61035261058136600461339e565b6112f0565b610352610594366004613259565b611802565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061062c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061067857507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b60408051602081019091526000815261069682611816565b60006106ef60608401356106ea6106b060c0870187613760565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a3a92505050565b611afe565b905073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961073d6060860160408701613259565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260248101849052604401600060405180830381600087803b1580156107aa57600080fd5b505af11580156107be573d6000803e3d6000fd5b506107d3925050506060840160408501613259565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08360405161083191815260200190565b60405180910390a3604080516020810190915290815292915050565b600061088f83836040516108629291906137c5565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190611d12565b949350505050565b61089f611d2d565b61090c84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611d8092505050565b50505050565b61091a611d2d565b61092383610afe565b61096a576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6109aa8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611f3692505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a00576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610a85611d2d565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b6000610678600567ffffffffffffffff8416611d12565b6040805180820190915260608082526020820152610b3282612030565b610b3f82606001356121bc565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610b998460200160208101906104d4919061340a565b8152602001610be66040805160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260609101604051602081830303815290604052905090565b905292915050565b67ffffffffffffffff8116600090815260076020526040812060609190610c179060050161225e565b90506000815167ffffffffffffffff811115610c3557610c356135d5565b604051908082528060200260200182016040528015610c6857816020015b6060815260200190600190039081610c535790505b50905060005b8251811015610d515760086000848381518110610c8d57610c8d6137d5565b602002602001015181526020019081526020016000208054610cae90613804565b80601f0160208091040260200160405190810160405280929190818152602001828054610cda90613804565b8015610d275780601f10610cfc57610100808354040283529160200191610d27565b820191906000526020600020905b815481529060010190602001808311610d0a57829003601f168201915b5050505050828281518110610d3e57610d3e6137d5565b6020908102919091010152600101610c6e565b509392505050565b6060610d65600261225e565b905090565b610d72611d2d565b610d7b83610afe565b610dbd576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610961565b610dfd8282604051610dd09291906137c5565b604080519182900390912067ffffffffffffffff861660009081526007602052919091206005019061226b565b610e39578282826040517f74f23c7c000000000000000000000000000000000000000000000000000000008152600401610961939291906138a0565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d768383604051610e759291906138c4565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261067890612277565b67ffffffffffffffff81166000908152600760205260409020600401805460609190610f8290613804565b80601f0160208091040260200160405190810160405280929190818152602001828054610fae90613804565b8015610ffb5780601f10610fd057610100808354040283529160200191610ffb565b820191906000526020600020905b815481529060010190602001808311610fde57829003601f168201915b50505050509050919050565b61100f611d2d565b73ffffffffffffffffffffffffffffffffffffffff811661105c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006110f0600561225e565b90506000815167ffffffffffffffff81111561110e5761110e6135d5565b604051908082528060200260200182016040528015611137578160200160208202803683370190505b50905060005b825181101561119357828181518110611158576111586137d5565b6020026020010151828281518110611172576111726137d5565b67ffffffffffffffff9092166020928302919091019091015260010161113d565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261067890612277565b60095473ffffffffffffffffffffffffffffffffffffffff1633148015906112ac575060015473ffffffffffffffffffffffffffffffffffffffff163314155b156112e5576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610961565b6109aa838383612329565b6112f8611d2d565b60005b838110156114e5576000858583818110611317576113176137d5565b905060200201602081019061132c919061340a565b9050611343600567ffffffffffffffff831661226b565b611385576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610961565b67ffffffffffffffff811660009081526007602052604081206113aa9060050161225e565b905060005b81518110156114165761140d8282815181106113cd576113cd6137d5565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060050161226b90919063ffffffff16565b506001016113af565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff0000000000000000000000000000000000000000009081168255600182018390556002820180549091169055600381018290559061147f6004830182613111565b6005820160008181611491828261314b565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916945060200192506114d3915050565b60405180910390a150506001016112fb565b5060005b818110156117fb576000838383818110611505576115056137d5565b905060200281019061151791906138d8565b611520906139a4565b905061153181606001516000612413565b61154081608001516000612413565b80604001515160000361157f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516115979060059067ffffffffffffffff16612550565b6115dc5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610961565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a90910299909316171790941695909517909255909202909117600382015590820151600482019061175f9082613b1b565b5060005b8260200151518110156117a35761179b83600001518460200151838151811061178e5761178e6137d5565b6020026020010151611f36565b600101611763565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c282600001518360400151846060015185608001516040516117e99493929190613c35565b60405180910390a150506001016114e9565b5050505050565b61180a611d2d565b6118138161255c565b50565b61182961029a60a0830160808401613259565b6118885761183d60a0820160808301613259565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610961565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6118d4604084016020850161340a565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611945573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119699190613cce565b156119a0576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119b86119b3604083016020840161340a565b612620565b6119d86119cb604083016020840161340a565b61033a60a0840184613760565b611a1d576119e960a0820182613760565b6040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016109619291906138c4565b611813611a30604083016020840161340a565b8260600135612746565b60008151600003611a6c57507f0000000000000000000000000000000000000000000000000000000000000000919050565b8151602014611aa957816040517f953576f70000000000000000000000000000000000000000000000000000000081526004016109619190613224565b600082806020019051810190611abf9190613ceb565b905060ff81111561067857826040517f953576f70000000000000000000000000000000000000000000000000000000081526004016109619190613224565b60007f000000000000000000000000000000000000000000000000000000000000000060ff168260ff1603611b34575081610678565b7f000000000000000000000000000000000000000000000000000000000000000060ff168260ff161115611c1f576000611b8e7f000000000000000000000000000000000000000000000000000000000000000084613d33565b9050604d8160ff161115611c02576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f000000000000000000000000000000000000000000000000000000000000000016602482015260448101859052606401610961565b611c0d81600a613e6c565b611c179085613e7b565b915050610678565b6000611c4b837f0000000000000000000000000000000000000000000000000000000000000000613d33565b9050604d8160ff161180611c925750611c6581600a613e6c565b611c8f907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff613e7b565b84115b15611cfd576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f000000000000000000000000000000000000000000000000000000000000000016602482015260448101859052606401610961565b611d0881600a613e6c565b61088f9085613eb6565b600081815260018301602052604081205415155b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611d7e576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f0000000000000000000000000000000000000000000000000000000000000000611dd7576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611e6d576000838281518110611df757611df76137d5565b60200260200101519050611e1581600261278d90919063ffffffff16565b15611e645760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611dda565b5060005b81518110156109aa576000828281518110611e8e57611e8e6137d5565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ed25750611f2e565b611edd6002826127af565b15611f2c5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611e71565b8051600003611f71576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff8416600090815260079092526040909120611fa39060050182612550565b611fdd5782826040517f393b8ad2000000000000000000000000000000000000000000000000000000008152600401610961929190613ecd565b6000818152600860205260409020611ff58382613b1b565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea83604051610e759190613224565b61204361029a60a0830160808401613259565b6120575761183d60a0820160808301613259565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6120a3604084016020850161340a565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015612114573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121389190613cce565b1561216f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6121876121826060830160408401613259565b6127d1565b61219f61219a604083016020840161340a565b612850565b6118136121b2604083016020840161340a565b826060013561299e565b6040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906379cc679090604401600060405180830381600087803b15801561224a57600080fd5b505af11580156117fb573d6000803e3d6000fd5b60606000611d26836129e2565b6000611d268383612a3d565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261230582606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426122e99190613ef0565b85608001516fffffffffffffffffffffffffffffffff16612b30565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61233283610afe565b612374576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610961565b61237f826000612413565b67ffffffffffffffff831660009081526007602052604090206123a29083612b58565b6123ad816000612413565b67ffffffffffffffff831660009081526007602052604090206123d39060020182612b58565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161240693929190613f03565b60405180910390a1505050565b8151156124de5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612469575060408201516fffffffffffffffffffffffffffffffff16155b156124a257816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016109619190613f86565b80156124da576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580612517575060208201516fffffffffffffffffffffffffffffffff1615155b156124da57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016109619190613f86565b6000611d268383612cfa565b3373ffffffffffffffffffffffffffffffffffffffff8216036125ab576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61262981610afe565b61266b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610961565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156126ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061270e9190613cce565b611813576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610961565b67ffffffffffffffff821660009081526007602052604090206124da90600201827f0000000000000000000000000000000000000000000000000000000000000000612d49565b6000611d268373ffffffffffffffffffffffffffffffffffffffff8416612a3d565b6000611d268373ffffffffffffffffffffffffffffffffffffffff8416612cfa565b7f000000000000000000000000000000000000000000000000000000000000000015611813576128026002826130cc565b611813576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610961565b61285981610afe565b61289b576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610961565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612914573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129389190613fc2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611813576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610961565b67ffffffffffffffff821660009081526007602052604090206124da90827f0000000000000000000000000000000000000000000000000000000000000000612d49565b606081600001805480602002602001604051908101604052809291908181526020018280548015610ffb57602002820191906000526020600020905b815481526020019060010190808311612a1e5750505050509050919050565b60008181526001830160205260408120548015612b26576000612a61600183613ef0565b8554909150600090612a7590600190613ef0565b9050808214612ada576000866000018281548110612a9557612a956137d5565b9060005260206000200154905080876000018481548110612ab857612ab86137d5565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612aeb57612aeb613fdf565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610678565b6000915050610678565b6000612b4f85612b408486613eb6565b612b4a908761400e565b6130fb565b95945050505050565b8154600090612b8190700100000000000000000000000000000000900463ffffffff1642613ef0565b90508015612c235760018301548354612bc9916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612b30565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612c49916fffffffffffffffffffffffffffffffff90811691166130fb565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612406908490613f86565b6000818152600183016020526040812054612d4157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610678565b506000610678565b825474010000000000000000000000000000000000000000900460ff161580612d70575081155b15612d7a57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612dc090700100000000000000000000000000000000900463ffffffff1642613ef0565b90508015612e805781831115612e02576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612e3c9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612b30565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612f375773ffffffffffffffffffffffffffffffffffffffff8416612edf576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610961565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610961565b8483101561304a5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612f7b9082613ef0565b612f85878a613ef0565b612f8f919061400e565b612f999190613e7b565b905073ffffffffffffffffffffffffffffffffffffffff8616612ff2576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610961565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610961565b6130548584613ef0565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611d26565b600081831061310a5781611d26565b5090919050565b50805461311d90613804565b6000825580601f1061312d575050565b601f0160209004906000526020600020908101906118139190613165565b508054600082559060005260206000209081019061181391905b5b8082111561317a5760008155600101613166565b5090565b60006020828403121561319057600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611d2657600080fd5b6000815180845260005b818110156131e6576020818501810151868301820152016131ca565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611d2660208301846131c0565b73ffffffffffffffffffffffffffffffffffffffff8116811461181357600080fd5b60006020828403121561326b57600080fd5b8135611d2681613237565b60006020828403121561328857600080fd5b813567ffffffffffffffff81111561329f57600080fd5b82016101008185031215611d2657600080fd5b803567ffffffffffffffff811681146132ca57600080fd5b919050565b6000806000604084860312156132e457600080fd5b6132ed846132b2565b9250602084013567ffffffffffffffff8082111561330a57600080fd5b818601915086601f83011261331e57600080fd5b81358181111561332d57600080fd5b87602082850101111561333f57600080fd5b6020830194508093505050509250925092565b60008083601f84011261336457600080fd5b50813567ffffffffffffffff81111561337c57600080fd5b6020830191508360208260051b850101111561339757600080fd5b9250929050565b600080600080604085870312156133b457600080fd5b843567ffffffffffffffff808211156133cc57600080fd5b6133d888838901613352565b909650945060208701359150808211156133f157600080fd5b506133fe87828801613352565b95989497509550505050565b60006020828403121561341c57600080fd5b611d26826132b2565b60006020828403121561343757600080fd5b813567ffffffffffffffff81111561344e57600080fd5b820160a08185031215611d2657600080fd5b60208152600082516040602084015261347c60608401826131c0565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612b4f82826131c0565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b8281101561352c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261351a8583516131c0565b945092850192908501906001016134e0565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561358757835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613555565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561358757835167ffffffffffffffff16835292840192918401916001016135af565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715613627576136276135d5565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613674576136746135d5565b604052919050565b801515811461181357600080fd5b80356fffffffffffffffffffffffffffffffff811681146132ca57600080fd5b6000606082840312156136bc57600080fd5b6040516060810181811067ffffffffffffffff821117156136df576136df6135d5565b60405290508082356136f08161367c565b81526136fe6020840161368a565b602082015261370f6040840161368a565b60408201525092915050565b600080600060e0848603121561373057600080fd5b613739846132b2565b925061374885602086016136aa565b915061375785608086016136aa565b90509250925092565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261379557600080fd5b83018035915067ffffffffffffffff8211156137b057600080fd5b60200191503681900382131561339757600080fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c9082168061381857607f821691505b602082108103613851577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b67ffffffffffffffff84168152604060208201526000612b4f604083018486613857565b60208152600061088f602083018486613857565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee183360301811261390c57600080fd5b9190910192915050565b600082601f83011261392757600080fd5b813567ffffffffffffffff811115613941576139416135d5565b61397260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161362d565b81815284602083860101111561398757600080fd5b816020850160208301376000918101602001919091529392505050565b600061012082360312156139b757600080fd5b6139bf613604565b6139c8836132b2565b815260208084013567ffffffffffffffff808211156139e657600080fd5b9085019036601f8301126139f957600080fd5b813581811115613a0b57613a0b6135d5565b8060051b613a1a85820161362d565b9182528381018501918581019036841115613a3457600080fd5b86860192505b83831015613a7057823585811115613a525760008081fd5b613a603689838a0101613916565b8352509186019190860190613a3a565b8087890152505050506040860135925080831115613a8d57600080fd5b5050613a9b36828601613916565b604083015250613aae36606085016136aa565b6060820152613ac03660c085016136aa565b608082015292915050565b601f8211156109aa576000816000526020600020601f850160051c81016020861015613af45750805b601f850160051c820191505b81811015613b1357828155600101613b00565b505050505050565b815167ffffffffffffffff811115613b3557613b356135d5565b613b4981613b438454613804565b84613acb565b602080601f831160018114613b9c5760008415613b665750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613b13565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613be957888601518255948401946001909101908401613bca565b5085821015613c2557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613c59818401876131c0565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613c979050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612b4f565b600060208284031215613ce057600080fd5b8151611d268161367c565b600060208284031215613cfd57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff828116828216039081111561067857610678613d04565b600181815b80851115613da557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613d8b57613d8b613d04565b80851615613d9857918102915b93841c9390800290613d51565b509250929050565b600082613dbc57506001610678565b81613dc957506000610678565b8160018114613ddf5760028114613de957613e05565b6001915050610678565b60ff841115613dfa57613dfa613d04565b50506001821b610678565b5060208310610133831016604e8410600b8410161715613e28575081810a610678565b613e328383613d4c565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613e6457613e64613d04565b029392505050565b6000611d2660ff841683613dad565b600082613eb1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761067857610678613d04565b67ffffffffffffffff8316815260406020820152600061088f60408301846131c0565b8181038181111561067857610678613d04565b67ffffffffffffffff8416815260e08101613f4f60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c083015261088f565b6060810161067882848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060208284031215613fd457600080fd5b8151611d2681613237565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8082018082111561067857610678613d0456fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"localTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MismatchedArrayLengths\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectors\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config[]\",\"name\":\"outboundConfigs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config[]\",\"name\":\"inboundConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setChainRateLimiterConfigs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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: "0x6101006040523480156200001257600080fd5b5060405162004ed638038062004ed6833981016040819052620000359162000918565b8484848484336000816200005c57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008f576200008f8162000206565b50506001600160a01b0385161580620000af57506001600160a01b038116155b80620000c257506001600160a01b038216155b15620000e1576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808616608081905290831660c0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa92505050801562000151575060408051601f3d908101601f191682019092526200014e9181019062000a3a565b60015b1562000192578060ff168560ff161462000190576040516332ad3e0760e11b815260ff8087166004830152821660248201526044015b60405180910390fd5b505b60ff841660a052600480546001600160a01b0319166001600160a01b038316179055825115801560e052620001dc57604080516000815260208101909152620001dc908462000280565b50620001fb935050506001600160a01b038716905030600019620003dd565b505050505062000b84565b336001600160a01b038216036200023057604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e051620002a1576040516335f4a7b360e01b815260040160405180910390fd5b60005b82518110156200032c576000838281518110620002c557620002c562000a58565b60209081029190910101519050620002df600282620004c3565b1562000322576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620002a4565b5060005b8151811015620003d857600082828151811062000351576200035162000a58565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200037d5750620003cf565b6200038a600282620004e3565b15620003cd576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000330565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa1580156200042f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000455919062000a6e565b62000461919062000a9e565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b17909152919250620004bd91869190620004fa16565b50505050565b6000620004da836001600160a01b038416620005cb565b90505b92915050565b6000620004da836001600160a01b038416620006cf565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000549906001600160a01b03851690849062000721565b805190915015620003d857808060200190518101906200056a919062000ab4565b620003d85760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000187565b60008181526001830160205260408120548015620006c4576000620005f260018362000adf565b8554909150600090620006089060019062000adf565b9050808214620006745760008660000182815481106200062c576200062c62000a58565b906000526020600020015490508087600001848154811062000652576200065262000a58565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000688576200068862000af5565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620004dd565b6000915050620004dd565b60008181526001830160205260408120546200071857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620004dd565b506000620004dd565b60606200073284846000856200073a565b949350505050565b6060824710156200079d5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000187565b600080866001600160a01b03168587604051620007bb919062000b31565b60006040518083038185875af1925050503d8060008114620007fa576040519150601f19603f3d011682016040523d82523d6000602084013e620007ff565b606091505b50909250905062000813878383876200081e565b979650505050505050565b60608315620008925782516000036200088a576001600160a01b0385163b6200088a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000187565b508162000732565b620007328383815115620008a95781518083602001fd5b8060405162461bcd60e51b815260040162000187919062000b4f565b6001600160a01b0381168114620008db57600080fd5b50565b805160ff81168114620008f057600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b8051620008f081620008c5565b600080600080600060a086880312156200093157600080fd5b85516200093e81620008c5565b945060206200094f878201620008de565b60408801519095506001600160401b03808211156200096d57600080fd5b818901915089601f8301126200098257600080fd5b815181811115620009975762000997620008f5565b8060051b604051601f19603f83011681018181108582111715620009bf57620009bf620008f5565b60405291825284820192508381018501918c831115620009de57600080fd5b938501935b8285101562000a0757620009f7856200090b565b84529385019392850192620009e3565b80985050505050505062000a1e606087016200090b565b915062000a2e608087016200090b565b90509295509295909350565b60006020828403121562000a4d57600080fd5b620004da82620008de565b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000a8157600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115620004dd57620004dd62000a88565b60006020828403121562000ac757600080fd5b8151801515811462000ad857600080fd5b9392505050565b81810381811115620004dd57620004dd62000a88565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000b2857818101518382015260200162000b0e565b50506000910152565b6000825162000b4581846020870162000b0b565b9190910192915050565b602081526000825180602084015262000b7081604085016020870162000b0b565b601f01601f19169190910160400192915050565b60805160a05160c05160e0516142a162000c356000396000818161056d01528181611efa0152612aed01526000818161054701528181611a1701526122d00152600081816102eb01528181610d2101528181611bc001528181611c7a01528181611cae01528181611ce101528181611d4601528181611d9f0152611e41015260008181610252015281816102a70152818161072601528181612453015281816128e10152612cd801526142a16000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c80639a4575b911610104578063c0d78655116100a2578063dc0bd97111610071578063dc0bd97114610545578063e0351e131461056b578063e8a1da1714610591578063f2fde38b146105a457600080fd5b8063c0d78655146104f7578063c4bffe2b1461050a578063c75eea9c1461051f578063cf7401f31461053257600080fd5b8063acfecf91116100de578063acfecf9114610444578063af58d59f14610457578063b0f479a1146104c6578063b7946580146104e457600080fd5b80639a4575b9146103ef578063a42a7b8b1461040f578063a7cd63b71461042f57600080fd5b806354c8a4f31161017c5780637d54534e1161014b5780637d54534e146103985780638926f54f146103ab5780638da5cb5b146103be578063962d4020146103dc57600080fd5b806354c8a4f31461034a57806362ddd3c41461035f5780636d3d1a581461037257806379ba50971461039057600080fd5b8063240028e8116101b8578063240028e81461029757806324f65ee7146102e457806339077537146103155780634c5ef0ed1461033757600080fd5b806301ffc9a7146101df578063181f5a771461020757806321df0da714610250575b600080fd5b6101f26101ed3660046132f6565b6105b7565b60405190151581526020015b60405180910390f35b6102436040518060400160405280601b81526020017f4275726e46726f6d4d696e74546f6b656e506f6f6c20312e352e31000000000081525081565b6040516101fe919061339c565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101fe565b6101f26102a53660046133d1565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101fe565b6103286103233660046133ee565b61069c565b604051905181526020016101fe565b6101f2610345366004613447565b61086b565b61035d610358366004613516565b6108b5565b005b61035d61036d366004613447565b610930565b60095473ffffffffffffffffffffffffffffffffffffffff16610272565b61035d6109cd565b61035d6103a63660046133d1565b610a9b565b6101f26103b9366004613582565b610b1c565b60015473ffffffffffffffffffffffffffffffffffffffff16610272565b61035d6103ea3660046135e2565b610b33565b6104026103fd36600461367c565b610c8d565b6040516101fe91906136b7565b61042261041d366004613582565b610d66565b6040516101fe919061370e565b610437610ed1565b6040516101fe9190613790565b61035d610452366004613447565b610ee2565b61046a610465366004613582565b610ffa565b6040516101fe919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610272565b6102436104f2366004613582565b6110cf565b61035d6105053660046133d1565b61117f565b61051261125a565b6040516101fe91906137ea565b61046a61052d366004613582565b611312565b61035d610540366004613972565b6113e4565b7f0000000000000000000000000000000000000000000000000000000000000000610272565b7f00000000000000000000000000000000000000000000000000000000000000006101f2565b61035d61059f366004613516565b611468565b61035d6105b23660046133d1565b61197a565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061064a57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061069657507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b6040805160208101909152600081526106b48261198e565b600061070d60608401356107086106ce60c08701876139b7565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bb292505050565b611c76565b905073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961075b60608601604087016133d1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260248101849052604401600060405180830381600087803b1580156107c857600080fd5b505af11580156107dc573d6000803e3d6000fd5b506107f19250505060608401604085016133d1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08360405161084f91815260200190565b60405180910390a3604080516020810190915290815292915050565b60006108ad8383604051610880929190613a1c565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190611e8a565b949350505050565b6108bd611ea5565b61092a84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611ef892505050565b50505050565b610938611ea5565b61094183610b1c565b610988576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6109c88383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506120ae92505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a1e576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610aa3611ea5565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b6000610696600567ffffffffffffffff8416611e8a565b60095473ffffffffffffffffffffffffffffffffffffffff163314801590610b73575060015473ffffffffffffffffffffffffffffffffffffffff163314155b15610bac576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161097f565b8483141580610bbb5750848114155b15610bf2576040517f568efce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b85811015610c8457610c7c878783818110610c1257610c12613a2c565b9050602002016020810190610c279190613582565b868684818110610c3957610c39613a2c565b905060600201803603810190610c4f9190613a5b565b858585818110610c6157610c61613a2c565b905060600201803603810190610c779190613a5b565b6121a8565b600101610bf5565b50505050505050565b6040805180820190915260608082526020820152610caa82612292565b610cb7826060013561241e565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610d118460200160208101906104f29190613582565b8152602001610d5e6040805160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260609101604051602081830303815290604052905090565b905292915050565b67ffffffffffffffff8116600090815260076020526040812060609190610d8f906005016124c0565b90506000815167ffffffffffffffff811115610dad57610dad61382c565b604051908082528060200260200182016040528015610de057816020015b6060815260200190600190039081610dcb5790505b50905060005b8251811015610ec95760086000848381518110610e0557610e05613a2c565b602002602001015181526020019081526020016000208054610e2690613a77565b80601f0160208091040260200160405190810160405280929190818152602001828054610e5290613a77565b8015610e9f5780601f10610e7457610100808354040283529160200191610e9f565b820191906000526020600020905b815481529060010190602001808311610e8257829003601f168201915b5050505050828281518110610eb657610eb6613a2c565b6020908102919091010152600101610de6565b509392505050565b6060610edd60026124c0565b905090565b610eea611ea5565b610ef383610b1c565b610f35576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161097f565b610f758282604051610f48929190613a1c565b604080519182900390912067ffffffffffffffff86166000908152600760205291909120600501906124cd565b610fb1578282826040517f74f23c7c00000000000000000000000000000000000000000000000000000000815260040161097f93929190613b13565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d768383604051610fed929190613b37565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526003909101548084166060830152919091049091166080820152610696906124d9565b67ffffffffffffffff811660009081526007602052604090206004018054606091906110fa90613a77565b80601f016020809104026020016040519081016040528092919081815260200182805461112690613a77565b80156111735780601f1061114857610100808354040283529160200191611173565b820191906000526020600020905b81548152906001019060200180831161115657829003601f168201915b50505050509050919050565b611187611ea5565b73ffffffffffffffffffffffffffffffffffffffff81166111d4576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b6060600061126860056124c0565b90506000815167ffffffffffffffff8111156112865761128661382c565b6040519080825280602002602001820160405280156112af578160200160208202803683370190505b50905060005b825181101561130b578281815181106112d0576112d0613a2c565b60200260200101518282815181106112ea576112ea613a2c565b67ffffffffffffffff909216602092830291909101909101526001016112b5565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526001909101548084166060830152919091049091166080820152610696906124d9565b60095473ffffffffffffffffffffffffffffffffffffffff163314801590611424575060015473ffffffffffffffffffffffffffffffffffffffff163314155b1561145d576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161097f565b6109c88383836121a8565b611470611ea5565b60005b8381101561165d57600085858381811061148f5761148f613a2c565b90506020020160208101906114a49190613582565b90506114bb600567ffffffffffffffff83166124cd565b6114fd576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161097f565b67ffffffffffffffff81166000908152600760205260408120611522906005016124c0565b905060005b815181101561158e5761158582828151811061154557611545613a2c565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206005016124cd90919063ffffffff16565b50600101611527565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906115f76004830182613289565b600582016000818161160982826132c3565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169450602001925061164b915050565b60405180910390a15050600101611473565b5060005b8181101561197357600083838381811061167d5761167d613a2c565b905060200281019061168f9190613b4b565b61169890613c17565b90506116a98160600151600061258b565b6116b88160800151600061258b565b8060400151516000036116f7576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805161170f9060059067ffffffffffffffff166126c8565b6117545780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161097f565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a9091029990931617179094169590951790925590920290911760038201559082015160048201906118d79082613d8e565b5060005b82602001515181101561191b5761191383600001518460200151838151811061190657611906613a2c565b60200260200101516120ae565b6001016118db565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c282600001518360400151846060015185608001516040516119619493929190613ea8565b60405180910390a15050600101611661565b5050505050565b611982611ea5565b61198b816126d4565b50565b6119a16102a560a08301608084016133d1565b611a00576119b560a08201608083016133d1565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161097f565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb611a4c6040840160208501613582565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611abd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae19190613f41565b15611b18576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b30611b2b6040830160208401613582565b612798565b611b50611b436040830160208401613582565b61034560a08401846139b7565b611b9557611b6160a08201826139b7565b6040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161097f929190613b37565b61198b611ba86040830160208401613582565b82606001356128be565b60008151600003611be457507f0000000000000000000000000000000000000000000000000000000000000000919050565b8151602014611c2157816040517f953576f700000000000000000000000000000000000000000000000000000000815260040161097f919061339c565b600082806020019051810190611c379190613f5e565b905060ff81111561069657826040517f953576f700000000000000000000000000000000000000000000000000000000815260040161097f919061339c565b60007f000000000000000000000000000000000000000000000000000000000000000060ff168260ff1603611cac575081610696565b7f000000000000000000000000000000000000000000000000000000000000000060ff168260ff161115611d97576000611d067f000000000000000000000000000000000000000000000000000000000000000084613fa6565b9050604d8160ff161115611d7a576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044810185905260640161097f565b611d8581600a6140df565b611d8f90856140ee565b915050610696565b6000611dc3837f0000000000000000000000000000000000000000000000000000000000000000613fa6565b9050604d8160ff161180611e0a5750611ddd81600a6140df565b611e07907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6140ee565b84115b15611e75576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044810185905260640161097f565b611e8081600a6140df565b6108ad9085614129565b600081815260018301602052604081205415155b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611ef6576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f0000000000000000000000000000000000000000000000000000000000000000611f4f576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611fe5576000838281518110611f6f57611f6f613a2c565b60200260200101519050611f8d81600261290590919063ffffffff16565b15611fdc5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611f52565b5060005b81518110156109c857600082828151811061200657612006613a2c565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361204a57506120a6565b612055600282612927565b156120a45760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611fe9565b80516000036120e9576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff841660009081526007909252604090912061211b90600501826126c8565b6121555782826040517f393b8ad200000000000000000000000000000000000000000000000000000000815260040161097f929190614140565b600081815260086020526040902061216d8382613d8e565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea83604051610fed919061339c565b6121b183610b1c565b6121f3576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161097f565b6121fe82600061258b565b67ffffffffffffffff831660009081526007602052604090206122219083612949565b61222c81600061258b565b67ffffffffffffffff831660009081526007602052604090206122529060020182612949565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161228593929190614163565b60405180910390a1505050565b6122a56102a560a08301608084016133d1565b6122b9576119b560a08201608083016133d1565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6123056040840160208501613582565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015612376573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239a9190613f41565b156123d1576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123e96123e460608301604084016133d1565b612aeb565b6124016123fc6040830160208401613582565b612b6a565b61198b6124146040830160208401613582565b8260600135612cb8565b6040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906379cc679090604401600060405180830381600087803b1580156124ac57600080fd5b505af1158015611973573d6000803e3d6000fd5b60606000611e9e83612cfc565b6000611e9e8383612d57565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261256782606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261254b91906141e6565b85608001516fffffffffffffffffffffffffffffffff16612e4a565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b8151156126565781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806125e1575060408201516fffffffffffffffffffffffffffffffff16155b1561261a57816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161097f91906141f9565b8015612652576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff1615158061268f575060208201516fffffffffffffffffffffffffffffffff1615155b1561265257816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161097f91906141f9565b6000611e9e8383612e72565b3373ffffffffffffffffffffffffffffffffffffffff821603612723576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6127a181610b1c565b6127e3576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161097f565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612862573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128869190613f41565b61198b576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161097f565b67ffffffffffffffff8216600090815260076020526040902061265290600201827f0000000000000000000000000000000000000000000000000000000000000000612ec1565b6000611e9e8373ffffffffffffffffffffffffffffffffffffffff8416612d57565b6000611e9e8373ffffffffffffffffffffffffffffffffffffffff8416612e72565b815460009061297290700100000000000000000000000000000000900463ffffffff16426141e6565b90508015612a1457600183015483546129ba916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612e4a565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612a3a916fffffffffffffffffffffffffffffffff9081169116613244565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906122859084906141f9565b7f00000000000000000000000000000000000000000000000000000000000000001561198b57612b1c60028261325a565b61198b576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161097f565b612b7381610b1c565b612bb5576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161097f565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612c2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c529190614235565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461198b576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161097f565b67ffffffffffffffff8216600090815260076020526040902061265290827f0000000000000000000000000000000000000000000000000000000000000000612ec1565b60608160000180548060200260200160405190810160405280929190818152602001828054801561117357602002820191906000526020600020905b815481526020019060010190808311612d385750505050509050919050565b60008181526001830160205260408120548015612e40576000612d7b6001836141e6565b8554909150600090612d8f906001906141e6565b9050808214612df4576000866000018281548110612daf57612daf613a2c565b9060005260206000200154905080876000018481548110612dd257612dd2613a2c565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612e0557612e05614252565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610696565b6000915050610696565b6000612e6985612e5a8486614129565b612e649087614281565b613244565b95945050505050565b6000818152600183016020526040812054612eb957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610696565b506000610696565b825474010000000000000000000000000000000000000000900460ff161580612ee8575081155b15612ef257505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612f3890700100000000000000000000000000000000900463ffffffff16426141e6565b90508015612ff85781831115612f7a576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612fb49083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612e4a565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156130af5773ffffffffffffffffffffffffffffffffffffffff8416613057576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161097f565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161097f565b848310156131c25760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906130f390826141e6565b6130fd878a6141e6565b6131079190614281565b61311191906140ee565b905073ffffffffffffffffffffffffffffffffffffffff861661316a576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161097f565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161097f565b6131cc85846141e6565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60008183106132535781611e9e565b5090919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611e9e565b50805461329590613a77565b6000825580601f106132a5575050565b601f01602090049060005260206000209081019061198b91906132dd565b508054600082559060005260206000209081019061198b91905b5b808211156132f257600081556001016132de565b5090565b60006020828403121561330857600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611e9e57600080fd5b6000815180845260005b8181101561335e57602081850181015186830182015201613342565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611e9e6020830184613338565b73ffffffffffffffffffffffffffffffffffffffff8116811461198b57600080fd5b6000602082840312156133e357600080fd5b8135611e9e816133af565b60006020828403121561340057600080fd5b813567ffffffffffffffff81111561341757600080fd5b82016101008185031215611e9e57600080fd5b803567ffffffffffffffff8116811461344257600080fd5b919050565b60008060006040848603121561345c57600080fd5b6134658461342a565b9250602084013567ffffffffffffffff8082111561348257600080fd5b818601915086601f83011261349657600080fd5b8135818111156134a557600080fd5b8760208285010111156134b757600080fd5b6020830194508093505050509250925092565b60008083601f8401126134dc57600080fd5b50813567ffffffffffffffff8111156134f457600080fd5b6020830191508360208260051b850101111561350f57600080fd5b9250929050565b6000806000806040858703121561352c57600080fd5b843567ffffffffffffffff8082111561354457600080fd5b613550888389016134ca565b9096509450602087013591508082111561356957600080fd5b50613576878288016134ca565b95989497509550505050565b60006020828403121561359457600080fd5b611e9e8261342a565b60008083601f8401126135af57600080fd5b50813567ffffffffffffffff8111156135c757600080fd5b60208301915083602060608302850101111561350f57600080fd5b600080600080600080606087890312156135fb57600080fd5b863567ffffffffffffffff8082111561361357600080fd5b61361f8a838b016134ca565b9098509650602089013591508082111561363857600080fd5b6136448a838b0161359d565b9096509450604089013591508082111561365d57600080fd5b5061366a89828a0161359d565b979a9699509497509295939492505050565b60006020828403121561368e57600080fd5b813567ffffffffffffffff8111156136a557600080fd5b820160a08185031215611e9e57600080fd5b6020815260008251604060208401526136d36060840182613338565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e698282613338565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015613783577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452613771858351613338565b94509285019290850190600101613737565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b818110156137de57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016137ac565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156137de57835167ffffffffffffffff1683529284019291840191600101613806565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff8111828210171561387e5761387e61382c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156138cb576138cb61382c565b604052919050565b801515811461198b57600080fd5b80356fffffffffffffffffffffffffffffffff8116811461344257600080fd5b60006060828403121561391357600080fd5b6040516060810181811067ffffffffffffffff821117156139365761393661382c565b6040529050808235613947816138d3565b8152613955602084016138e1565b6020820152613966604084016138e1565b60408201525092915050565b600080600060e0848603121561398757600080fd5b6139908461342a565b925061399f8560208601613901565b91506139ae8560808601613901565b90509250925092565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126139ec57600080fd5b83018035915067ffffffffffffffff821115613a0757600080fd5b60200191503681900382131561350f57600080fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060608284031215613a6d57600080fd5b611e9e8383613901565b600181811c90821680613a8b57607f821691505b602082108103613ac4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b67ffffffffffffffff84168152604060208201526000612e69604083018486613aca565b6020815260006108ad602083018486613aca565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee1833603018112613b7f57600080fd5b9190910192915050565b600082601f830112613b9a57600080fd5b813567ffffffffffffffff811115613bb457613bb461382c565b613be560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613884565b818152846020838601011115613bfa57600080fd5b816020850160208301376000918101602001919091529392505050565b60006101208236031215613c2a57600080fd5b613c3261385b565b613c3b8361342a565b815260208084013567ffffffffffffffff80821115613c5957600080fd5b9085019036601f830112613c6c57600080fd5b813581811115613c7e57613c7e61382c565b8060051b613c8d858201613884565b9182528381018501918581019036841115613ca757600080fd5b86860192505b83831015613ce357823585811115613cc55760008081fd5b613cd33689838a0101613b89565b8352509186019190860190613cad565b8087890152505050506040860135925080831115613d0057600080fd5b5050613d0e36828601613b89565b604083015250613d213660608501613901565b6060820152613d333660c08501613901565b608082015292915050565b601f8211156109c8576000816000526020600020601f850160051c81016020861015613d675750805b601f850160051c820191505b81811015613d8657828155600101613d73565b505050505050565b815167ffffffffffffffff811115613da857613da861382c565b613dbc81613db68454613a77565b84613d3e565b602080601f831160018114613e0f5760008415613dd95750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613d86565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613e5c57888601518255948401946001909101908401613e3d565b5085821015613e9857878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613ecc81840187613338565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613f0a9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e69565b600060208284031215613f5357600080fd5b8151611e9e816138d3565b600060208284031215613f7057600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff828116828216039081111561069657610696613f77565b600181815b8085111561401857817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613ffe57613ffe613f77565b8085161561400b57918102915b93841c9390800290613fc4565b509250929050565b60008261402f57506001610696565b8161403c57506000610696565b8160018114614052576002811461405c57614078565b6001915050610696565b60ff84111561406d5761406d613f77565b50506001821b610696565b5060208310610133831016604e8410600b841016171561409b575081810a610696565b6140a58383613fbf565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156140d7576140d7613f77565b029392505050565b6000611e9e60ff841683614020565b600082614124577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761069657610696613f77565b67ffffffffffffffff831681526040602082015260006108ad6040830184613338565b67ffffffffffffffff8416815260e081016141af60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526108ad565b8181038181111561069657610696613f77565b6060810161069682848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561424757600080fd5b8151611e9e816133af565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8082018082111561069657610696613f7756fea164736f6c6343000818000a", } var BurnFromMintTokenPoolABI = BurnFromMintTokenPoolMetaData.ABI @@ -713,6 +713,18 @@ func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) SetChainRa return _BurnFromMintTokenPool.Contract.SetChainRateLimiterConfig(&_BurnFromMintTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) } +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _BurnFromMintTokenPool.contract.Transact(opts, "setChainRateLimiterConfigs", remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.SetChainRateLimiterConfigs(&_BurnFromMintTokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.SetChainRateLimiterConfigs(&_BurnFromMintTokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) { return _BurnFromMintTokenPool.contract.Transact(opts, "setRateLimitAdmin", rateLimitAdmin) } @@ -3033,6 +3045,8 @@ type BurnFromMintTokenPoolInterface interface { SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) + SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go index ecfad493c2c..d789ab8e3bf 100644 --- a/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go @@ -81,8 +81,8 @@ type TokenPoolChainUpdate struct { } var BurnMintTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"localTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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: "0x6101006040523480156200001257600080fd5b5060405162004809380380620048098339810160408190526200003591620005a2565b8484848484336000816200005c57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008f576200008f81620001eb565b50506001600160a01b0385161580620000af57506001600160a01b038116155b80620000c257506001600160a01b038216155b15620000e1576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808616608081905290831660c0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa92505050801562000151575060408051601f3d908101601f191682019092526200014e91810190620006c4565b60015b1562000191578060ff168560ff16146200018f576040516332ad3e0760e11b815260ff80871660048301528216602482015260440160405180910390fd5b505b60ff841660a052600480546001600160a01b0319166001600160a01b038316179055825115801560e052620001db57604080516000815260208101909152620001db908462000265565b5050505050505050505062000730565b336001600160a01b038216036200021557604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e05162000286576040516335f4a7b360e01b815260040160405180910390fd5b60005b825181101562000311576000838281518110620002aa57620002aa620006e2565b60209081029190910101519050620002c4600282620003c2565b1562000307576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000289565b5060005b8151811015620003bd576000828281518110620003365762000336620006e2565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003625750620003b4565b6200036f600282620003e2565b15620003b2576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000315565b505050565b6000620003d9836001600160a01b038416620003f9565b90505b92915050565b6000620003d9836001600160a01b038416620004fd565b60008181526001830160205260408120548015620004f257600062000420600183620006f8565b85549091506000906200043690600190620006f8565b9050808214620004a25760008660000182815481106200045a576200045a620006e2565b9060005260206000200154905080876000018481548110620004805762000480620006e2565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004b657620004b66200071a565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003dc565b6000915050620003dc565b60008181526001830160205260408120546200054657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003dc565b506000620003dc565b6001600160a01b03811681146200056557600080fd5b50565b805160ff811681146200057a57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b80516200057a816200054f565b600080600080600060a08688031215620005bb57600080fd5b8551620005c8816200054f565b94506020620005d987820162000568565b60408801519095506001600160401b0380821115620005f757600080fd5b818901915089601f8301126200060c57600080fd5b8151818111156200062157620006216200057f565b8060051b604051601f19603f830116810181811085821117156200064957620006496200057f565b60405291825284820192508381018501918c8311156200066857600080fd5b938501935b828510156200069157620006818562000595565b845293850193928501926200066d565b809850505050505050620006a86060870162000595565b9150620006b86080870162000595565b90509295509295909350565b600060208284031215620006d757600080fd5b620003d98262000568565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003dc57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e051614028620007e16000396000818161054f01528181611d8201526127cd0152600081816105290152818161189f015261206e0152600081816102e001528181610ba901528181611a4801528181611b0201528181611b3601528181611b6901528181611bce01528181611c270152611cc90152600081816102470152818161029c01528181610708015281816121eb0152818161276301526129b801526140286000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639a4575b911610104578063c0d78655116100a2578063dc0bd97111610071578063dc0bd97114610527578063e0351e131461054d578063e8a1da1714610573578063f2fde38b1461058657600080fd5b8063c0d78655146104d9578063c4bffe2b146104ec578063c75eea9c14610501578063cf7401f31461051457600080fd5b8063acfecf91116100de578063acfecf9114610426578063af58d59f14610439578063b0f479a1146104a8578063b7946580146104c657600080fd5b80639a4575b9146103d1578063a42a7b8b146103f1578063a7cd63b71461041157600080fd5b806354c8a4f31161017157806379ba50971161014b57806379ba5097146103855780637d54534e1461038d5780638926f54f146103a05780638da5cb5b146103b357600080fd5b806354c8a4f31461033f57806362ddd3c4146103545780636d3d1a581461036757600080fd5b8063240028e8116101ad578063240028e81461028c57806324f65ee7146102d9578063390775371461030a5780634c5ef0ed1461032c57600080fd5b806301ffc9a7146101d4578063181f5a77146101fc57806321df0da714610245575b600080fd5b6101e76101e2366004613178565b610599565b60405190151581526020015b60405180910390f35b6102386040518060400160405280601781526020017f4275726e4d696e74546f6b656e506f6f6c20312e352e3100000000000000000081525081565b6040516101f3919061321e565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e761029a366004613253565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101f3565b61031d610318366004613270565b61067e565b604051905181526020016101f3565b6101e761033a3660046132c9565b61084d565b61035261034d366004613398565b610897565b005b6103526103623660046132c9565b610912565b60095473ffffffffffffffffffffffffffffffffffffffff16610267565b6103526109af565b61035261039b366004613253565b610a7d565b6101e76103ae366004613404565b610afe565b60015473ffffffffffffffffffffffffffffffffffffffff16610267565b6103e46103df36600461341f565b610b15565b6040516101f3919061345a565b6104046103ff366004613404565b610bee565b6040516101f391906134b1565b610419610d59565b6040516101f39190613533565b6103526104343660046132c9565b610d6a565b61044c610447366004613404565b610e82565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610267565b6102386104d4366004613404565b610f57565b6103526104e7366004613253565b611007565b6104f46110e2565b6040516101f3919061358d565b61044c61050f366004613404565b61119a565b610352610522366004613715565b61126c565b7f0000000000000000000000000000000000000000000000000000000000000000610267565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b610352610581366004613398565b6112f0565b610352610594366004613253565b611802565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061062c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061067857507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b60408051602081019091526000815261069682611816565b60006106ef60608401356106ea6106b060c087018761375a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a3a92505050565b611afe565b905073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961073d6060860160408701613253565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260248101849052604401600060405180830381600087803b1580156107aa57600080fd5b505af11580156107be573d6000803e3d6000fd5b506107d3925050506060840160408501613253565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08360405161083191815260200190565b60405180910390a3604080516020810190915290815292915050565b600061088f83836040516108629291906137bf565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190611d12565b949350505050565b61089f611d2d565b61090c84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611d8092505050565b50505050565b61091a611d2d565b61092383610afe565b61096a576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6109aa8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611f3692505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a00576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610a85611d2d565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b6000610678600567ffffffffffffffff8416611d12565b6040805180820190915260608082526020820152610b3282612030565b610b3f82606001356121bc565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610b998460200160208101906104d49190613404565b8152602001610be66040805160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260609101604051602081830303815290604052905090565b905292915050565b67ffffffffffffffff8116600090815260076020526040812060609190610c1790600501612258565b90506000815167ffffffffffffffff811115610c3557610c356135cf565b604051908082528060200260200182016040528015610c6857816020015b6060815260200190600190039081610c535790505b50905060005b8251811015610d515760086000848381518110610c8d57610c8d6137cf565b602002602001015181526020019081526020016000208054610cae906137fe565b80601f0160208091040260200160405190810160405280929190818152602001828054610cda906137fe565b8015610d275780601f10610cfc57610100808354040283529160200191610d27565b820191906000526020600020905b815481529060010190602001808311610d0a57829003601f168201915b5050505050828281518110610d3e57610d3e6137cf565b6020908102919091010152600101610c6e565b509392505050565b6060610d656002612258565b905090565b610d72611d2d565b610d7b83610afe565b610dbd576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610961565b610dfd8282604051610dd09291906137bf565b604080519182900390912067ffffffffffffffff8616600090815260076020529190912060050190612265565b610e39578282826040517f74f23c7c0000000000000000000000000000000000000000000000000000000081526004016109619392919061389a565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d768383604051610e759291906138be565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261067890612271565b67ffffffffffffffff81166000908152600760205260409020600401805460609190610f82906137fe565b80601f0160208091040260200160405190810160405280929190818152602001828054610fae906137fe565b8015610ffb5780601f10610fd057610100808354040283529160200191610ffb565b820191906000526020600020905b815481529060010190602001808311610fde57829003601f168201915b50505050509050919050565b61100f611d2d565b73ffffffffffffffffffffffffffffffffffffffff811661105c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006110f06005612258565b90506000815167ffffffffffffffff81111561110e5761110e6135cf565b604051908082528060200260200182016040528015611137578160200160208202803683370190505b50905060005b825181101561119357828181518110611158576111586137cf565b6020026020010151828281518110611172576111726137cf565b67ffffffffffffffff9092166020928302919091019091015260010161113d565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261067890612271565b60095473ffffffffffffffffffffffffffffffffffffffff1633148015906112ac575060015473ffffffffffffffffffffffffffffffffffffffff163314155b156112e5576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610961565b6109aa838383612323565b6112f8611d2d565b60005b838110156114e5576000858583818110611317576113176137cf565b905060200201602081019061132c9190613404565b9050611343600567ffffffffffffffff8316612265565b611385576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610961565b67ffffffffffffffff811660009081526007602052604081206113aa90600501612258565b905060005b81518110156114165761140d8282815181106113cd576113cd6137cf565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060050161226590919063ffffffff16565b506001016113af565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff0000000000000000000000000000000000000000009081168255600182018390556002820180549091169055600381018290559061147f600483018261310b565b60058201600081816114918282613145565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916945060200192506114d3915050565b60405180910390a150506001016112fb565b5060005b818110156117fb576000838383818110611505576115056137cf565b905060200281019061151791906138d2565b6115209061399e565b90506115318160600151600061240d565b6115408160800151600061240d565b80604001515160000361157f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516115979060059067ffffffffffffffff1661254a565b6115dc5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610961565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a90910299909316171790941695909517909255909202909117600382015590820151600482019061175f9082613b15565b5060005b8260200151518110156117a35761179b83600001518460200151838151811061178e5761178e6137cf565b6020026020010151611f36565b600101611763565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c282600001518360400151846060015185608001516040516117e99493929190613c2f565b60405180910390a150506001016114e9565b5050505050565b61180a611d2d565b61181381612556565b50565b61182961029a60a0830160808401613253565b6118885761183d60a0820160808301613253565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610961565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6118d46040840160208501613404565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611945573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119699190613cc8565b156119a0576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119b86119b36040830160208401613404565b61261a565b6119d86119cb6040830160208401613404565b61033a60a084018461375a565b611a1d576119e960a082018261375a565b6040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016109619291906138be565b611813611a306040830160208401613404565b8260600135612740565b60008151600003611a6c57507f0000000000000000000000000000000000000000000000000000000000000000919050565b8151602014611aa957816040517f953576f7000000000000000000000000000000000000000000000000000000008152600401610961919061321e565b600082806020019051810190611abf9190613ce5565b905060ff81111561067857826040517f953576f7000000000000000000000000000000000000000000000000000000008152600401610961919061321e565b60007f000000000000000000000000000000000000000000000000000000000000000060ff168260ff1603611b34575081610678565b7f000000000000000000000000000000000000000000000000000000000000000060ff168260ff161115611c1f576000611b8e7f000000000000000000000000000000000000000000000000000000000000000084613d2d565b9050604d8160ff161115611c02576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f000000000000000000000000000000000000000000000000000000000000000016602482015260448101859052606401610961565b611c0d81600a613e66565b611c179085613e75565b915050610678565b6000611c4b837f0000000000000000000000000000000000000000000000000000000000000000613d2d565b9050604d8160ff161180611c925750611c6581600a613e66565b611c8f907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff613e75565b84115b15611cfd576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f000000000000000000000000000000000000000000000000000000000000000016602482015260448101859052606401610961565b611d0881600a613e66565b61088f9085613eb0565b600081815260018301602052604081205415155b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611d7e576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f0000000000000000000000000000000000000000000000000000000000000000611dd7576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611e6d576000838281518110611df757611df76137cf565b60200260200101519050611e1581600261278790919063ffffffff16565b15611e645760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611dda565b5060005b81518110156109aa576000828281518110611e8e57611e8e6137cf565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ed25750611f2e565b611edd6002826127a9565b15611f2c5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611e71565b8051600003611f71576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff8416600090815260079092526040909120611fa3906005018261254a565b611fdd5782826040517f393b8ad2000000000000000000000000000000000000000000000000000000008152600401610961929190613ec7565b6000818152600860205260409020611ff58382613b15565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea83604051610e75919061321e565b61204361029a60a0830160808401613253565b6120575761183d60a0820160808301613253565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6120a36040840160208501613404565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015612114573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121389190613cc8565b1561216f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6121876121826060830160408401613253565b6127cb565b61219f61219a6040830160208401613404565b61284a565b6118136121b26040830160208401613404565b8260600135612998565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b15801561224457600080fd5b505af11580156117fb573d6000803e3d6000fd5b60606000611d26836129dc565b6000611d268383612a37565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526122ff82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426122e39190613eea565b85608001516fffffffffffffffffffffffffffffffff16612b2a565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61232c83610afe565b61236e576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610961565b61237982600061240d565b67ffffffffffffffff8316600090815260076020526040902061239c9083612b52565b6123a781600061240d565b67ffffffffffffffff831660009081526007602052604090206123cd9060020182612b52565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161240093929190613efd565b60405180910390a1505050565b8151156124d85781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612463575060408201516fffffffffffffffffffffffffffffffff16155b1561249c57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016109619190613f80565b80156124d4576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580612511575060208201516fffffffffffffffffffffffffffffffff1615155b156124d457816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016109619190613f80565b6000611d268383612cf4565b3373ffffffffffffffffffffffffffffffffffffffff8216036125a5576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61262381610afe565b612665576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610961565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156126e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127089190613cc8565b611813576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610961565b67ffffffffffffffff821660009081526007602052604090206124d490600201827f0000000000000000000000000000000000000000000000000000000000000000612d43565b6000611d268373ffffffffffffffffffffffffffffffffffffffff8416612a37565b6000611d268373ffffffffffffffffffffffffffffffffffffffff8416612cf4565b7f000000000000000000000000000000000000000000000000000000000000000015611813576127fc6002826130c6565b611813576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610961565b61285381610afe565b612895576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610961565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561290e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129329190613fbc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611813576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610961565b67ffffffffffffffff821660009081526007602052604090206124d490827f0000000000000000000000000000000000000000000000000000000000000000612d43565b606081600001805480602002602001604051908101604052809291908181526020018280548015610ffb57602002820191906000526020600020905b815481526020019060010190808311612a185750505050509050919050565b60008181526001830160205260408120548015612b20576000612a5b600183613eea565b8554909150600090612a6f90600190613eea565b9050808214612ad4576000866000018281548110612a8f57612a8f6137cf565b9060005260206000200154905080876000018481548110612ab257612ab26137cf565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612ae557612ae5613fd9565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610678565b6000915050610678565b6000612b4985612b3a8486613eb0565b612b449087614008565b6130f5565b95945050505050565b8154600090612b7b90700100000000000000000000000000000000900463ffffffff1642613eea565b90508015612c1d5760018301548354612bc3916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612b2a565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612c43916fffffffffffffffffffffffffffffffff90811691166130f5565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612400908490613f80565b6000818152600183016020526040812054612d3b57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610678565b506000610678565b825474010000000000000000000000000000000000000000900460ff161580612d6a575081155b15612d7457505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612dba90700100000000000000000000000000000000900463ffffffff1642613eea565b90508015612e7a5781831115612dfc576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612e369083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612b2a565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612f315773ffffffffffffffffffffffffffffffffffffffff8416612ed9576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610961565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610961565b848310156130445760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612f759082613eea565b612f7f878a613eea565b612f899190614008565b612f939190613e75565b905073ffffffffffffffffffffffffffffffffffffffff8616612fec576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610961565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610961565b61304e8584613eea565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611d26565b60008183106131045781611d26565b5090919050565b508054613117906137fe565b6000825580601f10613127575050565b601f016020900490600052602060002090810190611813919061315f565b508054600082559060005260206000209081019061181391905b5b808211156131745760008155600101613160565b5090565b60006020828403121561318a57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611d2657600080fd5b6000815180845260005b818110156131e0576020818501810151868301820152016131c4565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611d2660208301846131ba565b73ffffffffffffffffffffffffffffffffffffffff8116811461181357600080fd5b60006020828403121561326557600080fd5b8135611d2681613231565b60006020828403121561328257600080fd5b813567ffffffffffffffff81111561329957600080fd5b82016101008185031215611d2657600080fd5b803567ffffffffffffffff811681146132c457600080fd5b919050565b6000806000604084860312156132de57600080fd5b6132e7846132ac565b9250602084013567ffffffffffffffff8082111561330457600080fd5b818601915086601f83011261331857600080fd5b81358181111561332757600080fd5b87602082850101111561333957600080fd5b6020830194508093505050509250925092565b60008083601f84011261335e57600080fd5b50813567ffffffffffffffff81111561337657600080fd5b6020830191508360208260051b850101111561339157600080fd5b9250929050565b600080600080604085870312156133ae57600080fd5b843567ffffffffffffffff808211156133c657600080fd5b6133d28883890161334c565b909650945060208701359150808211156133eb57600080fd5b506133f88782880161334c565b95989497509550505050565b60006020828403121561341657600080fd5b611d26826132ac565b60006020828403121561343157600080fd5b813567ffffffffffffffff81111561344857600080fd5b820160a08185031215611d2657600080fd5b60208152600082516040602084015261347660608401826131ba565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612b4982826131ba565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015613526577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526135148583516131ba565b945092850192908501906001016134da565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561358157835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161354f565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561358157835167ffffffffffffffff16835292840192918401916001016135a9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715613621576136216135cf565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561366e5761366e6135cf565b604052919050565b801515811461181357600080fd5b80356fffffffffffffffffffffffffffffffff811681146132c457600080fd5b6000606082840312156136b657600080fd5b6040516060810181811067ffffffffffffffff821117156136d9576136d96135cf565b60405290508082356136ea81613676565b81526136f860208401613684565b602082015261370960408401613684565b60408201525092915050565b600080600060e0848603121561372a57600080fd5b613733846132ac565b925061374285602086016136a4565b915061375185608086016136a4565b90509250925092565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261378f57600080fd5b83018035915067ffffffffffffffff8211156137aa57600080fd5b60200191503681900382131561339157600080fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c9082168061381257607f821691505b60208210810361384b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b67ffffffffffffffff84168152604060208201526000612b49604083018486613851565b60208152600061088f602083018486613851565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee183360301811261390657600080fd5b9190910192915050565b600082601f83011261392157600080fd5b813567ffffffffffffffff81111561393b5761393b6135cf565b61396c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613627565b81815284602083860101111561398157600080fd5b816020850160208301376000918101602001919091529392505050565b600061012082360312156139b157600080fd5b6139b96135fe565b6139c2836132ac565b815260208084013567ffffffffffffffff808211156139e057600080fd5b9085019036601f8301126139f357600080fd5b813581811115613a0557613a056135cf565b8060051b613a14858201613627565b9182528381018501918581019036841115613a2e57600080fd5b86860192505b83831015613a6a57823585811115613a4c5760008081fd5b613a5a3689838a0101613910565b8352509186019190860190613a34565b8087890152505050506040860135925080831115613a8757600080fd5b5050613a9536828601613910565b604083015250613aa836606085016136a4565b6060820152613aba3660c085016136a4565b608082015292915050565b601f8211156109aa576000816000526020600020601f850160051c81016020861015613aee5750805b601f850160051c820191505b81811015613b0d57828155600101613afa565b505050505050565b815167ffffffffffffffff811115613b2f57613b2f6135cf565b613b4381613b3d84546137fe565b84613ac5565b602080601f831160018114613b965760008415613b605750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613b0d565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613be357888601518255948401946001909101908401613bc4565b5085821015613c1f57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613c53818401876131ba565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613c919050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612b49565b600060208284031215613cda57600080fd5b8151611d2681613676565b600060208284031215613cf757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff828116828216039081111561067857610678613cfe565b600181815b80851115613d9f57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613d8557613d85613cfe565b80851615613d9257918102915b93841c9390800290613d4b565b509250929050565b600082613db657506001610678565b81613dc357506000610678565b8160018114613dd95760028114613de357613dff565b6001915050610678565b60ff841115613df457613df4613cfe565b50506001821b610678565b5060208310610133831016604e8410600b8410161715613e22575081810a610678565b613e2c8383613d46565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613e5e57613e5e613cfe565b029392505050565b6000611d2660ff841683613da7565b600082613eab577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761067857610678613cfe565b67ffffffffffffffff8316815260406020820152600061088f60408301846131ba565b8181038181111561067857610678613cfe565b67ffffffffffffffff8416815260e08101613f4960208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c083015261088f565b6060810161067882848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060208284031215613fce57600080fd5b8151611d2681613231565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8082018082111561067857610678613cfe56fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"localTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MismatchedArrayLengths\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectors\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config[]\",\"name\":\"outboundConfigs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config[]\",\"name\":\"inboundConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setChainRateLimiterConfigs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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: "0x6101006040523480156200001257600080fd5b5060405162004a7c38038062004a7c8339810160408190526200003591620005a2565b8484848484336000816200005c57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008f576200008f81620001eb565b50506001600160a01b0385161580620000af57506001600160a01b038116155b80620000c257506001600160a01b038216155b15620000e1576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808616608081905290831660c0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa92505050801562000151575060408051601f3d908101601f191682019092526200014e91810190620006c4565b60015b1562000191578060ff168560ff16146200018f576040516332ad3e0760e11b815260ff80871660048301528216602482015260440160405180910390fd5b505b60ff841660a052600480546001600160a01b0319166001600160a01b038316179055825115801560e052620001db57604080516000815260208101909152620001db908462000265565b5050505050505050505062000730565b336001600160a01b038216036200021557604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e05162000286576040516335f4a7b360e01b815260040160405180910390fd5b60005b825181101562000311576000838281518110620002aa57620002aa620006e2565b60209081029190910101519050620002c4600282620003c2565b1562000307576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000289565b5060005b8151811015620003bd576000828281518110620003365762000336620006e2565b6020026020010151905060006001600160a01b0316816001600160a01b031603620003625750620003b4565b6200036f600282620003e2565b15620003b2576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000315565b505050565b6000620003d9836001600160a01b038416620003f9565b90505b92915050565b6000620003d9836001600160a01b038416620004fd565b60008181526001830160205260408120548015620004f257600062000420600183620006f8565b85549091506000906200043690600190620006f8565b9050808214620004a25760008660000182815481106200045a576200045a620006e2565b9060005260206000200154905080876000018481548110620004805762000480620006e2565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004b657620004b66200071a565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003dc565b6000915050620003dc565b60008181526001830160205260408120546200054657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003dc565b506000620003dc565b6001600160a01b03811681146200056557600080fd5b50565b805160ff811681146200057a57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b80516200057a816200054f565b600080600080600060a08688031215620005bb57600080fd5b8551620005c8816200054f565b94506020620005d987820162000568565b60408801519095506001600160401b0380821115620005f757600080fd5b818901915089601f8301126200060c57600080fd5b8151818111156200062157620006216200057f565b8060051b604051601f19603f830116810181811085821117156200064957620006496200057f565b60405291825284820192508381018501918c8311156200066857600080fd5b938501935b828510156200069157620006818562000595565b845293850193928501926200066d565b809850505050505050620006a86060870162000595565b9150620006b86080870162000595565b90509295509295909350565b600060208284031215620006d757600080fd5b620003d98262000568565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003dc57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e05161429b620007e16000396000818161056d01528181611efa0152612ae701526000818161054701528181611a1701526122d00152600081816102eb01528181610d2101528181611bc001528181611c7a01528181611cae01528181611ce101528181611d4601528181611d9f0152611e41015260008181610252015281816102a7015281816107260152818161244d015281816128db0152612cd2015261429b6000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c80639a4575b911610104578063c0d78655116100a2578063dc0bd97111610071578063dc0bd97114610545578063e0351e131461056b578063e8a1da1714610591578063f2fde38b146105a457600080fd5b8063c0d78655146104f7578063c4bffe2b1461050a578063c75eea9c1461051f578063cf7401f31461053257600080fd5b8063acfecf91116100de578063acfecf9114610444578063af58d59f14610457578063b0f479a1146104c6578063b7946580146104e457600080fd5b80639a4575b9146103ef578063a42a7b8b1461040f578063a7cd63b71461042f57600080fd5b806354c8a4f31161017c5780637d54534e1161014b5780637d54534e146103985780638926f54f146103ab5780638da5cb5b146103be578063962d4020146103dc57600080fd5b806354c8a4f31461034a57806362ddd3c41461035f5780636d3d1a581461037257806379ba50971461039057600080fd5b8063240028e8116101b8578063240028e81461029757806324f65ee7146102e457806339077537146103155780634c5ef0ed1461033757600080fd5b806301ffc9a7146101df578063181f5a771461020757806321df0da714610250575b600080fd5b6101f26101ed3660046132f0565b6105b7565b60405190151581526020015b60405180910390f35b6102436040518060400160405280601781526020017f4275726e4d696e74546f6b656e506f6f6c20312e352e3100000000000000000081525081565b6040516101fe9190613396565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101fe565b6101f26102a53660046133cb565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101fe565b6103286103233660046133e8565b61069c565b604051905181526020016101fe565b6101f2610345366004613441565b61086b565b61035d610358366004613510565b6108b5565b005b61035d61036d366004613441565b610930565b60095473ffffffffffffffffffffffffffffffffffffffff16610272565b61035d6109cd565b61035d6103a63660046133cb565b610a9b565b6101f26103b936600461357c565b610b1c565b60015473ffffffffffffffffffffffffffffffffffffffff16610272565b61035d6103ea3660046135dc565b610b33565b6104026103fd366004613676565b610c8d565b6040516101fe91906136b1565b61042261041d36600461357c565b610d66565b6040516101fe9190613708565b610437610ed1565b6040516101fe919061378a565b61035d610452366004613441565b610ee2565b61046a61046536600461357c565b610ffa565b6040516101fe919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610272565b6102436104f236600461357c565b6110cf565b61035d6105053660046133cb565b61117f565b61051261125a565b6040516101fe91906137e4565b61046a61052d36600461357c565b611312565b61035d61054036600461396c565b6113e4565b7f0000000000000000000000000000000000000000000000000000000000000000610272565b7f00000000000000000000000000000000000000000000000000000000000000006101f2565b61035d61059f366004613510565b611468565b61035d6105b23660046133cb565b61197a565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061064a57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061069657507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b6040805160208101909152600081526106b48261198e565b600061070d60608401356107086106ce60c08701876139b1565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bb292505050565b611c76565b905073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961075b60608601604087016133cb565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260248101849052604401600060405180830381600087803b1580156107c857600080fd5b505af11580156107dc573d6000803e3d6000fd5b506107f19250505060608401604085016133cb565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08360405161084f91815260200190565b60405180910390a3604080516020810190915290815292915050565b60006108ad8383604051610880929190613a16565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190611e8a565b949350505050565b6108bd611ea5565b61092a84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611ef892505050565b50505050565b610938611ea5565b61094183610b1c565b610988576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6109c88383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506120ae92505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a1e576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610aa3611ea5565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b6000610696600567ffffffffffffffff8416611e8a565b60095473ffffffffffffffffffffffffffffffffffffffff163314801590610b73575060015473ffffffffffffffffffffffffffffffffffffffff163314155b15610bac576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161097f565b8483141580610bbb5750848114155b15610bf2576040517f568efce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b85811015610c8457610c7c878783818110610c1257610c12613a26565b9050602002016020810190610c27919061357c565b868684818110610c3957610c39613a26565b905060600201803603810190610c4f9190613a55565b858585818110610c6157610c61613a26565b905060600201803603810190610c779190613a55565b6121a8565b600101610bf5565b50505050505050565b6040805180820190915260608082526020820152610caa82612292565b610cb7826060013561241e565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610d118460200160208101906104f2919061357c565b8152602001610d5e6040805160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260609101604051602081830303815290604052905090565b905292915050565b67ffffffffffffffff8116600090815260076020526040812060609190610d8f906005016124ba565b90506000815167ffffffffffffffff811115610dad57610dad613826565b604051908082528060200260200182016040528015610de057816020015b6060815260200190600190039081610dcb5790505b50905060005b8251811015610ec95760086000848381518110610e0557610e05613a26565b602002602001015181526020019081526020016000208054610e2690613a71565b80601f0160208091040260200160405190810160405280929190818152602001828054610e5290613a71565b8015610e9f5780601f10610e7457610100808354040283529160200191610e9f565b820191906000526020600020905b815481529060010190602001808311610e8257829003601f168201915b5050505050828281518110610eb657610eb6613a26565b6020908102919091010152600101610de6565b509392505050565b6060610edd60026124ba565b905090565b610eea611ea5565b610ef383610b1c565b610f35576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161097f565b610f758282604051610f48929190613a16565b604080519182900390912067ffffffffffffffff86166000908152600760205291909120600501906124c7565b610fb1578282826040517f74f23c7c00000000000000000000000000000000000000000000000000000000815260040161097f93929190613b0d565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d768383604051610fed929190613b31565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526003909101548084166060830152919091049091166080820152610696906124d3565b67ffffffffffffffff811660009081526007602052604090206004018054606091906110fa90613a71565b80601f016020809104026020016040519081016040528092919081815260200182805461112690613a71565b80156111735780601f1061114857610100808354040283529160200191611173565b820191906000526020600020905b81548152906001019060200180831161115657829003601f168201915b50505050509050919050565b611187611ea5565b73ffffffffffffffffffffffffffffffffffffffff81166111d4576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b6060600061126860056124ba565b90506000815167ffffffffffffffff81111561128657611286613826565b6040519080825280602002602001820160405280156112af578160200160208202803683370190505b50905060005b825181101561130b578281815181106112d0576112d0613a26565b60200260200101518282815181106112ea576112ea613a26565b67ffffffffffffffff909216602092830291909101909101526001016112b5565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526001909101548084166060830152919091049091166080820152610696906124d3565b60095473ffffffffffffffffffffffffffffffffffffffff163314801590611424575060015473ffffffffffffffffffffffffffffffffffffffff163314155b1561145d576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161097f565b6109c88383836121a8565b611470611ea5565b60005b8381101561165d57600085858381811061148f5761148f613a26565b90506020020160208101906114a4919061357c565b90506114bb600567ffffffffffffffff83166124c7565b6114fd576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161097f565b67ffffffffffffffff81166000908152600760205260408120611522906005016124ba565b905060005b815181101561158e5761158582828151811061154557611545613a26565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206005016124c790919063ffffffff16565b50600101611527565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906115f76004830182613283565b600582016000818161160982826132bd565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169450602001925061164b915050565b60405180910390a15050600101611473565b5060005b8181101561197357600083838381811061167d5761167d613a26565b905060200281019061168f9190613b45565b61169890613c11565b90506116a981606001516000612585565b6116b881608001516000612585565b8060400151516000036116f7576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805161170f9060059067ffffffffffffffff166126c2565b6117545780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161097f565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a9091029990931617179094169590951790925590920290911760038201559082015160048201906118d79082613d88565b5060005b82602001515181101561191b5761191383600001518460200151838151811061190657611906613a26565b60200260200101516120ae565b6001016118db565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c282600001518360400151846060015185608001516040516119619493929190613ea2565b60405180910390a15050600101611661565b5050505050565b611982611ea5565b61198b816126ce565b50565b6119a16102a560a08301608084016133cb565b611a00576119b560a08201608083016133cb565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161097f565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb611a4c604084016020850161357c565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611abd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae19190613f3b565b15611b18576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b30611b2b604083016020840161357c565b612792565b611b50611b43604083016020840161357c565b61034560a08401846139b1565b611b9557611b6160a08201826139b1565b6040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161097f929190613b31565b61198b611ba8604083016020840161357c565b82606001356128b8565b60008151600003611be457507f0000000000000000000000000000000000000000000000000000000000000000919050565b8151602014611c2157816040517f953576f700000000000000000000000000000000000000000000000000000000815260040161097f9190613396565b600082806020019051810190611c379190613f58565b905060ff81111561069657826040517f953576f700000000000000000000000000000000000000000000000000000000815260040161097f9190613396565b60007f000000000000000000000000000000000000000000000000000000000000000060ff168260ff1603611cac575081610696565b7f000000000000000000000000000000000000000000000000000000000000000060ff168260ff161115611d97576000611d067f000000000000000000000000000000000000000000000000000000000000000084613fa0565b9050604d8160ff161115611d7a576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044810185905260640161097f565b611d8581600a6140d9565b611d8f90856140e8565b915050610696565b6000611dc3837f0000000000000000000000000000000000000000000000000000000000000000613fa0565b9050604d8160ff161180611e0a5750611ddd81600a6140d9565b611e07907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6140e8565b84115b15611e75576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044810185905260640161097f565b611e8081600a6140d9565b6108ad9085614123565b600081815260018301602052604081205415155b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611ef6576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f0000000000000000000000000000000000000000000000000000000000000000611f4f576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611fe5576000838281518110611f6f57611f6f613a26565b60200260200101519050611f8d8160026128ff90919063ffffffff16565b15611fdc5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611f52565b5060005b81518110156109c857600082828151811061200657612006613a26565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361204a57506120a6565b612055600282612921565b156120a45760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611fe9565b80516000036120e9576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff841660009081526007909252604090912061211b90600501826126c2565b6121555782826040517f393b8ad200000000000000000000000000000000000000000000000000000000815260040161097f92919061413a565b600081815260086020526040902061216d8382613d88565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea83604051610fed9190613396565b6121b183610b1c565b6121f3576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161097f565b6121fe826000612585565b67ffffffffffffffff831660009081526007602052604090206122219083612943565b61222c816000612585565b67ffffffffffffffff831660009081526007602052604090206122529060020182612943565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516122859392919061415d565b60405180910390a1505050565b6122a56102a560a08301608084016133cb565b6122b9576119b560a08201608083016133cb565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb612305604084016020850161357c565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015612376573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239a9190613f3b565b156123d1576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123e96123e460608301604084016133cb565b612ae5565b6124016123fc604083016020840161357c565b612b64565b61198b612414604083016020840161357c565b8260600135612cb2565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b1580156124a657600080fd5b505af1158015611973573d6000803e3d6000fd5b60606000611e9e83612cf6565b6000611e9e8383612d51565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261256182606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261254591906141e0565b85608001516fffffffffffffffffffffffffffffffff16612e44565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b8151156126505781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806125db575060408201516fffffffffffffffffffffffffffffffff16155b1561261457816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161097f91906141f3565b801561264c576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580612689575060208201516fffffffffffffffffffffffffffffffff1615155b1561264c57816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161097f91906141f3565b6000611e9e8383612e6c565b3373ffffffffffffffffffffffffffffffffffffffff82160361271d576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61279b81610b1c565b6127dd576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161097f565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561285c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128809190613f3b565b61198b576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161097f565b67ffffffffffffffff8216600090815260076020526040902061264c90600201827f0000000000000000000000000000000000000000000000000000000000000000612ebb565b6000611e9e8373ffffffffffffffffffffffffffffffffffffffff8416612d51565b6000611e9e8373ffffffffffffffffffffffffffffffffffffffff8416612e6c565b815460009061296c90700100000000000000000000000000000000900463ffffffff16426141e0565b90508015612a0e57600183015483546129b4916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612e44565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612a34916fffffffffffffffffffffffffffffffff908116911661323e565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906122859084906141f3565b7f00000000000000000000000000000000000000000000000000000000000000001561198b57612b16600282613254565b61198b576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161097f565b612b6d81610b1c565b612baf576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161097f565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612c28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c4c919061422f565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461198b576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161097f565b67ffffffffffffffff8216600090815260076020526040902061264c90827f0000000000000000000000000000000000000000000000000000000000000000612ebb565b60608160000180548060200260200160405190810160405280929190818152602001828054801561117357602002820191906000526020600020905b815481526020019060010190808311612d325750505050509050919050565b60008181526001830160205260408120548015612e3a576000612d756001836141e0565b8554909150600090612d89906001906141e0565b9050808214612dee576000866000018281548110612da957612da9613a26565b9060005260206000200154905080876000018481548110612dcc57612dcc613a26565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612dff57612dff61424c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610696565b6000915050610696565b6000612e6385612e548486614123565b612e5e908761427b565b61323e565b95945050505050565b6000818152600183016020526040812054612eb357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610696565b506000610696565b825474010000000000000000000000000000000000000000900460ff161580612ee2575081155b15612eec57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612f3290700100000000000000000000000000000000900463ffffffff16426141e0565b90508015612ff25781831115612f74576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612fae9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612e44565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156130a95773ffffffffffffffffffffffffffffffffffffffff8416613051576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161097f565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161097f565b848310156131bc5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906130ed90826141e0565b6130f7878a6141e0565b613101919061427b565b61310b91906140e8565b905073ffffffffffffffffffffffffffffffffffffffff8616613164576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161097f565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161097f565b6131c685846141e0565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b600081831061324d5781611e9e565b5090919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611e9e565b50805461328f90613a71565b6000825580601f1061329f575050565b601f01602090049060005260206000209081019061198b91906132d7565b508054600082559060005260206000209081019061198b91905b5b808211156132ec57600081556001016132d8565b5090565b60006020828403121561330257600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611e9e57600080fd5b6000815180845260005b818110156133585760208185018101518683018201520161333c565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611e9e6020830184613332565b73ffffffffffffffffffffffffffffffffffffffff8116811461198b57600080fd5b6000602082840312156133dd57600080fd5b8135611e9e816133a9565b6000602082840312156133fa57600080fd5b813567ffffffffffffffff81111561341157600080fd5b82016101008185031215611e9e57600080fd5b803567ffffffffffffffff8116811461343c57600080fd5b919050565b60008060006040848603121561345657600080fd5b61345f84613424565b9250602084013567ffffffffffffffff8082111561347c57600080fd5b818601915086601f83011261349057600080fd5b81358181111561349f57600080fd5b8760208285010111156134b157600080fd5b6020830194508093505050509250925092565b60008083601f8401126134d657600080fd5b50813567ffffffffffffffff8111156134ee57600080fd5b6020830191508360208260051b850101111561350957600080fd5b9250929050565b6000806000806040858703121561352657600080fd5b843567ffffffffffffffff8082111561353e57600080fd5b61354a888389016134c4565b9096509450602087013591508082111561356357600080fd5b50613570878288016134c4565b95989497509550505050565b60006020828403121561358e57600080fd5b611e9e82613424565b60008083601f8401126135a957600080fd5b50813567ffffffffffffffff8111156135c157600080fd5b60208301915083602060608302850101111561350957600080fd5b600080600080600080606087890312156135f557600080fd5b863567ffffffffffffffff8082111561360d57600080fd5b6136198a838b016134c4565b9098509650602089013591508082111561363257600080fd5b61363e8a838b01613597565b9096509450604089013591508082111561365757600080fd5b5061366489828a01613597565b979a9699509497509295939492505050565b60006020828403121561368857600080fd5b813567ffffffffffffffff81111561369f57600080fd5b820160a08185031215611e9e57600080fd5b6020815260008251604060208401526136cd6060840182613332565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e638282613332565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b8281101561377d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261376b858351613332565b94509285019290850190600101613731565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b818110156137d857835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016137a6565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156137d857835167ffffffffffffffff1683529284019291840191600101613800565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff8111828210171561387857613878613826565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156138c5576138c5613826565b604052919050565b801515811461198b57600080fd5b80356fffffffffffffffffffffffffffffffff8116811461343c57600080fd5b60006060828403121561390d57600080fd5b6040516060810181811067ffffffffffffffff8211171561393057613930613826565b6040529050808235613941816138cd565b815261394f602084016138db565b6020820152613960604084016138db565b60408201525092915050565b600080600060e0848603121561398157600080fd5b61398a84613424565b925061399985602086016138fb565b91506139a885608086016138fb565b90509250925092565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126139e657600080fd5b83018035915067ffffffffffffffff821115613a0157600080fd5b60200191503681900382131561350957600080fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060608284031215613a6757600080fd5b611e9e83836138fb565b600181811c90821680613a8557607f821691505b602082108103613abe577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b67ffffffffffffffff84168152604060208201526000612e63604083018486613ac4565b6020815260006108ad602083018486613ac4565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee1833603018112613b7957600080fd5b9190910192915050565b600082601f830112613b9457600080fd5b813567ffffffffffffffff811115613bae57613bae613826565b613bdf60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161387e565b818152846020838601011115613bf457600080fd5b816020850160208301376000918101602001919091529392505050565b60006101208236031215613c2457600080fd5b613c2c613855565b613c3583613424565b815260208084013567ffffffffffffffff80821115613c5357600080fd5b9085019036601f830112613c6657600080fd5b813581811115613c7857613c78613826565b8060051b613c8785820161387e565b9182528381018501918581019036841115613ca157600080fd5b86860192505b83831015613cdd57823585811115613cbf5760008081fd5b613ccd3689838a0101613b83565b8352509186019190860190613ca7565b8087890152505050506040860135925080831115613cfa57600080fd5b5050613d0836828601613b83565b604083015250613d1b36606085016138fb565b6060820152613d2d3660c085016138fb565b608082015292915050565b601f8211156109c8576000816000526020600020601f850160051c81016020861015613d615750805b601f850160051c820191505b81811015613d8057828155600101613d6d565b505050505050565b815167ffffffffffffffff811115613da257613da2613826565b613db681613db08454613a71565b84613d38565b602080601f831160018114613e095760008415613dd35750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613d80565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613e5657888601518255948401946001909101908401613e37565b5085821015613e9257878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613ec681840187613332565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613f049050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e63565b600060208284031215613f4d57600080fd5b8151611e9e816138cd565b600060208284031215613f6a57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff828116828216039081111561069657610696613f71565b600181815b8085111561401257817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613ff857613ff8613f71565b8085161561400557918102915b93841c9390800290613fbe565b509250929050565b60008261402957506001610696565b8161403657506000610696565b816001811461404c576002811461405657614072565b6001915050610696565b60ff84111561406757614067613f71565b50506001821b610696565b5060208310610133831016604e8410600b8410161715614095575081810a610696565b61409f8383613fb9565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156140d1576140d1613f71565b029392505050565b6000611e9e60ff84168361401a565b60008261411e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761069657610696613f71565b67ffffffffffffffff831681526040602082015260006108ad6040830184613332565b67ffffffffffffffff8416815260e081016141a960208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526108ad565b8181038181111561069657610696613f71565b6060810161069682848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561424157600080fd5b8151611e9e816133a9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8082018082111561069657610696613f7156fea164736f6c6343000818000a", } var BurnMintTokenPoolABI = BurnMintTokenPoolMetaData.ABI @@ -713,6 +713,18 @@ func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) SetChainRateLimite return _BurnMintTokenPool.Contract.SetChainRateLimiterConfig(&_BurnMintTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) } +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "setChainRateLimiterConfigs", remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.SetChainRateLimiterConfigs(&_BurnMintTokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.SetChainRateLimiterConfigs(&_BurnMintTokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) { return _BurnMintTokenPool.contract.Transact(opts, "setRateLimitAdmin", rateLimitAdmin) } @@ -3033,6 +3045,8 @@ type BurnMintTokenPoolInterface interface { SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) + SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go index 7315989c076..46f233948ce 100644 --- a/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go @@ -81,8 +81,8 @@ type TokenPoolChainUpdate struct { } var BurnWithFromMintTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"localTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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\":\"pure\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b5060405162004c5c38038062004c5c833981016040819052620000359162000918565b8484848484336000816200005c57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008f576200008f8162000206565b50506001600160a01b0385161580620000af57506001600160a01b038116155b80620000c257506001600160a01b038216155b15620000e1576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808616608081905290831660c0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa92505050801562000151575060408051601f3d908101601f191682019092526200014e9181019062000a3a565b60015b1562000192578060ff168560ff161462000190576040516332ad3e0760e11b815260ff8087166004830152821660248201526044015b60405180910390fd5b505b60ff841660a052600480546001600160a01b0319166001600160a01b038316179055825115801560e052620001dc57604080516000815260208101909152620001dc908462000280565b50620001fb935050506001600160a01b038716905030600019620003dd565b505050505062000b84565b336001600160a01b038216036200023057604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e051620002a1576040516335f4a7b360e01b815260040160405180910390fd5b60005b82518110156200032c576000838281518110620002c557620002c562000a58565b60209081029190910101519050620002df600282620004c3565b1562000322576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620002a4565b5060005b8151811015620003d857600082828151811062000351576200035162000a58565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200037d5750620003cf565b6200038a600282620004e3565b15620003cd576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000330565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa1580156200042f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000455919062000a6e565b62000461919062000a9e565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b17909152919250620004bd91869190620004fa16565b50505050565b6000620004da836001600160a01b038416620005cb565b90505b92915050565b6000620004da836001600160a01b038416620006cf565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000549906001600160a01b03851690849062000721565b805190915015620003d857808060200190518101906200056a919062000ab4565b620003d85760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000187565b60008181526001830160205260408120548015620006c4576000620005f260018362000adf565b8554909150600090620006089060019062000adf565b9050808214620006745760008660000182815481106200062c576200062c62000a58565b906000526020600020015490508087600001848154811062000652576200065262000a58565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000688576200068862000af5565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620004dd565b6000915050620004dd565b60008181526001830160205260408120546200071857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620004dd565b506000620004dd565b60606200073284846000856200073a565b949350505050565b6060824710156200079d5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000187565b600080866001600160a01b03168587604051620007bb919062000b31565b60006040518083038185875af1925050503d8060008114620007fa576040519150601f19603f3d011682016040523d82523d6000602084013e620007ff565b606091505b50909250905062000813878383876200081e565b979650505050505050565b60608315620008925782516000036200088a576001600160a01b0385163b6200088a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000187565b508162000732565b620007328383815115620008a95781518083602001fd5b8060405162461bcd60e51b815260040162000187919062000b4f565b6001600160a01b0381168114620008db57600080fd5b50565b805160ff81168114620008f057600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b8051620008f081620008c5565b600080600080600060a086880312156200093157600080fd5b85516200093e81620008c5565b945060206200094f878201620008de565b60408801519095506001600160401b03808211156200096d57600080fd5b818901915089601f8301126200098257600080fd5b815181811115620009975762000997620008f5565b8060051b604051601f19603f83011681018181108582111715620009bf57620009bf620008f5565b60405291825284820192508381018501918c831115620009de57600080fd5b938501935b8285101562000a0757620009f7856200090b565b84529385019392850192620009e3565b80985050505050505062000a1e606087016200090b565b915062000a2e608087016200090b565b90509295509295909350565b60006020828403121562000a4d57600080fd5b620004da82620008de565b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000a8157600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115620004dd57620004dd62000a88565b60006020828403121562000ac757600080fd5b8151801515811462000ad857600080fd5b9392505050565b81810381811115620004dd57620004dd62000a88565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000b2857818101518382015260200162000b0e565b50506000910152565b6000825162000b4581846020870162000b0b565b9190910192915050565b602081526000825180602084015262000b7081604085016020870162000b0b565b601f01601f19169190910160400192915050565b60805160a05160c05160e05161402762000c356000396000818161054801528181611d7b01526127cc0152600081816105220152818161189801526120670152600081816102d901528181610ba201528181611a4101528181611afb01528181611b2f01528181611b6201528181611bc701528181611c200152611cc20152600081816102400152818161029501528181610701015281816121ea0152818161276201526129b701526140276000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639a4575b911610104578063c0d78655116100a2578063dc0bd97111610071578063dc0bd97114610520578063e0351e1314610546578063e8a1da171461056c578063f2fde38b1461057f57600080fd5b8063c0d78655146104d2578063c4bffe2b146104e5578063c75eea9c146104fa578063cf7401f31461050d57600080fd5b8063acfecf91116100de578063acfecf911461041f578063af58d59f14610432578063b0f479a1146104a1578063b7946580146104bf57600080fd5b80639a4575b9146103ca578063a42a7b8b146103ea578063a7cd63b71461040a57600080fd5b806354c8a4f31161017157806379ba50971161014b57806379ba50971461037e5780637d54534e146103865780638926f54f146103995780638da5cb5b146103ac57600080fd5b806354c8a4f31461033857806362ddd3c41461034d5780636d3d1a581461036057600080fd5b8063240028e8116101ad578063240028e81461028557806324f65ee7146102d257806339077537146103035780634c5ef0ed1461032557600080fd5b806301ffc9a7146101d4578063181f5a77146101fc57806321df0da71461023e575b600080fd5b6101e76101e2366004613177565b610592565b60405190151581526020015b60405180910390f35b60408051808201909152601f81527f4275726e5769746846726f6d4d696e74546f6b656e506f6f6c20312e352e310060208201525b6040516101f3919061321d565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e7610293366004613252565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101f3565b61031661031136600461326f565b610677565b604051905181526020016101f3565b6101e76103333660046132c8565b610846565b61034b610346366004613397565b610890565b005b61034b61035b3660046132c8565b61090b565b60095473ffffffffffffffffffffffffffffffffffffffff16610260565b61034b6109a8565b61034b610394366004613252565b610a76565b6101e76103a7366004613403565b610af7565b60015473ffffffffffffffffffffffffffffffffffffffff16610260565b6103dd6103d836600461341e565b610b0e565b6040516101f39190613459565b6103fd6103f8366004613403565b610be7565b6040516101f391906134b0565b610412610d52565b6040516101f39190613532565b61034b61042d3660046132c8565b610d63565b610445610440366004613403565b610e7b565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610260565b6102316104cd366004613403565b610f50565b61034b6104e0366004613252565b611000565b6104ed6110db565b6040516101f3919061358c565b610445610508366004613403565b611193565b61034b61051b366004613714565b611265565b7f0000000000000000000000000000000000000000000000000000000000000000610260565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b61034b61057a366004613397565b6112e9565b61034b61058d366004613252565b6117fb565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061062557507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061067157507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b60408051602081019091526000815261068f8261180f565b60006106e860608401356106e36106a960c0870187613759565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a3392505050565b611af7565b905073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196107366060860160408701613252565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260248101849052604401600060405180830381600087803b1580156107a357600080fd5b505af11580156107b7573d6000803e3d6000fd5b506107cc925050506060840160408501613252565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08360405161082a91815260200190565b60405180910390a3604080516020810190915290815292915050565b6000610888838360405161085b9291906137be565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190611d0b565b949350505050565b610898611d26565b61090584848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611d7992505050565b50505050565b610913611d26565b61091c83610af7565b610963576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6109a38383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611f2f92505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146109f9576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610a7e611d26565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b6000610671600567ffffffffffffffff8416611d0b565b6040805180820190915260608082526020820152610b2b82612029565b610b3882606001356121b5565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610b928460200160208101906104cd9190613403565b8152602001610bdf6040805160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260609101604051602081830303815290604052905090565b905292915050565b67ffffffffffffffff8116600090815260076020526040812060609190610c1090600501612257565b90506000815167ffffffffffffffff811115610c2e57610c2e6135ce565b604051908082528060200260200182016040528015610c6157816020015b6060815260200190600190039081610c4c5790505b50905060005b8251811015610d4a5760086000848381518110610c8657610c866137ce565b602002602001015181526020019081526020016000208054610ca7906137fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd3906137fd565b8015610d205780601f10610cf557610100808354040283529160200191610d20565b820191906000526020600020905b815481529060010190602001808311610d0357829003601f168201915b5050505050828281518110610d3757610d376137ce565b6020908102919091010152600101610c67565b509392505050565b6060610d5e6002612257565b905090565b610d6b611d26565b610d7483610af7565b610db6576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161095a565b610df68282604051610dc99291906137be565b604080519182900390912067ffffffffffffffff8616600090815260076020529190912060050190612264565b610e32578282826040517f74f23c7c00000000000000000000000000000000000000000000000000000000815260040161095a93929190613899565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d768383604051610e6e9291906138bd565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261067190612270565b67ffffffffffffffff81166000908152600760205260409020600401805460609190610f7b906137fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610fa7906137fd565b8015610ff45780601f10610fc957610100808354040283529160200191610ff4565b820191906000526020600020905b815481529060010190602001808311610fd757829003601f168201915b50505050509050919050565b611008611d26565b73ffffffffffffffffffffffffffffffffffffffff8116611055576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006110e96005612257565b90506000815167ffffffffffffffff811115611107576111076135ce565b604051908082528060200260200182016040528015611130578160200160208202803683370190505b50905060005b825181101561118c57828181518110611151576111516137ce565b602002602001015182828151811061116b5761116b6137ce565b67ffffffffffffffff90921660209283029190910190910152600101611136565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261067190612270565b60095473ffffffffffffffffffffffffffffffffffffffff1633148015906112a5575060015473ffffffffffffffffffffffffffffffffffffffff163314155b156112de576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161095a565b6109a3838383612322565b6112f1611d26565b60005b838110156114de576000858583818110611310576113106137ce565b90506020020160208101906113259190613403565b905061133c600567ffffffffffffffff8316612264565b61137e576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161095a565b67ffffffffffffffff811660009081526007602052604081206113a390600501612257565b905060005b815181101561140f576114068282815181106113c6576113c66137ce565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060050161226490919063ffffffff16565b506001016113a8565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff00000000000000000000000000000000000000000090811682556001820183905560028201805490911690556003810182905590611478600483018261310a565b600582016000818161148a8282613144565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916945060200192506114cc915050565b60405180910390a150506001016112f4565b5060005b818110156117f45760008383838181106114fe576114fe6137ce565b905060200281019061151091906138d1565b6115199061399d565b905061152a8160600151600061240c565b6115398160800151600061240c565b806040015151600003611578576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516115909060059067ffffffffffffffff16612549565b6115d55780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161095a565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a9091029990931617179094169590951790925590920290911760038201559082015160048201906117589082613b14565b5060005b82602001515181101561179c57611794836000015184602001518381518110611787576117876137ce565b6020026020010151611f2f565b60010161175c565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c282600001518360400151846060015185608001516040516117e29493929190613c2e565b60405180910390a150506001016114e2565b5050505050565b611803611d26565b61180c81612555565b50565b61182261029360a0830160808401613252565b6118815761183660a0820160808301613252565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161095a565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6118cd6040840160208501613403565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa15801561193e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119629190613cc7565b15611999576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119b16119ac6040830160208401613403565b612619565b6119d16119c46040830160208401613403565b61033360a0840184613759565b611a16576119e260a0820182613759565b6040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161095a9291906138bd565b61180c611a296040830160208401613403565b826060013561273f565b60008151600003611a6557507f0000000000000000000000000000000000000000000000000000000000000000919050565b8151602014611aa257816040517f953576f700000000000000000000000000000000000000000000000000000000815260040161095a919061321d565b600082806020019051810190611ab89190613ce4565b905060ff81111561067157826040517f953576f700000000000000000000000000000000000000000000000000000000815260040161095a919061321d565b60007f000000000000000000000000000000000000000000000000000000000000000060ff168260ff1603611b2d575081610671565b7f000000000000000000000000000000000000000000000000000000000000000060ff168260ff161115611c18576000611b877f000000000000000000000000000000000000000000000000000000000000000084613d2c565b9050604d8160ff161115611bfb576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044810185905260640161095a565b611c0681600a613e65565b611c109085613e74565b915050610671565b6000611c44837f0000000000000000000000000000000000000000000000000000000000000000613d2c565b9050604d8160ff161180611c8b5750611c5e81600a613e65565b611c88907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff613e74565b84115b15611cf6576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044810185905260640161095a565b611d0181600a613e65565b6108889085613eaf565b600081815260018301602052604081205415155b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611d77576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f0000000000000000000000000000000000000000000000000000000000000000611dd0576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611e66576000838281518110611df057611df06137ce565b60200260200101519050611e0e81600261278690919063ffffffff16565b15611e5d5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611dd3565b5060005b81518110156109a3576000828281518110611e8757611e876137ce565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ecb5750611f27565b611ed66002826127a8565b15611f255760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611e6a565b8051600003611f6a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff8416600090815260079092526040909120611f9c9060050182612549565b611fd65782826040517f393b8ad200000000000000000000000000000000000000000000000000000000815260040161095a929190613ec6565b6000818152600860205260409020611fee8382613b14565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea83604051610e6e919061321d565b61203c61029360a0830160808401613252565b6120505761183660a0820160808301613252565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb61209c6040840160208501613403565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa15801561210d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121319190613cc7565b15612168576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61218061217b6060830160408401613252565b6127ca565b6121986121936040830160208401613403565b612849565b61180c6121ab6040830160208401613403565b8260600135612997565b6040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639dc29fac90604401600060405180830381600087803b15801561224357600080fd5b505af11580156117f4573d6000803e3d6000fd5b60606000611d1f836129db565b6000611d1f8383612a36565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526122fe82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426122e29190613ee9565b85608001516fffffffffffffffffffffffffffffffff16612b29565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61232b83610af7565b61236d576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161095a565b61237882600061240c565b67ffffffffffffffff8316600090815260076020526040902061239b9083612b51565b6123a681600061240c565b67ffffffffffffffff831660009081526007602052604090206123cc9060020182612b51565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516123ff93929190613efc565b60405180910390a1505050565b8151156124d75781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612462575060408201516fffffffffffffffffffffffffffffffff16155b1561249b57816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161095a9190613f7f565b80156124d3576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580612510575060208201516fffffffffffffffffffffffffffffffff1615155b156124d357816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161095a9190613f7f565b6000611d1f8383612cf3565b3373ffffffffffffffffffffffffffffffffffffffff8216036125a4576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61262281610af7565b612664576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161095a565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156126e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127079190613cc7565b61180c576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161095a565b67ffffffffffffffff821660009081526007602052604090206124d390600201827f0000000000000000000000000000000000000000000000000000000000000000612d42565b6000611d1f8373ffffffffffffffffffffffffffffffffffffffff8416612a36565b6000611d1f8373ffffffffffffffffffffffffffffffffffffffff8416612cf3565b7f00000000000000000000000000000000000000000000000000000000000000001561180c576127fb6002826130c5565b61180c576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161095a565b61285281610af7565b612894576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161095a565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561290d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129319190613fbb565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461180c576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161095a565b67ffffffffffffffff821660009081526007602052604090206124d390827f0000000000000000000000000000000000000000000000000000000000000000612d42565b606081600001805480602002602001604051908101604052809291908181526020018280548015610ff457602002820191906000526020600020905b815481526020019060010190808311612a175750505050509050919050565b60008181526001830160205260408120548015612b1f576000612a5a600183613ee9565b8554909150600090612a6e90600190613ee9565b9050808214612ad3576000866000018281548110612a8e57612a8e6137ce565b9060005260206000200154905080876000018481548110612ab157612ab16137ce565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612ae457612ae4613fd8565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610671565b6000915050610671565b6000612b4885612b398486613eaf565b612b439087614007565b6130f4565b95945050505050565b8154600090612b7a90700100000000000000000000000000000000900463ffffffff1642613ee9565b90508015612c1c5760018301548354612bc2916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612b29565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612c42916fffffffffffffffffffffffffffffffff90811691166130f4565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906123ff908490613f7f565b6000818152600183016020526040812054612d3a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610671565b506000610671565b825474010000000000000000000000000000000000000000900460ff161580612d69575081155b15612d7357505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612db990700100000000000000000000000000000000900463ffffffff1642613ee9565b90508015612e795781831115612dfb576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612e359083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612b29565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612f305773ffffffffffffffffffffffffffffffffffffffff8416612ed8576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161095a565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161095a565b848310156130435760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612f749082613ee9565b612f7e878a613ee9565b612f889190614007565b612f929190613e74565b905073ffffffffffffffffffffffffffffffffffffffff8616612feb576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161095a565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161095a565b61304d8584613ee9565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611d1f565b60008183106131035781611d1f565b5090919050565b508054613116906137fd565b6000825580601f10613126575050565b601f01602090049060005260206000209081019061180c919061315e565b508054600082559060005260206000209081019061180c91905b5b80821115613173576000815560010161315f565b5090565b60006020828403121561318957600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611d1f57600080fd5b6000815180845260005b818110156131df576020818501810151868301820152016131c3565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611d1f60208301846131b9565b73ffffffffffffffffffffffffffffffffffffffff8116811461180c57600080fd5b60006020828403121561326457600080fd5b8135611d1f81613230565b60006020828403121561328157600080fd5b813567ffffffffffffffff81111561329857600080fd5b82016101008185031215611d1f57600080fd5b803567ffffffffffffffff811681146132c357600080fd5b919050565b6000806000604084860312156132dd57600080fd5b6132e6846132ab565b9250602084013567ffffffffffffffff8082111561330357600080fd5b818601915086601f83011261331757600080fd5b81358181111561332657600080fd5b87602082850101111561333857600080fd5b6020830194508093505050509250925092565b60008083601f84011261335d57600080fd5b50813567ffffffffffffffff81111561337557600080fd5b6020830191508360208260051b850101111561339057600080fd5b9250929050565b600080600080604085870312156133ad57600080fd5b843567ffffffffffffffff808211156133c557600080fd5b6133d18883890161334b565b909650945060208701359150808211156133ea57600080fd5b506133f78782880161334b565b95989497509550505050565b60006020828403121561341557600080fd5b611d1f826132ab565b60006020828403121561343057600080fd5b813567ffffffffffffffff81111561344757600080fd5b820160a08185031215611d1f57600080fd5b60208152600082516040602084015261347560608401826131b9565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612b4882826131b9565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015613525577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526135138583516131b9565b945092850192908501906001016134d9565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561358057835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161354e565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561358057835167ffffffffffffffff16835292840192918401916001016135a8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715613620576136206135ce565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561366d5761366d6135ce565b604052919050565b801515811461180c57600080fd5b80356fffffffffffffffffffffffffffffffff811681146132c357600080fd5b6000606082840312156136b557600080fd5b6040516060810181811067ffffffffffffffff821117156136d8576136d86135ce565b60405290508082356136e981613675565b81526136f760208401613683565b602082015261370860408401613683565b60408201525092915050565b600080600060e0848603121561372957600080fd5b613732846132ab565b925061374185602086016136a3565b915061375085608086016136a3565b90509250925092565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261378e57600080fd5b83018035915067ffffffffffffffff8211156137a957600080fd5b60200191503681900382131561339057600080fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c9082168061381157607f821691505b60208210810361384a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b67ffffffffffffffff84168152604060208201526000612b48604083018486613850565b602081526000610888602083018486613850565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee183360301811261390557600080fd5b9190910192915050565b600082601f83011261392057600080fd5b813567ffffffffffffffff81111561393a5761393a6135ce565b61396b60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613626565b81815284602083860101111561398057600080fd5b816020850160208301376000918101602001919091529392505050565b600061012082360312156139b057600080fd5b6139b86135fd565b6139c1836132ab565b815260208084013567ffffffffffffffff808211156139df57600080fd5b9085019036601f8301126139f257600080fd5b813581811115613a0457613a046135ce565b8060051b613a13858201613626565b9182528381018501918581019036841115613a2d57600080fd5b86860192505b83831015613a6957823585811115613a4b5760008081fd5b613a593689838a010161390f565b8352509186019190860190613a33565b8087890152505050506040860135925080831115613a8657600080fd5b5050613a943682860161390f565b604083015250613aa736606085016136a3565b6060820152613ab93660c085016136a3565b608082015292915050565b601f8211156109a3576000816000526020600020601f850160051c81016020861015613aed5750805b601f850160051c820191505b81811015613b0c57828155600101613af9565b505050505050565b815167ffffffffffffffff811115613b2e57613b2e6135ce565b613b4281613b3c84546137fd565b84613ac4565b602080601f831160018114613b955760008415613b5f5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613b0c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613be257888601518255948401946001909101908401613bc3565b5085821015613c1e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613c52818401876131b9565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613c909050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612b48565b600060208284031215613cd957600080fd5b8151611d1f81613675565b600060208284031215613cf657600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff828116828216039081111561067157610671613cfd565b600181815b80851115613d9e57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613d8457613d84613cfd565b80851615613d9157918102915b93841c9390800290613d4a565b509250929050565b600082613db557506001610671565b81613dc257506000610671565b8160018114613dd85760028114613de257613dfe565b6001915050610671565b60ff841115613df357613df3613cfd565b50506001821b610671565b5060208310610133831016604e8410600b8410161715613e21575081810a610671565b613e2b8383613d45565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613e5d57613e5d613cfd565b029392505050565b6000611d1f60ff841683613da6565b600082613eaa577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761067157610671613cfd565b67ffffffffffffffff8316815260406020820152600061088860408301846131b9565b8181038181111561067157610671613cfd565b67ffffffffffffffff8416815260e08101613f4860208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152610888565b6060810161067182848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060208284031215613fcd57600080fd5b8151611d1f81613230565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8082018082111561067157610671613cfd56fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"localTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MismatchedArrayLengths\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectors\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config[]\",\"name\":\"outboundConfigs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config[]\",\"name\":\"inboundConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setChainRateLimiterConfigs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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\":\"pure\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b5060405162004ecf38038062004ecf833981016040819052620000359162000918565b8484848484336000816200005c57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008f576200008f8162000206565b50506001600160a01b0385161580620000af57506001600160a01b038116155b80620000c257506001600160a01b038216155b15620000e1576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808616608081905290831660c0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa92505050801562000151575060408051601f3d908101601f191682019092526200014e9181019062000a3a565b60015b1562000192578060ff168560ff161462000190576040516332ad3e0760e11b815260ff8087166004830152821660248201526044015b60405180910390fd5b505b60ff841660a052600480546001600160a01b0319166001600160a01b038316179055825115801560e052620001dc57604080516000815260208101909152620001dc908462000280565b50620001fb935050506001600160a01b038716905030600019620003dd565b505050505062000b84565b336001600160a01b038216036200023057604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e051620002a1576040516335f4a7b360e01b815260040160405180910390fd5b60005b82518110156200032c576000838281518110620002c557620002c562000a58565b60209081029190910101519050620002df600282620004c3565b1562000322576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620002a4565b5060005b8151811015620003d857600082828151811062000351576200035162000a58565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200037d5750620003cf565b6200038a600282620004e3565b15620003cd576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000330565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa1580156200042f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000455919062000a6e565b62000461919062000a9e565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b17909152919250620004bd91869190620004fa16565b50505050565b6000620004da836001600160a01b038416620005cb565b90505b92915050565b6000620004da836001600160a01b038416620006cf565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000549906001600160a01b03851690849062000721565b805190915015620003d857808060200190518101906200056a919062000ab4565b620003d85760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000187565b60008181526001830160205260408120548015620006c4576000620005f260018362000adf565b8554909150600090620006089060019062000adf565b9050808214620006745760008660000182815481106200062c576200062c62000a58565b906000526020600020015490508087600001848154811062000652576200065262000a58565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000688576200068862000af5565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620004dd565b6000915050620004dd565b60008181526001830160205260408120546200071857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620004dd565b506000620004dd565b60606200073284846000856200073a565b949350505050565b6060824710156200079d5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000187565b600080866001600160a01b03168587604051620007bb919062000b31565b60006040518083038185875af1925050503d8060008114620007fa576040519150601f19603f3d011682016040523d82523d6000602084013e620007ff565b606091505b50909250905062000813878383876200081e565b979650505050505050565b60608315620008925782516000036200088a576001600160a01b0385163b6200088a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000187565b508162000732565b620007328383815115620008a95781518083602001fd5b8060405162461bcd60e51b815260040162000187919062000b4f565b6001600160a01b0381168114620008db57600080fd5b50565b805160ff81168114620008f057600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b8051620008f081620008c5565b600080600080600060a086880312156200093157600080fd5b85516200093e81620008c5565b945060206200094f878201620008de565b60408801519095506001600160401b03808211156200096d57600080fd5b818901915089601f8301126200098257600080fd5b815181811115620009975762000997620008f5565b8060051b604051601f19603f83011681018181108582111715620009bf57620009bf620008f5565b60405291825284820192508381018501918c831115620009de57600080fd5b938501935b8285101562000a0757620009f7856200090b565b84529385019392850192620009e3565b80985050505050505062000a1e606087016200090b565b915062000a2e608087016200090b565b90509295509295909350565b60006020828403121562000a4d57600080fd5b620004da82620008de565b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000a8157600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115620004dd57620004dd62000a88565b60006020828403121562000ac757600080fd5b8151801515811462000ad857600080fd5b9392505050565b81810381811115620004dd57620004dd62000a88565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000b2857818101518382015260200162000b0e565b50506000910152565b6000825162000b4581846020870162000b0b565b9190910192915050565b602081526000825180602084015262000b7081604085016020870162000b0b565b601f01601f19169190910160400192915050565b60805160a05160c05160e05161429a62000c356000396000818161056601528181611ef30152612ae601526000818161054001528181611a1001526122c90152600081816102e401528181610d1a01528181611bb901528181611c7301528181611ca701528181611cda01528181611d3f01528181611d980152611e3a01526000818161024b015281816102a00152818161071f0152818161244c015281816128da0152612cd1015261429a6000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c80639a4575b911610104578063c0d78655116100a2578063dc0bd97111610071578063dc0bd9711461053e578063e0351e1314610564578063e8a1da171461058a578063f2fde38b1461059d57600080fd5b8063c0d78655146104f0578063c4bffe2b14610503578063c75eea9c14610518578063cf7401f31461052b57600080fd5b8063acfecf91116100de578063acfecf911461043d578063af58d59f14610450578063b0f479a1146104bf578063b7946580146104dd57600080fd5b80639a4575b9146103e8578063a42a7b8b14610408578063a7cd63b71461042857600080fd5b806354c8a4f31161017c5780637d54534e1161014b5780637d54534e146103915780638926f54f146103a45780638da5cb5b146103b7578063962d4020146103d557600080fd5b806354c8a4f31461034357806362ddd3c4146103585780636d3d1a581461036b57806379ba50971461038957600080fd5b8063240028e8116101b8578063240028e81461029057806324f65ee7146102dd578063390775371461030e5780634c5ef0ed1461033057600080fd5b806301ffc9a7146101df578063181f5a771461020757806321df0da714610249575b600080fd5b6101f26101ed3660046132ef565b6105b0565b60405190151581526020015b60405180910390f35b60408051808201909152601f81527f4275726e5769746846726f6d4d696e74546f6b656e506f6f6c20312e352e310060208201525b6040516101fe9190613395565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101fe565b6101f261029e3660046133ca565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101fe565b61032161031c3660046133e7565b610695565b604051905181526020016101fe565b6101f261033e366004613440565b610864565b61035661035136600461350f565b6108ae565b005b610356610366366004613440565b610929565b60095473ffffffffffffffffffffffffffffffffffffffff1661026b565b6103566109c6565b61035661039f3660046133ca565b610a94565b6101f26103b236600461357b565b610b15565b60015473ffffffffffffffffffffffffffffffffffffffff1661026b565b6103566103e33660046135db565b610b2c565b6103fb6103f6366004613675565b610c86565b6040516101fe91906136b0565b61041b61041636600461357b565b610d5f565b6040516101fe9190613707565b610430610eca565b6040516101fe9190613789565b61035661044b366004613440565b610edb565b61046361045e36600461357b565b610ff3565b6040516101fe919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff1661026b565b61023c6104eb36600461357b565b6110c8565b6103566104fe3660046133ca565b611178565b61050b611253565b6040516101fe91906137e3565b61046361052636600461357b565b61130b565b61035661053936600461396b565b6113dd565b7f000000000000000000000000000000000000000000000000000000000000000061026b565b7f00000000000000000000000000000000000000000000000000000000000000006101f2565b61035661059836600461350f565b611461565b6103566105ab3660046133ca565b611973565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061064357507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061068f57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b6040805160208101909152600081526106ad82611987565b600061070660608401356107016106c760c08701876139b0565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bab92505050565b611c6f565b905073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961075460608601604087016133ca565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260248101849052604401600060405180830381600087803b1580156107c157600080fd5b505af11580156107d5573d6000803e3d6000fd5b506107ea9250505060608401604085016133ca565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08360405161084891815260200190565b60405180910390a3604080516020810190915290815292915050565b60006108a68383604051610879929190613a15565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190611e83565b949350505050565b6108b6611e9e565b61092384848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611ef192505050565b50505050565b610931611e9e565b61093a83610b15565b610981576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6109c18383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506120a792505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a17576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610a9c611e9e565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b600061068f600567ffffffffffffffff8416611e83565b60095473ffffffffffffffffffffffffffffffffffffffff163314801590610b6c575060015473ffffffffffffffffffffffffffffffffffffffff163314155b15610ba5576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610978565b8483141580610bb45750848114155b15610beb576040517f568efce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b85811015610c7d57610c75878783818110610c0b57610c0b613a25565b9050602002016020810190610c20919061357b565b868684818110610c3257610c32613a25565b905060600201803603810190610c489190613a54565b858585818110610c5a57610c5a613a25565b905060600201803603810190610c709190613a54565b6121a1565b600101610bee565b50505050505050565b6040805180820190915260608082526020820152610ca38261228b565b610cb08260600135612417565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610d0a8460200160208101906104eb919061357b565b8152602001610d576040805160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260609101604051602081830303815290604052905090565b905292915050565b67ffffffffffffffff8116600090815260076020526040812060609190610d88906005016124b9565b90506000815167ffffffffffffffff811115610da657610da6613825565b604051908082528060200260200182016040528015610dd957816020015b6060815260200190600190039081610dc45790505b50905060005b8251811015610ec25760086000848381518110610dfe57610dfe613a25565b602002602001015181526020019081526020016000208054610e1f90613a70565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4b90613a70565b8015610e985780601f10610e6d57610100808354040283529160200191610e98565b820191906000526020600020905b815481529060010190602001808311610e7b57829003601f168201915b5050505050828281518110610eaf57610eaf613a25565b6020908102919091010152600101610ddf565b509392505050565b6060610ed660026124b9565b905090565b610ee3611e9e565b610eec83610b15565b610f2e576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610978565b610f6e8282604051610f41929190613a15565b604080519182900390912067ffffffffffffffff86166000908152600760205291909120600501906124c6565b610faa578282826040517f74f23c7c00000000000000000000000000000000000000000000000000000000815260040161097893929190613b0c565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d768383604051610fe6929190613b30565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261068f906124d2565b67ffffffffffffffff811660009081526007602052604090206004018054606091906110f390613a70565b80601f016020809104026020016040519081016040528092919081815260200182805461111f90613a70565b801561116c5780601f106111415761010080835404028352916020019161116c565b820191906000526020600020905b81548152906001019060200180831161114f57829003601f168201915b50505050509050919050565b611180611e9e565b73ffffffffffffffffffffffffffffffffffffffff81166111cd576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b6060600061126160056124b9565b90506000815167ffffffffffffffff81111561127f5761127f613825565b6040519080825280602002602001820160405280156112a8578160200160208202803683370190505b50905060005b8251811015611304578281815181106112c9576112c9613a25565b60200260200101518282815181106112e3576112e3613a25565b67ffffffffffffffff909216602092830291909101909101526001016112ae565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261068f906124d2565b60095473ffffffffffffffffffffffffffffffffffffffff16331480159061141d575060015473ffffffffffffffffffffffffffffffffffffffff163314155b15611456576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610978565b6109c18383836121a1565b611469611e9e565b60005b8381101561165657600085858381811061148857611488613a25565b905060200201602081019061149d919061357b565b90506114b4600567ffffffffffffffff83166124c6565b6114f6576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610978565b67ffffffffffffffff8116600090815260076020526040812061151b906005016124b9565b905060005b81518110156115875761157e82828151811061153e5761153e613a25565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206005016124c690919063ffffffff16565b50600101611520565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906115f06004830182613282565b600582016000818161160282826132bc565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d85991694506020019250611644915050565b60405180910390a1505060010161146c565b5060005b8181101561196c57600083838381811061167657611676613a25565b90506020028101906116889190613b44565b61169190613c10565b90506116a281606001516000612584565b6116b181608001516000612584565b8060400151516000036116f0576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516117089060059067ffffffffffffffff166126c1565b61174d5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610978565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a9091029990931617179094169590951790925590920290911760038201559082015160048201906118d09082613d87565b5060005b8260200151518110156119145761190c8360000151846020015183815181106118ff576118ff613a25565b60200260200101516120a7565b6001016118d4565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2826000015183604001518460600151856080015160405161195a9493929190613ea1565b60405180910390a1505060010161165a565b5050505050565b61197b611e9e565b611984816126cd565b50565b61199a61029e60a08301608084016133ca565b6119f9576119ae60a08201608083016133ca565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610978565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb611a45604084016020850161357b565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611ab6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ada9190613f3a565b15611b11576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b29611b24604083016020840161357b565b612791565b611b49611b3c604083016020840161357b565b61033e60a08401846139b0565b611b8e57611b5a60a08201826139b0565b6040517f24eb47e5000000000000000000000000000000000000000000000000000000008152600401610978929190613b30565b611984611ba1604083016020840161357b565b82606001356128b7565b60008151600003611bdd57507f0000000000000000000000000000000000000000000000000000000000000000919050565b8151602014611c1a57816040517f953576f70000000000000000000000000000000000000000000000000000000081526004016109789190613395565b600082806020019051810190611c309190613f57565b905060ff81111561068f57826040517f953576f70000000000000000000000000000000000000000000000000000000081526004016109789190613395565b60007f000000000000000000000000000000000000000000000000000000000000000060ff168260ff1603611ca557508161068f565b7f000000000000000000000000000000000000000000000000000000000000000060ff168260ff161115611d90576000611cff7f000000000000000000000000000000000000000000000000000000000000000084613f9f565b9050604d8160ff161115611d73576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f000000000000000000000000000000000000000000000000000000000000000016602482015260448101859052606401610978565b611d7e81600a6140d8565b611d8890856140e7565b91505061068f565b6000611dbc837f0000000000000000000000000000000000000000000000000000000000000000613f9f565b9050604d8160ff161180611e035750611dd681600a6140d8565b611e00907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6140e7565b84115b15611e6e576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f000000000000000000000000000000000000000000000000000000000000000016602482015260448101859052606401610978565b611e7981600a6140d8565b6108a69085614122565b600081815260018301602052604081205415155b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611eef576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f0000000000000000000000000000000000000000000000000000000000000000611f48576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611fde576000838281518110611f6857611f68613a25565b60200260200101519050611f868160026128fe90919063ffffffff16565b15611fd55760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611f4b565b5060005b81518110156109c1576000828281518110611fff57611fff613a25565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612043575061209f565b61204e600282612920565b1561209d5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611fe2565b80516000036120e2576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff841660009081526007909252604090912061211490600501826126c1565b61214e5782826040517f393b8ad2000000000000000000000000000000000000000000000000000000008152600401610978929190614139565b60008181526008602052604090206121668382613d87565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea83604051610fe69190613395565b6121aa83610b15565b6121ec576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610978565b6121f7826000612584565b67ffffffffffffffff8316600090815260076020526040902061221a9083612942565b612225816000612584565b67ffffffffffffffff8316600090815260076020526040902061224b9060020182612942565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161227e9392919061415c565b60405180910390a1505050565b61229e61029e60a08301608084016133ca565b6122b2576119ae60a08201608083016133ca565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6122fe604084016020850161357b565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa15801561236f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123939190613f3a565b156123ca576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123e26123dd60608301604084016133ca565b612ae4565b6123fa6123f5604083016020840161357b565b612b63565b61198461240d604083016020840161357b565b8260600135612cb1565b6040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639dc29fac90604401600060405180830381600087803b1580156124a557600080fd5b505af115801561196c573d6000803e3d6000fd5b60606000611e9783612cf5565b6000611e978383612d50565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261256082606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261254491906141df565b85608001516fffffffffffffffffffffffffffffffff16612e43565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b81511561264f5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806125da575060408201516fffffffffffffffffffffffffffffffff16155b1561261357816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161097891906141f2565b801561264b576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580612688575060208201516fffffffffffffffffffffffffffffffff1615155b1561264b57816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161097891906141f2565b6000611e978383612e6b565b3373ffffffffffffffffffffffffffffffffffffffff82160361271c576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61279a81610b15565b6127dc576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610978565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561285b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061287f9190613f3a565b611984576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610978565b67ffffffffffffffff8216600090815260076020526040902061264b90600201827f0000000000000000000000000000000000000000000000000000000000000000612eba565b6000611e978373ffffffffffffffffffffffffffffffffffffffff8416612d50565b6000611e978373ffffffffffffffffffffffffffffffffffffffff8416612e6b565b815460009061296b90700100000000000000000000000000000000900463ffffffff16426141df565b90508015612a0d57600183015483546129b3916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612e43565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612a33916fffffffffffffffffffffffffffffffff908116911661323d565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061227e9084906141f2565b7f00000000000000000000000000000000000000000000000000000000000000001561198457612b15600282613253565b611984576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610978565b612b6c81610b15565b612bae576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610978565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612c27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c4b919061422e565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611984576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610978565b67ffffffffffffffff8216600090815260076020526040902061264b90827f0000000000000000000000000000000000000000000000000000000000000000612eba565b60608160000180548060200260200160405190810160405280929190818152602001828054801561116c57602002820191906000526020600020905b815481526020019060010190808311612d315750505050509050919050565b60008181526001830160205260408120548015612e39576000612d746001836141df565b8554909150600090612d88906001906141df565b9050808214612ded576000866000018281548110612da857612da8613a25565b9060005260206000200154905080876000018481548110612dcb57612dcb613a25565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612dfe57612dfe61424b565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061068f565b600091505061068f565b6000612e6285612e538486614122565b612e5d908761427a565b61323d565b95945050505050565b6000818152600183016020526040812054612eb25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561068f565b50600061068f565b825474010000000000000000000000000000000000000000900460ff161580612ee1575081155b15612eeb57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612f3190700100000000000000000000000000000000900463ffffffff16426141df565b90508015612ff15781831115612f73576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612fad9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612e43565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156130a85773ffffffffffffffffffffffffffffffffffffffff8416613050576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610978565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610978565b848310156131bb5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906130ec90826141df565b6130f6878a6141df565b613100919061427a565b61310a91906140e7565b905073ffffffffffffffffffffffffffffffffffffffff8616613163576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610978565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610978565b6131c585846141df565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b600081831061324c5781611e97565b5090919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611e97565b50805461328e90613a70565b6000825580601f1061329e575050565b601f01602090049060005260206000209081019061198491906132d6565b508054600082559060005260206000209081019061198491905b5b808211156132eb57600081556001016132d7565b5090565b60006020828403121561330157600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611e9757600080fd5b6000815180845260005b818110156133575760208185018101518683018201520161333b565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611e976020830184613331565b73ffffffffffffffffffffffffffffffffffffffff8116811461198457600080fd5b6000602082840312156133dc57600080fd5b8135611e97816133a8565b6000602082840312156133f957600080fd5b813567ffffffffffffffff81111561341057600080fd5b82016101008185031215611e9757600080fd5b803567ffffffffffffffff8116811461343b57600080fd5b919050565b60008060006040848603121561345557600080fd5b61345e84613423565b9250602084013567ffffffffffffffff8082111561347b57600080fd5b818601915086601f83011261348f57600080fd5b81358181111561349e57600080fd5b8760208285010111156134b057600080fd5b6020830194508093505050509250925092565b60008083601f8401126134d557600080fd5b50813567ffffffffffffffff8111156134ed57600080fd5b6020830191508360208260051b850101111561350857600080fd5b9250929050565b6000806000806040858703121561352557600080fd5b843567ffffffffffffffff8082111561353d57600080fd5b613549888389016134c3565b9096509450602087013591508082111561356257600080fd5b5061356f878288016134c3565b95989497509550505050565b60006020828403121561358d57600080fd5b611e9782613423565b60008083601f8401126135a857600080fd5b50813567ffffffffffffffff8111156135c057600080fd5b60208301915083602060608302850101111561350857600080fd5b600080600080600080606087890312156135f457600080fd5b863567ffffffffffffffff8082111561360c57600080fd5b6136188a838b016134c3565b9098509650602089013591508082111561363157600080fd5b61363d8a838b01613596565b9096509450604089013591508082111561365657600080fd5b5061366389828a01613596565b979a9699509497509295939492505050565b60006020828403121561368757600080fd5b813567ffffffffffffffff81111561369e57600080fd5b820160a08185031215611e9757600080fd5b6020815260008251604060208401526136cc6060840182613331565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612e628282613331565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b8281101561377c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261376a858351613331565b94509285019290850190600101613730565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b818110156137d757835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016137a5565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156137d757835167ffffffffffffffff16835292840192918401916001016137ff565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff8111828210171561387757613877613825565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156138c4576138c4613825565b604052919050565b801515811461198457600080fd5b80356fffffffffffffffffffffffffffffffff8116811461343b57600080fd5b60006060828403121561390c57600080fd5b6040516060810181811067ffffffffffffffff8211171561392f5761392f613825565b6040529050808235613940816138cc565b815261394e602084016138da565b602082015261395f604084016138da565b60408201525092915050565b600080600060e0848603121561398057600080fd5b61398984613423565b925061399885602086016138fa565b91506139a785608086016138fa565b90509250925092565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126139e557600080fd5b83018035915067ffffffffffffffff821115613a0057600080fd5b60200191503681900382131561350857600080fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060608284031215613a6657600080fd5b611e9783836138fa565b600181811c90821680613a8457607f821691505b602082108103613abd577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b67ffffffffffffffff84168152604060208201526000612e62604083018486613ac3565b6020815260006108a6602083018486613ac3565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee1833603018112613b7857600080fd5b9190910192915050565b600082601f830112613b9357600080fd5b813567ffffffffffffffff811115613bad57613bad613825565b613bde60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161387d565b818152846020838601011115613bf357600080fd5b816020850160208301376000918101602001919091529392505050565b60006101208236031215613c2357600080fd5b613c2b613854565b613c3483613423565b815260208084013567ffffffffffffffff80821115613c5257600080fd5b9085019036601f830112613c6557600080fd5b813581811115613c7757613c77613825565b8060051b613c8685820161387d565b9182528381018501918581019036841115613ca057600080fd5b86860192505b83831015613cdc57823585811115613cbe5760008081fd5b613ccc3689838a0101613b82565b8352509186019190860190613ca6565b8087890152505050506040860135925080831115613cf957600080fd5b5050613d0736828601613b82565b604083015250613d1a36606085016138fa565b6060820152613d2c3660c085016138fa565b608082015292915050565b601f8211156109c1576000816000526020600020601f850160051c81016020861015613d605750805b601f850160051c820191505b81811015613d7f57828155600101613d6c565b505050505050565b815167ffffffffffffffff811115613da157613da1613825565b613db581613daf8454613a70565b84613d37565b602080601f831160018114613e085760008415613dd25750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613d7f565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613e5557888601518255948401946001909101908401613e36565b5085821015613e9157878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613ec581840187613331565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613f039050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612e62565b600060208284031215613f4c57600080fd5b8151611e97816138cc565b600060208284031215613f6957600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff828116828216039081111561068f5761068f613f70565b600181815b8085111561401157817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613ff757613ff7613f70565b8085161561400457918102915b93841c9390800290613fbd565b509250929050565b6000826140285750600161068f565b816140355750600061068f565b816001811461404b576002811461405557614071565b600191505061068f565b60ff84111561406657614066613f70565b50506001821b61068f565b5060208310610133831016604e8410600b8410161715614094575081810a61068f565b61409e8383613fb8565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156140d0576140d0613f70565b029392505050565b6000611e9760ff841683614019565b60008261411d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761068f5761068f613f70565b67ffffffffffffffff831681526040602082015260006108a66040830184613331565b67ffffffffffffffff8416815260e081016141a860208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526108a6565b8181038181111561068f5761068f613f70565b6060810161068f82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561424057600080fd5b8151611e97816133a8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8082018082111561068f5761068f613f7056fea164736f6c6343000818000a", } var BurnWithFromMintTokenPoolABI = BurnWithFromMintTokenPoolMetaData.ABI @@ -713,6 +713,18 @@ func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) Se return _BurnWithFromMintTokenPool.Contract.SetChainRateLimiterConfig(&_BurnWithFromMintTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) } +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.contract.Transact(opts, "setChainRateLimiterConfigs", remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.SetChainRateLimiterConfigs(&_BurnWithFromMintTokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.SetChainRateLimiterConfigs(&_BurnWithFromMintTokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) { return _BurnWithFromMintTokenPool.contract.Transact(opts, "setRateLimitAdmin", rateLimitAdmin) } @@ -3033,6 +3045,8 @@ type BurnWithFromMintTokenPoolInterface interface { SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) + SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go b/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go deleted file mode 100644 index 3c2d44cd302..00000000000 --- a/core/gethwrappers/ccip/generated/ccip_config/ccip_config.go +++ /dev/null @@ -1,1126 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package ccip_config - -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 CCIPConfigTypesChainConfig struct { - Readers [][32]byte - FChain uint8 - Config []byte -} - -type CCIPConfigTypesChainConfigInfo struct { - ChainSelector uint64 - ChainConfig CCIPConfigTypesChainConfig -} - -type CCIPConfigTypesOCR3Config struct { - PluginType uint8 - ChainSelector uint64 - F uint8 - OffchainConfigVersion uint64 - OfframpAddress []byte - P2pIds [][32]byte - Signers [][]byte - Transmitters [][]byte - OffchainConfig []byte -} - -type CCIPConfigTypesOCR3ConfigWithMeta struct { - Config CCIPConfigTypesOCR3Config - ConfigCount uint64 - ConfigDigest [32]byte -} - -var CCIPConfigMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"capabilitiesRegistry\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainSelectorNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ChainSelectorNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FChainMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"InvalidConfigLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumCCIPConfigTypes.ConfigState\",\"name\":\"currentState\",\"type\":\"uint8\"},{\"internalType\":\"enumCCIPConfigTypes.ConfigState\",\"name\":\"proposedState\",\"type\":\"uint8\"}],\"name\":\"InvalidConfigStateTransition\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPluginType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"NodeNotInRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonExistentConfigTransition\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimum\",\"type\":\"uint256\"}],\"name\":\"NotEnoughTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OfframpAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCapabilitiesRegistryCanCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"p2pIdsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"signersLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"transmittersLength\",\"type\":\"uint256\"}],\"name\":\"P2PIdsLengthNotMatching\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOCR3Configs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManySigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"}],\"name\":\"WrongConfigCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"got\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"WrongConfigDigest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"got\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"}],\"name\":\"WrongConfigDigestBlueGreen\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CapabilityConfigurationSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainConfigRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigSet\",\"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\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"chainSelectorRemoves\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfigInfo[]\",\"name\":\"chainConfigAdds\",\"type\":\"tuple[]\"}],\"name\":\"applyChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"beforeCapabilityConfigSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"pageIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"pageSize\",\"type\":\"uint256\"}],\"name\":\"getAllChainConfigs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPConfigTypes.ChainConfigInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"getCapabilityConfiguration\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"configuration\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilityRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getOCRConfig\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"p2pIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes[]\",\"name\":\"signers\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes[]\",\"name\":\"transmitters\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPConfigTypes.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"internalType\":\"structCCIPConfigTypes.OCR3ConfigWithMeta[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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: "0x60a06040523480156200001157600080fd5b5060405162004080380380620040808339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e9576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b608051613e7f620002016000396000818160f801528181610ea701526111170152613e7f6000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80638318ed5d11610081578063f2fde38b1161005b578063f2fde38b1461020f578063f442c89a14610222578063fba64a7c1461023557600080fd5b80638318ed5d146101b05780638da5cb5b146101d1578063b74b2356146101ef57600080fd5b8063181f5a77116100b2578063181f5a771461013d5780634bd0473f1461018657806379ba5097146101a657600080fd5b806301ffc9a7146100ce578063020330e6146100f6575b600080fd5b6100e16100dc366004612cbd565b610248565b60405190151581526020015b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ed565b6101796040518060400160405280601481526020017f43434950436f6e66696720312e362e302d64657600000000000000000000000081525081565b6040516100ed9190612d63565b610199610194366004612da7565b6102e1565b6040516100ed9190612ec6565b6101ae610759565b005b6101796101be366004613082565b5060408051602081019091526000815290565b60005473ffffffffffffffffffffffffffffffffffffffff16610118565b6102026101fd36600461309f565b61085b565b6040516100ed9190613105565b6101ae61021d366004613195565b610adc565b6101ae610230366004613217565b610af0565b6101ae61024336600461329b565b610e8f565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f78bea7210000000000000000000000000000000000000000000000000000000014806102db57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b63ffffffff8216600090815260056020526040812060609183600181111561030b5761030b612ddc565b600181111561031c5761031c612ddc565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561074d57600084815260209020604080516101808101909152600884029091018054829060608201908390829060ff16600181111561038f5761038f612ddc565b60018111156103a0576103a0612ddc565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a01000000000000000000009091041660608201526001820180546080909201916103f890613358565b80601f016020809104026020016040519081016040528092919081815260200182805461042490613358565b80156104715780601f1061044657610100808354040283529160200191610471565b820191906000526020600020905b81548152906001019060200180831161045457829003601f168201915b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156104c957602002820191906000526020600020905b8154815260200190600101908083116104b5575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b828210156105a357838290600052602060002001805461051690613358565b80601f016020809104026020016040519081016040528092919081815260200182805461054290613358565b801561058f5780601f106105645761010080835404028352916020019161058f565b820191906000526020600020905b81548152906001019060200180831161057257829003601f168201915b5050505050815260200190600101906104f7565b50505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b8282101561067c5783829060005260206000200180546105ef90613358565b80601f016020809104026020016040519081016040528092919081815260200182805461061b90613358565b80156106685780601f1061063d57610100808354040283529160200191610668565b820191906000526020600020905b81548152906001019060200180831161064b57829003601f168201915b5050505050815260200190600101906105d0565b50505050815260200160058201805461069490613358565b80601f01602080910402602001604051908101604052809291908181526020018280546106c090613358565b801561070d5780601f106106e25761010080835404028352916020019161070d565b820191906000526020600020905b8154815290600101906020018083116106f057829003601f168201915b505050919092525050508152600682015467ffffffffffffffff16602080830191909152600790920154604090910152908252600192909201910161034a565b50505050905092915050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146107df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b606060006108696003610f4a565b9050600061087784866133da565b90508315806108865750818110155b156108c65760408051600080825260208201909252906108bc565b6108a9612a5c565b8152602001906001900390816108a15790505b50925050506102db565b60006108d28583613420565b9050828111156108df5750815b60006108eb8383613433565b67ffffffffffffffff811115610903576109036133f1565b60405190808252806020026020018201604052801561093c57816020015b610929612a5c565b8152602001906001900390816109215790505b509050600061094b6003610f54565b9050835b83811015610acf57600082828151811061096b5761096b613446565b60209081029190910181015160408051808201825267ffffffffffffffff8316808252600090815260028552829020825181546080818802830181019095526060820181815295975092958601949093919284928491908401828280156109f157602002820191906000526020600020905b8154815260200190600101908083116109dd575b5050509183525050600182015460ff166020820152600282018054604090920191610a1b90613358565b80601f0160208091040260200160405190810160405280929190818152602001828054610a4790613358565b8015610a945780601f10610a6957610100808354040283529160200191610a94565b820191906000526020600020905b815481529060010190602001808311610a7757829003601f168201915b50505091909252505050905284610aab8885613433565b81518110610abb57610abb613446565b60209081029190910101525060010161094f565b5090979650505050505050565b610ae4610f68565b610aed81610feb565b50565b610af8610f68565b60005b83811015610cde57610b3f858583818110610b1857610b18613446565b9050602002016020810190610b2d9190613475565b60039067ffffffffffffffff166110e0565b610ba957848482818110610b5557610b55613446565b9050602002016020810190610b6a9190613475565b6040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d6565b60026000868684818110610bbf57610bbf613446565b9050602002016020810190610bd49190613475565b67ffffffffffffffff1681526020810191909152604001600090812090610bfb8282612aa4565b6001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610c33600283016000612ac2565b5050610c71858583818110610c4a57610c4a613446565b9050602002016020810190610c5f9190613475565b60039067ffffffffffffffff166110f8565b507f2a680691fef3b2d105196805935232c661ce703e92d464ef0b94a7bc62d714f0858583818110610ca557610ca5613446565b9050602002016020810190610cba9190613475565b60405167ffffffffffffffff909116815260200160405180910390a1600101610afb565b5060005b81811015610e88576000838383818110610cfe57610cfe613446565b9050602002810190610d109190613490565b610d1e9060208101906134ce565b610d27906136d0565b90506000848484818110610d3d57610d3d613446565b9050602002810190610d4f9190613490565b610d5d906020810190613475565b9050610d6c8260000151611104565b816020015160ff16600003610dad576040517fa9b3766e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600260209081526040909120835180518593610ddd928492910190612afc565b5060208201516001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff90921691909117905560408201516002820190610e2a90826137b7565b50610e4491506003905067ffffffffffffffff8316611250565b507f05dd57854af2c291a94ea52e7c43d80bc3be7fa73022f98b735dea86642fa5e08183604051610e769291906138d1565b60405180910390a15050600101610ce2565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610efe576040517fac7a7efd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610f15610f108688018861397c565b61125c565b8151919350915015610f2d57610f2d836000846114a7565b805115610f4057610f40836001836114a7565b5050505050505050565b60006102db825490565b60606000610f6183611c09565b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610fe9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107d6565b565b3373ffffffffffffffffffffffffffffffffffffffff82160361106a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107d6565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120541515610f61565b6000610f618383611c65565b60005b815181101561124c5760008019167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166350c946fe84848151811061116357611163613446565b60200260200101516040518263ffffffff1660e01b815260040161118991815260200190565b600060405180830381865afa1580156111a6573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526111ec9190810190613bc7565b60800151036112445781818151811061120757611207613446565b60200260200101516040517f8907a4fa0000000000000000000000000000000000000000000000000000000081526004016107d691815260200190565b600101611107565b5050565b6000610f618383611d5f565b606080600460ff168351111561129e576040517f8854586400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160028082526060820190925290816020015b61131b6040805161012081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff16815260200160608152602001606081526020016060815260200160608152602001606081525090565b8152602001906001900390816112b457505060408051600280825260608201909252919350602082015b6113ac6040805161012081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff16815260200160608152602001606081526020016060815260200160608152602001606081525090565b81526020019060019003908161134557905050905060008060005b855181101561149a5760008682815181106113e4576113e4613446565b602002602001015160000151600181111561140157611401612ddc565b0361144e5785818151811061141857611418613446565b602002602001015185848151811061143257611432613446565b60200260200101819052508261144790613c9f565b9250611492565b85818151811061146057611460613446565b602002602001015184838151811061147a5761147a613446565b60200260200101819052508161148f90613c9f565b91505b6001016113c7565b5090835281529092909150565b63ffffffff83166000908152600560205260408120818460018111156114cf576114cf612ddc565b60018111156114e0576114e0612ddc565b8152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561191157600084815260209020604080516101808101909152600884029091018054829060608201908390829060ff16600181111561155357611553612ddc565b600181111561156457611564612ddc565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a01000000000000000000009091041660608201526001820180546080909201916115bc90613358565b80601f01602080910402602001604051908101604052809291908181526020018280546115e890613358565b80156116355780601f1061160a57610100808354040283529160200191611635565b820191906000526020600020905b81548152906001019060200180831161161857829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561168d57602002820191906000526020600020905b815481526020019060010190808311611679575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b828210156117675783829060005260206000200180546116da90613358565b80601f016020809104026020016040519081016040528092919081815260200182805461170690613358565b80156117535780601f1061172857610100808354040283529160200191611753565b820191906000526020600020905b81548152906001019060200180831161173657829003601f168201915b5050505050815260200190600101906116bb565b50505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b828210156118405783829060005260206000200180546117b390613358565b80601f01602080910402602001604051908101604052809291908181526020018280546117df90613358565b801561182c5780601f106118015761010080835404028352916020019161182c565b820191906000526020600020905b81548152906001019060200180831161180f57829003601f168201915b505050505081526020019060010190611794565b50505050815260200160058201805461185890613358565b80601f016020809104026020016040519081016040528092919081815260200182805461188490613358565b80156118d15780601f106118a6576101008083540402835291602001916118d1565b820191906000526020600020905b8154815290600101906020018083116118b457829003601f168201915b505050919092525050508152600682015467ffffffffffffffff16602080830191909152600790920154604090910152908252600192909201910161150e565b50505050905060006119238251611dae565b905060006119318451611dae565b905061193d8282611e00565b600061194c8785878686611ebc565b905061195884826122a0565b63ffffffff871660009081526005602052604081209087600181111561198057611980612ddc565b600181111561199157611991612ddc565b815260200190815260200160002060006119ab9190612b47565b60005b8151811015610f405763ffffffff88166000908152600560205260408120908860018111156119df576119df612ddc565b60018111156119f0576119f0612ddc565b8152602001908152602001600020828281518110611a1057611a10613446565b6020908102919091018101518254600181810185556000948552929093208151805160089095029091018054929490939192849283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016908381811115611a7a57611a7a612ddc565b021790555060208201518154604084015160608501517fffffffffffffffffffffffffffffffffffffffffffff000000000000000000ff90921661010067ffffffffffffffff948516027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff1617690100000000000000000060ff90921691909102177fffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffff166a0100000000000000000000929091169190910217815560808201516001820190611b4990826137b7565b5060a08201518051611b65916002840191602090910190612afc565b5060c08201518051611b81916003840191602090910190612b68565b5060e08201518051611b9d916004840191602090910190612b68565b506101008201516005820190611bb390826137b7565b50505060208201516006820180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff9092169190911790556040909101516007909101556001016119ae565b606081600001805480602002602001604051908101604052809291908181526020018280548015611c5957602002820191906000526020600020905b815481526020019060010190808311611c45575b50505050509050919050565b60008181526001830160205260408120548015611d4e576000611c89600183613433565b8554909150600090611c9d90600190613433565b9050808214611d02576000866000018281548110611cbd57611cbd613446565b9060005260206000200154905080876000018481548110611ce057611ce0613446565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611d1357611d13613cd7565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506102db565b60009150506102db565b5092915050565b6000818152600183016020526040812054611da6575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556102db565b5060006102db565b60006002821115611dee576040517f3e478526000000000000000000000000000000000000000000000000000000008152600481018390526024016107d6565b8160028111156102db576102db612ddc565b6000826002811115611e1457611e14612ddc565b826002811115611e2657611e26612ddc565b611e309190613d06565b90508060011480611e7c5750807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff148015611e7c57506002836002811115611e7a57611e7a612ddc565b145b15611e8657505050565b82826040517f0a6b675b0000000000000000000000000000000000000000000000000000000081526004016107d6929190613d36565b60606000845167ffffffffffffffff811115611eda57611eda6133f1565b604051908082528060200260200182016040528015611f03578160200160208202803683370190505b5090506000846002811115611f1a57611f1a612ddc565b148015611f3857506001836002811115611f3657611f36612ddc565b145b15611f7957600181600081518110611f5257611f52613446565b602002602001019067ffffffffffffffff16908167ffffffffffffffff16815250506120e1565b6001846002811115611f8d57611f8d612ddc565b148015611fab57506002836002811115611fa957611fa9612ddc565b145b156120425785600081518110611fc357611fc3613446565b60200260200101516020015181600081518110611fe257611fe2613446565b602002602001019067ffffffffffffffff16908167ffffffffffffffff16815250508560008151811061201757612017613446565b602002602001015160200151600161202f9190613d51565b81600181518110611f5257611f52613446565b600284600281111561205657612056612ddc565b1480156120745750600183600281111561207257612072612ddc565b145b156120ab578560018151811061208c5761208c613446565b60200260200101516020015181600081518110611f5257611f52613446565b83836040517f0a6b675b0000000000000000000000000000000000000000000000000000000081526004016107d6929190613d36565b6000855167ffffffffffffffff8111156120fd576120fd6133f1565b6040519080825280602002602001820160405280156121ab57816020015b6040805161018081018252600060608083018281526080840183905260a0840183905260c0840183905260e08401829052610100840182905261012084018290526101408401829052610160840191909152825260208083018290529282015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90920191018161211b5790505b50905060005b8251811015612294576121dc8782815181106121cf576121cf613446565b602002602001015161261f565b60405180606001604052808883815181106121f9576121f9613446565b6020026020010151815260200184838151811061221857612218613446565b602002602001015167ffffffffffffffff16815260200161226c8b86858151811061224557612245613446565b60200260200101518b868151811061225f5761225f613446565b602002602001015161298e565b81525082828151811061228157612281613446565b60209081029190910101526001016121b1565b50979650505050505050565b81518151811580156122b25750806001145b1561235457826000815181106122ca576122ca613446565b60200260200101516020015167ffffffffffffffff1660011461234e57826000815181106122fa576122fa613446565b60209081029190910181015101516040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152600160248201526044016107d6565b50505050565b8160011480156123645750806002145b1561251a578360008151811061237c5761237c613446565b6020026020010151604001518360008151811061239b5761239b613446565b6020026020010151604001511461242757826000815181106123bf576123bf613446565b602002602001015160400151846000815181106123de576123de613446565b6020026020010151604001516040517fc7ccdd7f0000000000000000000000000000000000000000000000000000000081526004016107d6929190918252602082015260400190565b8360008151811061243a5761243a613446565b60200260200101516020015160016124529190613d51565b67ffffffffffffffff168360018151811061246f5761246f613446565b60200260200101516020015167ffffffffffffffff161461234e578260018151811061249d5761249d613446565b602002602001015160200151846000815181106124bc576124bc613446565b60200260200101516020015160016124d49190613d51565b6040517fc1658eb800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9283166004820152911660248201526044016107d6565b81600214801561252a5750806001145b156125ed578360018151811061254257612542613446565b6020026020010151604001518360008151811061256157612561613446565b6020026020010151604001511461234e578260008151811061258557612585613446565b602002602001015160400151846001815181106125a4576125a4613446565b6020026020010151604001516040517f9e9756700000000000000000000000000000000000000000000000000000000081526004016107d6929190918252602082015260400190565b6040517f1f1b2bb600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806020015167ffffffffffffffff16600003612667576040517f698cf8e000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008151600181111561267c5761267c612ddc565b1415801561269d575060018151600181111561269a5761269a612ddc565b14155b156126d4576040517f3302dbd700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6080810151511580612711575060408051600060208201520160405160208183030381529060405280519060200120816080015180519060200120145b15612748576040517f358c192700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101516127639060039067ffffffffffffffff166110e0565b6127ab5760208101516040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d6565b60208082015167ffffffffffffffff166000908152600290915260408120600101546127db9060ff166003613d72565b6127e6906001613d8e565b60ff169050808260e0015151101561283b5760e0820151516040517f548dd21f0000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016107d6565b60c08201515161010081111561287d576040517f1b925da600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260a00151518114158061289657508260e00151518114155b156128f05760a08301515160c08401515160e0850151516040517fba900f6d0000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064016107d6565b826040015160ff16600003612931576040517f39d1a4d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040830151612941906003613d72565b60ff16811161297c576040517f4856694e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129898360a00151611104565b505050565b60008082602001518584600001518560800151878760a001518860c001518960e001518a604001518b606001518c61010001516040516020016129db9b9a99989796959493929190613da7565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e0a000000000000000000000000000000000000000000000000000000000000179150509392505050565b6040518060400160405280600067ffffffffffffffff168152602001612a9f604051806060016040528060608152602001600060ff168152602001606081525090565b905290565b5080546000825590600052602060002090810190610aed9190612bba565b508054612ace90613358565b6000825580601f10612ade575050565b601f016020900490600052602060002090810190610aed9190612bba565b828054828255906000526020600020908101928215612b37579160200282015b82811115612b37578251825591602001919060010190612b1c565b50612b43929150612bba565b5090565b5080546000825560080290600052602060002090810190610aed9190612bcf565b828054828255906000526020600020908101928215612bae579160200282015b82811115612bae5782518290612b9e90826137b7565b5091602001919060010190612b88565b50612b43929150612c82565b5b80821115612b435760008155600101612bbb565b80821115612b435780547fffffffffffffffffffffffffffff00000000000000000000000000000000000016815560008181612c0e6001830182612ac2565b612c1c600283016000612aa4565b612c2a600383016000612c9f565b612c38600483016000612c9f565b612c46600583016000612ac2565b5050506006810180547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016905560006007820155600801612bcf565b80821115612b43576000612c968282612ac2565b50600101612c82565b5080546000825590600052602060002090810190610aed9190612c82565b600060208284031215612ccf57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f6157600080fd5b6000815180845260005b81811015612d2557602081850181015186830182015201612d09565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610f616020830184612cff565b63ffffffff81168114610aed57600080fd5b8035612d9381612d76565b919050565b803560028110612d9357600080fd5b60008060408385031215612dba57600080fd5b8235612dc581612d76565b9150612dd360208401612d98565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60028110612e1b57612e1b612ddc565b9052565b60008151808452602080850194506020840160005b83811015612e5057815187529582019590820190600101612e34565b509495945050505050565b60008282518085526020808601955060208260051b8401016020860160005b84811015610acf577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0868403018952612eb4838351612cff565b98840198925090830190600101612e7a565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015613074577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0898403018552815160608151818652612f348287018251612e0b565b898101516080612f4f8189018367ffffffffffffffff169052565b8a830151915060a0612f65818a018460ff169052565b938301519360c09250612f838984018667ffffffffffffffff169052565b818401519450610120915060e082818b0152612fa36101808b0187612cff565b95508185015191507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0610100818c890301818d0152612fe28885612e1f565b958701518c87038301868e0152959750612ffc8887612e5b565b9750828701519550818c8903016101408d01526130198887612e5b565b975080870151965050808b8803016101608c0152505050505061303c8282612cff565b915050888201516130588a87018267ffffffffffffffff169052565b5090870151938701939093529386019390860190600101612eef565b509098975050505050505050565b60006020828403121561309457600080fd5b8135610f6181612d76565b600080604083850312156130b257600080fd5b50508035926020909101359150565b60008151606084526130d66060850182612e1f565b905060ff6020840151166020850152604083015184820360408601526130fc8282612cff565b95945050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015613074578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805167ffffffffffffffff168452870151878401879052613182878501826130c1565b958801959350509086019060010161312e565b6000602082840312156131a757600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f6157600080fd5b60008083601f8401126131dd57600080fd5b50813567ffffffffffffffff8111156131f557600080fd5b6020830191508360208260051b850101111561321057600080fd5b9250929050565b6000806000806040858703121561322d57600080fd5b843567ffffffffffffffff8082111561324557600080fd5b613251888389016131cb565b9096509450602087013591508082111561326a57600080fd5b50613277878288016131cb565b95989497509550505050565b803567ffffffffffffffff81168114612d9357600080fd5b600080600080600080608087890312156132b457600080fd5b863567ffffffffffffffff808211156132cc57600080fd5b6132d88a838b016131cb565b909850965060208901359150808211156132f157600080fd5b818901915089601f83011261330557600080fd5b81358181111561331457600080fd5b8a602082850101111561332657600080fd5b60208301965080955050505061333e60408801613283565b915061334c60608801612d88565b90509295509295509295565b600181811c9082168061336c57607f821691505b6020821081036133a5577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176102db576102db6133ab565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b808201808211156102db576102db6133ab565b818103818111156102db576102db6133ab565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561348757600080fd5b610f6182613283565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126134c457600080fd5b9190910192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18336030181126134c457600080fd5b604051610120810167ffffffffffffffff81118282101715613526576135266133f1565b60405290565b60405160e0810167ffffffffffffffff81118282101715613526576135266133f1565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613596576135966133f1565b604052919050565b600067ffffffffffffffff8211156135b8576135b86133f1565b5060051b60200190565b600082601f8301126135d357600080fd5b813560206135e86135e38361359e565b61354f565b8083825260208201915060208460051b87010193508684111561360a57600080fd5b602086015b84811015613626578035835291830191830161360f565b509695505050505050565b803560ff81168114612d9357600080fd5b600082601f83011261365357600080fd5b813567ffffffffffffffff81111561366d5761366d6133f1565b61369e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161354f565b8181528460208386010111156136b357600080fd5b816020850160208301376000918101602001919091529392505050565b6000606082360312156136e257600080fd5b6040516060810167ffffffffffffffff8282108183111715613706576137066133f1565b81604052843591508082111561371b57600080fd5b613727368387016135c2565b835261373560208601613631565b6020840152604085013591508082111561374e57600080fd5b5061375b36828601613642565b60408301525092915050565b601f821115612989576000816000526020600020601f850160051c810160208610156137905750805b601f850160051c820191505b818110156137af5782815560010161379c565b505050505050565b815167ffffffffffffffff8111156137d1576137d16133f1565b6137e5816137df8454613358565b84613767565b602080601f83116001811461383857600084156138025750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556137af565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561388557888601518255948401946001909101908401613866565b50858210156138c157878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff831681526040602082015260006138f460408301846130c1565b949350505050565b600082601f83011261390d57600080fd5b8135602061391d6135e38361359e565b82815260059290921b8401810191818101908684111561393c57600080fd5b8286015b8481101561362657803567ffffffffffffffff8111156139605760008081fd5b61396e8986838b0101613642565b845250918301918301613940565b6000602080838503121561398f57600080fd5b823567ffffffffffffffff808211156139a757600080fd5b818501915085601f8301126139bb57600080fd5b81356139c96135e38261359e565b81815260059190911b830184019084810190888311156139e857600080fd5b8585015b83811015613b5057803585811115613a0357600080fd5b8601610120818c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001811315613a3957600080fd5b613a41613502565b613a4c8a8401612d98565b8152613a5a60408401613283565b8a820152613a6a60608401613631565b6040820152613a7b60808401613283565b606082015260a083013588811115613a9257600080fd5b613aa08e8c83870101613642565b60808301525060c083013588811115613ab857600080fd5b613ac68e8c838701016135c2565b60a08301525060e083013588811115613adf5760008081fd5b613aed8e8c838701016138fc565b60c0830152506101008084013589811115613b085760008081fd5b613b168f8d838801016138fc565b60e084015250918301359188831115613b2f5760008081fd5b613b3d8e8c85870101613642565b90820152855250509186019186016139ec565b5098975050505050505050565b8051612d9381612d76565b600082601f830112613b7957600080fd5b81516020613b896135e38361359e565b8083825260208201915060208460051b870101935086841115613bab57600080fd5b602086015b848110156136265780518352918301918301613bb0565b600060208284031215613bd957600080fd5b815167ffffffffffffffff80821115613bf157600080fd5b9083019060e08286031215613c0557600080fd5b613c0d61352c565b613c1683613b5d565b8152613c2460208401613b5d565b6020820152613c3560408401613b5d565b6040820152606083015160608201526080830151608082015260a083015182811115613c6057600080fd5b613c6c87828601613b68565b60a08301525060c083015182811115613c8457600080fd5b613c9087828601613b68565b60c08301525095945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613cd057613cd06133ab565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8181036000831280158383131683831282161715611d5857611d586133ab565b60038110612e1b57612e1b612ddc565b60408101613d448285613d26565b610f616020830184613d26565b67ffffffffffffffff818116838216019080821115611d5857611d586133ab565b60ff8181168382160290811690818114611d5857611d586133ab565b60ff81811683821601908111156102db576102db6133ab565b600061016067ffffffffffffffff8e16835263ffffffff8d166020840152613dd2604084018d612e0b565b806060840152613de48184018c612cff565b67ffffffffffffffff8b166080850152905082810360a0840152613e08818a612e1f565b905082810360c0840152613e1c8189612e5b565b905082810360e0840152613e308188612e5b565b60ff8716610100850152905067ffffffffffffffff8516610120840152828103610140840152613e608185612cff565b9e9d505050505050505050505050505056fea164736f6c6343000818000a", -} - -var CCIPConfigABI = CCIPConfigMetaData.ABI - -var CCIPConfigBin = CCIPConfigMetaData.Bin - -func DeployCCIPConfig(auth *bind.TransactOpts, backend bind.ContractBackend, capabilitiesRegistry common.Address) (common.Address, *types.Transaction, *CCIPConfig, error) { - parsed, err := CCIPConfigMetaData.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(CCIPConfigBin), backend, capabilitiesRegistry) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &CCIPConfig{address: address, abi: *parsed, CCIPConfigCaller: CCIPConfigCaller{contract: contract}, CCIPConfigTransactor: CCIPConfigTransactor{contract: contract}, CCIPConfigFilterer: CCIPConfigFilterer{contract: contract}}, nil -} - -type CCIPConfig struct { - address common.Address - abi abi.ABI - CCIPConfigCaller - CCIPConfigTransactor - CCIPConfigFilterer -} - -type CCIPConfigCaller struct { - contract *bind.BoundContract -} - -type CCIPConfigTransactor struct { - contract *bind.BoundContract -} - -type CCIPConfigFilterer struct { - contract *bind.BoundContract -} - -type CCIPConfigSession struct { - Contract *CCIPConfig - CallOpts bind.CallOpts - TransactOpts bind.TransactOpts -} - -type CCIPConfigCallerSession struct { - Contract *CCIPConfigCaller - CallOpts bind.CallOpts -} - -type CCIPConfigTransactorSession struct { - Contract *CCIPConfigTransactor - TransactOpts bind.TransactOpts -} - -type CCIPConfigRaw struct { - Contract *CCIPConfig -} - -type CCIPConfigCallerRaw struct { - Contract *CCIPConfigCaller -} - -type CCIPConfigTransactorRaw struct { - Contract *CCIPConfigTransactor -} - -func NewCCIPConfig(address common.Address, backend bind.ContractBackend) (*CCIPConfig, error) { - abi, err := abi.JSON(strings.NewReader(CCIPConfigABI)) - if err != nil { - return nil, err - } - contract, err := bindCCIPConfig(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &CCIPConfig{address: address, abi: abi, CCIPConfigCaller: CCIPConfigCaller{contract: contract}, CCIPConfigTransactor: CCIPConfigTransactor{contract: contract}, CCIPConfigFilterer: CCIPConfigFilterer{contract: contract}}, nil -} - -func NewCCIPConfigCaller(address common.Address, caller bind.ContractCaller) (*CCIPConfigCaller, error) { - contract, err := bindCCIPConfig(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &CCIPConfigCaller{contract: contract}, nil -} - -func NewCCIPConfigTransactor(address common.Address, transactor bind.ContractTransactor) (*CCIPConfigTransactor, error) { - contract, err := bindCCIPConfig(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &CCIPConfigTransactor{contract: contract}, nil -} - -func NewCCIPConfigFilterer(address common.Address, filterer bind.ContractFilterer) (*CCIPConfigFilterer, error) { - contract, err := bindCCIPConfig(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &CCIPConfigFilterer{contract: contract}, nil -} - -func bindCCIPConfig(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := CCIPConfigMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -func (_CCIPConfig *CCIPConfigRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _CCIPConfig.Contract.CCIPConfigCaller.contract.Call(opts, result, method, params...) -} - -func (_CCIPConfig *CCIPConfigRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _CCIPConfig.Contract.CCIPConfigTransactor.contract.Transfer(opts) -} - -func (_CCIPConfig *CCIPConfigRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _CCIPConfig.Contract.CCIPConfigTransactor.contract.Transact(opts, method, params...) -} - -func (_CCIPConfig *CCIPConfigCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _CCIPConfig.Contract.contract.Call(opts, result, method, params...) -} - -func (_CCIPConfig *CCIPConfigTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _CCIPConfig.Contract.contract.Transfer(opts) -} - -func (_CCIPConfig *CCIPConfigTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _CCIPConfig.Contract.contract.Transact(opts, method, params...) -} - -func (_CCIPConfig *CCIPConfigCaller) GetAllChainConfigs(opts *bind.CallOpts, pageIndex *big.Int, pageSize *big.Int) ([]CCIPConfigTypesChainConfigInfo, error) { - var out []interface{} - err := _CCIPConfig.contract.Call(opts, &out, "getAllChainConfigs", pageIndex, pageSize) - - if err != nil { - return *new([]CCIPConfigTypesChainConfigInfo), err - } - - out0 := *abi.ConvertType(out[0], new([]CCIPConfigTypesChainConfigInfo)).(*[]CCIPConfigTypesChainConfigInfo) - - return out0, err - -} - -func (_CCIPConfig *CCIPConfigSession) GetAllChainConfigs(pageIndex *big.Int, pageSize *big.Int) ([]CCIPConfigTypesChainConfigInfo, error) { - return _CCIPConfig.Contract.GetAllChainConfigs(&_CCIPConfig.CallOpts, pageIndex, pageSize) -} - -func (_CCIPConfig *CCIPConfigCallerSession) GetAllChainConfigs(pageIndex *big.Int, pageSize *big.Int) ([]CCIPConfigTypesChainConfigInfo, error) { - return _CCIPConfig.Contract.GetAllChainConfigs(&_CCIPConfig.CallOpts, pageIndex, pageSize) -} - -func (_CCIPConfig *CCIPConfigCaller) GetCapabilityConfiguration(opts *bind.CallOpts, arg0 uint32) ([]byte, error) { - var out []interface{} - err := _CCIPConfig.contract.Call(opts, &out, "getCapabilityConfiguration", arg0) - - if err != nil { - return *new([]byte), err - } - - out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) - - return out0, err - -} - -func (_CCIPConfig *CCIPConfigSession) GetCapabilityConfiguration(arg0 uint32) ([]byte, error) { - return _CCIPConfig.Contract.GetCapabilityConfiguration(&_CCIPConfig.CallOpts, arg0) -} - -func (_CCIPConfig *CCIPConfigCallerSession) GetCapabilityConfiguration(arg0 uint32) ([]byte, error) { - return _CCIPConfig.Contract.GetCapabilityConfiguration(&_CCIPConfig.CallOpts, arg0) -} - -func (_CCIPConfig *CCIPConfigCaller) GetCapabilityRegistry(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _CCIPConfig.contract.Call(opts, &out, "getCapabilityRegistry") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -func (_CCIPConfig *CCIPConfigSession) GetCapabilityRegistry() (common.Address, error) { - return _CCIPConfig.Contract.GetCapabilityRegistry(&_CCIPConfig.CallOpts) -} - -func (_CCIPConfig *CCIPConfigCallerSession) GetCapabilityRegistry() (common.Address, error) { - return _CCIPConfig.Contract.GetCapabilityRegistry(&_CCIPConfig.CallOpts) -} - -func (_CCIPConfig *CCIPConfigCaller) GetOCRConfig(opts *bind.CallOpts, donId uint32, pluginType uint8) ([]CCIPConfigTypesOCR3ConfigWithMeta, error) { - var out []interface{} - err := _CCIPConfig.contract.Call(opts, &out, "getOCRConfig", donId, pluginType) - - if err != nil { - return *new([]CCIPConfigTypesOCR3ConfigWithMeta), err - } - - out0 := *abi.ConvertType(out[0], new([]CCIPConfigTypesOCR3ConfigWithMeta)).(*[]CCIPConfigTypesOCR3ConfigWithMeta) - - return out0, err - -} - -func (_CCIPConfig *CCIPConfigSession) GetOCRConfig(donId uint32, pluginType uint8) ([]CCIPConfigTypesOCR3ConfigWithMeta, error) { - return _CCIPConfig.Contract.GetOCRConfig(&_CCIPConfig.CallOpts, donId, pluginType) -} - -func (_CCIPConfig *CCIPConfigCallerSession) GetOCRConfig(donId uint32, pluginType uint8) ([]CCIPConfigTypesOCR3ConfigWithMeta, error) { - return _CCIPConfig.Contract.GetOCRConfig(&_CCIPConfig.CallOpts, donId, pluginType) -} - -func (_CCIPConfig *CCIPConfigCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _CCIPConfig.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 (_CCIPConfig *CCIPConfigSession) Owner() (common.Address, error) { - return _CCIPConfig.Contract.Owner(&_CCIPConfig.CallOpts) -} - -func (_CCIPConfig *CCIPConfigCallerSession) Owner() (common.Address, error) { - return _CCIPConfig.Contract.Owner(&_CCIPConfig.CallOpts) -} - -func (_CCIPConfig *CCIPConfigCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { - var out []interface{} - err := _CCIPConfig.contract.Call(opts, &out, "supportsInterface", interfaceId) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -func (_CCIPConfig *CCIPConfigSession) SupportsInterface(interfaceId [4]byte) (bool, error) { - return _CCIPConfig.Contract.SupportsInterface(&_CCIPConfig.CallOpts, interfaceId) -} - -func (_CCIPConfig *CCIPConfigCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { - return _CCIPConfig.Contract.SupportsInterface(&_CCIPConfig.CallOpts, interfaceId) -} - -func (_CCIPConfig *CCIPConfigCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { - var out []interface{} - err := _CCIPConfig.contract.Call(opts, &out, "typeAndVersion") - - if err != nil { - return *new(string), err - } - - out0 := *abi.ConvertType(out[0], new(string)).(*string) - - return out0, err - -} - -func (_CCIPConfig *CCIPConfigSession) TypeAndVersion() (string, error) { - return _CCIPConfig.Contract.TypeAndVersion(&_CCIPConfig.CallOpts) -} - -func (_CCIPConfig *CCIPConfigCallerSession) TypeAndVersion() (string, error) { - return _CCIPConfig.Contract.TypeAndVersion(&_CCIPConfig.CallOpts) -} - -func (_CCIPConfig *CCIPConfigTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _CCIPConfig.contract.Transact(opts, "acceptOwnership") -} - -func (_CCIPConfig *CCIPConfigSession) AcceptOwnership() (*types.Transaction, error) { - return _CCIPConfig.Contract.AcceptOwnership(&_CCIPConfig.TransactOpts) -} - -func (_CCIPConfig *CCIPConfigTransactorSession) AcceptOwnership() (*types.Transaction, error) { - return _CCIPConfig.Contract.AcceptOwnership(&_CCIPConfig.TransactOpts) -} - -func (_CCIPConfig *CCIPConfigTransactor) ApplyChainConfigUpdates(opts *bind.TransactOpts, chainSelectorRemoves []uint64, chainConfigAdds []CCIPConfigTypesChainConfigInfo) (*types.Transaction, error) { - return _CCIPConfig.contract.Transact(opts, "applyChainConfigUpdates", chainSelectorRemoves, chainConfigAdds) -} - -func (_CCIPConfig *CCIPConfigSession) ApplyChainConfigUpdates(chainSelectorRemoves []uint64, chainConfigAdds []CCIPConfigTypesChainConfigInfo) (*types.Transaction, error) { - return _CCIPConfig.Contract.ApplyChainConfigUpdates(&_CCIPConfig.TransactOpts, chainSelectorRemoves, chainConfigAdds) -} - -func (_CCIPConfig *CCIPConfigTransactorSession) ApplyChainConfigUpdates(chainSelectorRemoves []uint64, chainConfigAdds []CCIPConfigTypesChainConfigInfo) (*types.Transaction, error) { - return _CCIPConfig.Contract.ApplyChainConfigUpdates(&_CCIPConfig.TransactOpts, chainSelectorRemoves, chainConfigAdds) -} - -func (_CCIPConfig *CCIPConfigTransactor) BeforeCapabilityConfigSet(opts *bind.TransactOpts, arg0 [][32]byte, config []byte, arg2 uint64, donId uint32) (*types.Transaction, error) { - return _CCIPConfig.contract.Transact(opts, "beforeCapabilityConfigSet", arg0, config, arg2, donId) -} - -func (_CCIPConfig *CCIPConfigSession) BeforeCapabilityConfigSet(arg0 [][32]byte, config []byte, arg2 uint64, donId uint32) (*types.Transaction, error) { - return _CCIPConfig.Contract.BeforeCapabilityConfigSet(&_CCIPConfig.TransactOpts, arg0, config, arg2, donId) -} - -func (_CCIPConfig *CCIPConfigTransactorSession) BeforeCapabilityConfigSet(arg0 [][32]byte, config []byte, arg2 uint64, donId uint32) (*types.Transaction, error) { - return _CCIPConfig.Contract.BeforeCapabilityConfigSet(&_CCIPConfig.TransactOpts, arg0, config, arg2, donId) -} - -func (_CCIPConfig *CCIPConfigTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _CCIPConfig.contract.Transact(opts, "transferOwnership", to) -} - -func (_CCIPConfig *CCIPConfigSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _CCIPConfig.Contract.TransferOwnership(&_CCIPConfig.TransactOpts, to) -} - -func (_CCIPConfig *CCIPConfigTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _CCIPConfig.Contract.TransferOwnership(&_CCIPConfig.TransactOpts, to) -} - -type CCIPConfigCapabilityConfigurationSetIterator struct { - Event *CCIPConfigCapabilityConfigurationSet - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *CCIPConfigCapabilityConfigurationSetIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(CCIPConfigCapabilityConfigurationSet) - 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(CCIPConfigCapabilityConfigurationSet) - 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 *CCIPConfigCapabilityConfigurationSetIterator) Error() error { - return it.fail -} - -func (it *CCIPConfigCapabilityConfigurationSetIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type CCIPConfigCapabilityConfigurationSet struct { - Raw types.Log -} - -func (_CCIPConfig *CCIPConfigFilterer) FilterCapabilityConfigurationSet(opts *bind.FilterOpts) (*CCIPConfigCapabilityConfigurationSetIterator, error) { - - logs, sub, err := _CCIPConfig.contract.FilterLogs(opts, "CapabilityConfigurationSet") - if err != nil { - return nil, err - } - return &CCIPConfigCapabilityConfigurationSetIterator{contract: _CCIPConfig.contract, event: "CapabilityConfigurationSet", logs: logs, sub: sub}, nil -} - -func (_CCIPConfig *CCIPConfigFilterer) WatchCapabilityConfigurationSet(opts *bind.WatchOpts, sink chan<- *CCIPConfigCapabilityConfigurationSet) (event.Subscription, error) { - - logs, sub, err := _CCIPConfig.contract.WatchLogs(opts, "CapabilityConfigurationSet") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(CCIPConfigCapabilityConfigurationSet) - if err := _CCIPConfig.contract.UnpackLog(event, "CapabilityConfigurationSet", 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 (_CCIPConfig *CCIPConfigFilterer) ParseCapabilityConfigurationSet(log types.Log) (*CCIPConfigCapabilityConfigurationSet, error) { - event := new(CCIPConfigCapabilityConfigurationSet) - if err := _CCIPConfig.contract.UnpackLog(event, "CapabilityConfigurationSet", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type CCIPConfigChainConfigRemovedIterator struct { - Event *CCIPConfigChainConfigRemoved - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *CCIPConfigChainConfigRemovedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(CCIPConfigChainConfigRemoved) - 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(CCIPConfigChainConfigRemoved) - 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 *CCIPConfigChainConfigRemovedIterator) Error() error { - return it.fail -} - -func (it *CCIPConfigChainConfigRemovedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type CCIPConfigChainConfigRemoved struct { - ChainSelector uint64 - Raw types.Log -} - -func (_CCIPConfig *CCIPConfigFilterer) FilterChainConfigRemoved(opts *bind.FilterOpts) (*CCIPConfigChainConfigRemovedIterator, error) { - - logs, sub, err := _CCIPConfig.contract.FilterLogs(opts, "ChainConfigRemoved") - if err != nil { - return nil, err - } - return &CCIPConfigChainConfigRemovedIterator{contract: _CCIPConfig.contract, event: "ChainConfigRemoved", logs: logs, sub: sub}, nil -} - -func (_CCIPConfig *CCIPConfigFilterer) WatchChainConfigRemoved(opts *bind.WatchOpts, sink chan<- *CCIPConfigChainConfigRemoved) (event.Subscription, error) { - - logs, sub, err := _CCIPConfig.contract.WatchLogs(opts, "ChainConfigRemoved") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(CCIPConfigChainConfigRemoved) - if err := _CCIPConfig.contract.UnpackLog(event, "ChainConfigRemoved", 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 (_CCIPConfig *CCIPConfigFilterer) ParseChainConfigRemoved(log types.Log) (*CCIPConfigChainConfigRemoved, error) { - event := new(CCIPConfigChainConfigRemoved) - if err := _CCIPConfig.contract.UnpackLog(event, "ChainConfigRemoved", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type CCIPConfigChainConfigSetIterator struct { - Event *CCIPConfigChainConfigSet - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *CCIPConfigChainConfigSetIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(CCIPConfigChainConfigSet) - 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(CCIPConfigChainConfigSet) - 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 *CCIPConfigChainConfigSetIterator) Error() error { - return it.fail -} - -func (it *CCIPConfigChainConfigSetIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type CCIPConfigChainConfigSet struct { - ChainSelector uint64 - ChainConfig CCIPConfigTypesChainConfig - Raw types.Log -} - -func (_CCIPConfig *CCIPConfigFilterer) FilterChainConfigSet(opts *bind.FilterOpts) (*CCIPConfigChainConfigSetIterator, error) { - - logs, sub, err := _CCIPConfig.contract.FilterLogs(opts, "ChainConfigSet") - if err != nil { - return nil, err - } - return &CCIPConfigChainConfigSetIterator{contract: _CCIPConfig.contract, event: "ChainConfigSet", logs: logs, sub: sub}, nil -} - -func (_CCIPConfig *CCIPConfigFilterer) WatchChainConfigSet(opts *bind.WatchOpts, sink chan<- *CCIPConfigChainConfigSet) (event.Subscription, error) { - - logs, sub, err := _CCIPConfig.contract.WatchLogs(opts, "ChainConfigSet") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(CCIPConfigChainConfigSet) - if err := _CCIPConfig.contract.UnpackLog(event, "ChainConfigSet", 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 (_CCIPConfig *CCIPConfigFilterer) ParseChainConfigSet(log types.Log) (*CCIPConfigChainConfigSet, error) { - event := new(CCIPConfigChainConfigSet) - if err := _CCIPConfig.contract.UnpackLog(event, "ChainConfigSet", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type CCIPConfigOwnershipTransferRequestedIterator struct { - Event *CCIPConfigOwnershipTransferRequested - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *CCIPConfigOwnershipTransferRequestedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(CCIPConfigOwnershipTransferRequested) - 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(CCIPConfigOwnershipTransferRequested) - 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 *CCIPConfigOwnershipTransferRequestedIterator) Error() error { - return it.fail -} - -func (it *CCIPConfigOwnershipTransferRequestedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type CCIPConfigOwnershipTransferRequested struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_CCIPConfig *CCIPConfigFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CCIPConfigOwnershipTransferRequestedIterator, 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 := _CCIPConfig.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) - if err != nil { - return nil, err - } - return &CCIPConfigOwnershipTransferRequestedIterator{contract: _CCIPConfig.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil -} - -func (_CCIPConfig *CCIPConfigFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CCIPConfigOwnershipTransferRequested, 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 := _CCIPConfig.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(CCIPConfigOwnershipTransferRequested) - if err := _CCIPConfig.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 (_CCIPConfig *CCIPConfigFilterer) ParseOwnershipTransferRequested(log types.Log) (*CCIPConfigOwnershipTransferRequested, error) { - event := new(CCIPConfigOwnershipTransferRequested) - if err := _CCIPConfig.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type CCIPConfigOwnershipTransferredIterator struct { - Event *CCIPConfigOwnershipTransferred - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *CCIPConfigOwnershipTransferredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(CCIPConfigOwnershipTransferred) - 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(CCIPConfigOwnershipTransferred) - 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 *CCIPConfigOwnershipTransferredIterator) Error() error { - return it.fail -} - -func (it *CCIPConfigOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type CCIPConfigOwnershipTransferred struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_CCIPConfig *CCIPConfigFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CCIPConfigOwnershipTransferredIterator, 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 := _CCIPConfig.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) - if err != nil { - return nil, err - } - return &CCIPConfigOwnershipTransferredIterator{contract: _CCIPConfig.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} - -func (_CCIPConfig *CCIPConfigFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CCIPConfigOwnershipTransferred, 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 := _CCIPConfig.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(CCIPConfigOwnershipTransferred) - if err := _CCIPConfig.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 (_CCIPConfig *CCIPConfigFilterer) ParseOwnershipTransferred(log types.Log) (*CCIPConfigOwnershipTransferred, error) { - event := new(CCIPConfigOwnershipTransferred) - if err := _CCIPConfig.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -func (_CCIPConfig *CCIPConfig) ParseLog(log types.Log) (generated.AbigenLog, error) { - switch log.Topics[0] { - case _CCIPConfig.abi.Events["CapabilityConfigurationSet"].ID: - return _CCIPConfig.ParseCapabilityConfigurationSet(log) - case _CCIPConfig.abi.Events["ChainConfigRemoved"].ID: - return _CCIPConfig.ParseChainConfigRemoved(log) - case _CCIPConfig.abi.Events["ChainConfigSet"].ID: - return _CCIPConfig.ParseChainConfigSet(log) - case _CCIPConfig.abi.Events["OwnershipTransferRequested"].ID: - return _CCIPConfig.ParseOwnershipTransferRequested(log) - case _CCIPConfig.abi.Events["OwnershipTransferred"].ID: - return _CCIPConfig.ParseOwnershipTransferred(log) - - default: - return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) - } -} - -func (CCIPConfigCapabilityConfigurationSet) Topic() common.Hash { - return common.HexToHash("0x84ad7751b744c9e2ee77da1d902b428aec7f0a343d67a24bbe2142e6f58a8d0f") -} - -func (CCIPConfigChainConfigRemoved) Topic() common.Hash { - return common.HexToHash("0x2a680691fef3b2d105196805935232c661ce703e92d464ef0b94a7bc62d714f0") -} - -func (CCIPConfigChainConfigSet) Topic() common.Hash { - return common.HexToHash("0x05dd57854af2c291a94ea52e7c43d80bc3be7fa73022f98b735dea86642fa5e0") -} - -func (CCIPConfigOwnershipTransferRequested) Topic() common.Hash { - return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") -} - -func (CCIPConfigOwnershipTransferred) Topic() common.Hash { - return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") -} - -func (_CCIPConfig *CCIPConfig) Address() common.Address { - return _CCIPConfig.address -} - -type CCIPConfigInterface interface { - GetAllChainConfigs(opts *bind.CallOpts, pageIndex *big.Int, pageSize *big.Int) ([]CCIPConfigTypesChainConfigInfo, error) - - GetCapabilityConfiguration(opts *bind.CallOpts, arg0 uint32) ([]byte, error) - - GetCapabilityRegistry(opts *bind.CallOpts) (common.Address, error) - - GetOCRConfig(opts *bind.CallOpts, donId uint32, pluginType uint8) ([]CCIPConfigTypesOCR3ConfigWithMeta, error) - - Owner(opts *bind.CallOpts) (common.Address, error) - - SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) - - TypeAndVersion(opts *bind.CallOpts) (string, error) - - AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) - - ApplyChainConfigUpdates(opts *bind.TransactOpts, chainSelectorRemoves []uint64, chainConfigAdds []CCIPConfigTypesChainConfigInfo) (*types.Transaction, error) - - BeforeCapabilityConfigSet(opts *bind.TransactOpts, arg0 [][32]byte, config []byte, arg2 uint64, donId uint32) (*types.Transaction, error) - - TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) - - FilterCapabilityConfigurationSet(opts *bind.FilterOpts) (*CCIPConfigCapabilityConfigurationSetIterator, error) - - WatchCapabilityConfigurationSet(opts *bind.WatchOpts, sink chan<- *CCIPConfigCapabilityConfigurationSet) (event.Subscription, error) - - ParseCapabilityConfigurationSet(log types.Log) (*CCIPConfigCapabilityConfigurationSet, error) - - FilterChainConfigRemoved(opts *bind.FilterOpts) (*CCIPConfigChainConfigRemovedIterator, error) - - WatchChainConfigRemoved(opts *bind.WatchOpts, sink chan<- *CCIPConfigChainConfigRemoved) (event.Subscription, error) - - ParseChainConfigRemoved(log types.Log) (*CCIPConfigChainConfigRemoved, error) - - FilterChainConfigSet(opts *bind.FilterOpts) (*CCIPConfigChainConfigSetIterator, error) - - WatchChainConfigSet(opts *bind.WatchOpts, sink chan<- *CCIPConfigChainConfigSet) (event.Subscription, error) - - ParseChainConfigSet(log types.Log) (*CCIPConfigChainConfigSet, error) - - FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CCIPConfigOwnershipTransferRequestedIterator, error) - - WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CCIPConfigOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) - - ParseOwnershipTransferRequested(log types.Log) (*CCIPConfigOwnershipTransferRequested, error) - - FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CCIPConfigOwnershipTransferredIterator, error) - - WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CCIPConfigOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) - - ParseOwnershipTransferred(log types.Log) (*CCIPConfigOwnershipTransferred, error) - - ParseLog(log types.Log) (generated.AbigenLog, error) - - Address() common.Address -} diff --git a/core/gethwrappers/ccip/generated/ccip_home/ccip_home.go b/core/gethwrappers/ccip/generated/ccip_home/ccip_home.go index b44dc9a5f96..7ea7f633147 100644 --- a/core/gethwrappers/ccip/generated/ccip_home/ccip_home.go +++ b/core/gethwrappers/ccip/generated/ccip_home/ccip_home.go @@ -65,8 +65,8 @@ type CCIPHomeVersionedConfig struct { } var CCIPHomeMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"capabilitiesRegistry\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainSelectorNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ChainSelectorNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expectedConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"gotConfigDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"callDonId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"capabilityRegistryDonId\",\"type\":\"uint32\"}],\"name\":\"DONIdMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FChainMustBePositive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fChain\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"FRoleDON\",\"type\":\"uint256\"}],\"name\":\"FChainTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node\",\"name\":\"node\",\"type\":\"tuple\"}],\"name\":\"InvalidNode\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPluginType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"}],\"name\":\"InvalidSelector\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoOpStateTransitionNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimum\",\"type\":\"uint256\"}],\"name\":\"NotEnoughTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OfframpAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCapabilitiesRegistryCanCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RMNHomeAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RevokingZeroDigestNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManySigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ActiveConfigRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"CandidateConfigRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CapabilityConfigurationSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainConfigRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structCCIPHome.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigPromoted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"FRoleDON\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rmnHomeAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structCCIPHome.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"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\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"chainSelectorRemoves\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPHome.ChainConfigArgs[]\",\"name\":\"chainConfigAdds\",\"type\":\"tuple[]\"}],\"name\":\"applyChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"update\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"beforeCapabilityConfigSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getActiveDigest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"pageIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"pageSize\",\"type\":\"uint256\"}],\"name\":\"getAllChainConfigs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPHome.ChainConfigArgs[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getAllConfigs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"FRoleDON\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rmnHomeAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPHome.VersionedConfig\",\"name\":\"activeConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"FRoleDON\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rmnHomeAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPHome.VersionedConfig\",\"name\":\"candidateConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getCandidateDigest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"getCapabilityConfiguration\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"configuration\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilityRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"FRoleDON\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rmnHomeAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPHome.VersionedConfig\",\"name\":\"versionedConfig\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"ok\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getConfigDigests\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"activeConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"candidateConfigDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNumChainConfigurations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"digestToPromote\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"digestToRevoke\",\"type\":\"bytes32\"}],\"name\":\"promoteCandidateAndRevokeActive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"revokeCandidate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"FRoleDON\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rmnHomeAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"digestToOverwrite\",\"type\":\"bytes32\"}],\"name\":\"setCandidate\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"newConfigDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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: "0x60a06040526006805463ffffffff191690553480156200001e57600080fd5b5060405162004c7a38038062004c7a83398101604081905262000041916200014c565b336000816200006357604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038481169190911790915581161562000096576200009681620000d2565b50506001600160a01b038116620000c0576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03166080526200017e565b336001600160a01b03821603620000fc57604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200015f57600080fd5b81516001600160a01b03811681146200017757600080fd5b9392505050565b608051614ad2620001a860003960008181610180015281816121eb0152612c450152614ad26000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c806379ba5097116100cd578063b74b235611610081578063f2fde38b11610066578063f2fde38b14610356578063f442c89a14610369578063fba64a7c1461037c57600080fd5b8063b74b235614610323578063bae4e0fa1461034357600080fd5b80638318ed5d116100b25780638318ed5d146102d15780638da5cb5b146102f2578063922ea4061461031057600080fd5b806379ba5097146102c15780637ac0d41e146102c957600080fd5b80633df45a72116101245780635a837f97116101095780635a837f97146102785780635f1edd9c1461028d5780637524051a146102ae57600080fd5b80633df45a721461022f5780634851d5491461025057600080fd5b806301ffc9a714610156578063020330e61461017e578063181f5a77146101c557806333d9704a1461020e575b600080fd5b610169610164366004612fb2565b61038f565b60405190151581526020015b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610175565b6102016040518060400160405280601281526020017f43434950486f6d6520312e362e302d646576000000000000000000000000000081525081565b6040516101759190613044565b61022161021c366004613091565b610428565b6040516101759291906132d8565b61024261023d3660046132fc565b610922565b604051610175929190613335565b61026361025e3660046132fc565b611222565b60408051928352602083019190915201610175565b61028b61028636600461335a565b611318565b005b6102a061029b3660046132fc565b61162b565b604051908152602001610175565b61028b6102bc366004613091565b6116a2565b61028b61188d565b6102a061195b565b6102016102df3660046133a0565b5060408051602081019091526000815290565b60015473ffffffffffffffffffffffffffffffffffffffff166101a0565b6102a061031e3660046132fc565b61196c565b6103366103313660046133bd565b6119bd565b6040516101759190613456565b6102a06103513660046134f4565b611c22565b61028b610364366004613564565b611e20565b61028b6103773660046135df565b611e34565b61028b61038a36600461366c565b6121d3565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f78bea72100000000000000000000000000000000000000000000000000000000148061042257507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b610430612e3b565b6000805b60028110156109145763ffffffff861660009081526005602052604081208591876001811115610466576104666130d2565b6001811115610477576104776130d2565b8152602001908152602001600020826002811061049657610496613729565b60070201600101541480156104aa57508315155b1561090c5763ffffffff86166000908152600560205260408120908660018111156104d7576104d76130d2565b60018111156104e8576104e86130d2565b8152602001908152602001600020816002811061050757610507613729565b6040805160608101825260079290920292909201805463ffffffff1682526001808201546020840152835161010081018552600283018054939592949386938501929190829060ff1687811115610560576105606130d2565b6001811115610571576105716130d2565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a01000000000000000000009091041660608201526001820180546080909201916105c990613758565b80601f01602080910402602001604051908101604052809291908181526020018280546105f590613758565b80156106425780601f1061061757610100808354040283529160200191610642565b820191906000526020600020905b81548152906001019060200180831161062557829003601f168201915b5050505050815260200160028201805461065b90613758565b80601f016020809104026020016040519081016040528092919081815260200182805461068790613758565b80156106d45780601f106106a9576101008083540402835291602001916106d4565b820191906000526020600020905b8154815290600101906020018083116106b757829003601f168201915b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b8282101561086257838290600052602060002090600302016040518060600160405290816000820154815260200160018201805461073f90613758565b80601f016020809104026020016040519081016040528092919081815260200182805461076b90613758565b80156107b85780601f1061078d576101008083540402835291602001916107b8565b820191906000526020600020905b81548152906001019060200180831161079b57829003601f168201915b505050505081526020016002820180546107d190613758565b80601f01602080910402602001604051908101604052809291908181526020018280546107fd90613758565b801561084a5780601f1061081f5761010080835404028352916020019161084a565b820191906000526020600020905b81548152906001019060200180831161082d57829003601f168201915b50505050508152505081526020019060010190610702565b50505050815260200160048201805461087a90613758565b80601f01602080910402602001604051908101604052809291908181526020018280546108a690613758565b80156108f35780601f106108c8576101008083540402835291602001916108f3565b820191906000526020600020905b8154815290600101906020018083116108d657829003601f168201915b505050505081525050815250509150925092505061091a565b600101610434565b50600090505b935093915050565b61092a612e3b565b610932612e3b565b63ffffffff841660009081526005602052604081208185600181111561095a5761095a6130d2565b600181111561096b5761096b6130d2565b81526020019081526020016000206109838686612490565b63ffffffff166002811061099957610999613729565b6040805160608101825260079290920292909201805463ffffffff1682526001808201546020840152835161010081018552600283018054949593949386019391929091839160ff909116908111156109f4576109f46130d2565b6001811115610a0557610a056130d2565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a0100000000000000000000909104166060820152600182018054608090920191610a5d90613758565b80601f0160208091040260200160405190810160405280929190818152602001828054610a8990613758565b8015610ad65780601f10610aab57610100808354040283529160200191610ad6565b820191906000526020600020905b815481529060010190602001808311610ab957829003601f168201915b50505050508152602001600282018054610aef90613758565b80601f0160208091040260200160405190810160405280929190818152602001828054610b1b90613758565b8015610b685780601f10610b3d57610100808354040283529160200191610b68565b820191906000526020600020905b815481529060010190602001808311610b4b57829003601f168201915b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b82821015610cf6578382906000526020600020906003020160405180606001604052908160008201548152602001600182018054610bd390613758565b80601f0160208091040260200160405190810160405280929190818152602001828054610bff90613758565b8015610c4c5780601f10610c2157610100808354040283529160200191610c4c565b820191906000526020600020905b815481529060010190602001808311610c2f57829003601f168201915b50505050508152602001600282018054610c6590613758565b80601f0160208091040260200160405190810160405280929190818152602001828054610c9190613758565b8015610cde5780601f10610cb357610100808354040283529160200191610cde565b820191906000526020600020905b815481529060010190602001808311610cc157829003601f168201915b50505050508152505081526020019060010190610b96565b505050508152602001600482018054610d0e90613758565b80601f0160208091040260200160405190810160405280929190818152602001828054610d3a90613758565b8015610d875780601f10610d5c57610100808354040283529160200191610d87565b820191906000526020600020905b815481529060010190602001808311610d6a57829003601f168201915b50505091909252505050905250602081015190915015610da5578092505b63ffffffff8516600090815260056020526040812081866001811115610dcd57610dcd6130d2565b6001811115610dde57610dde6130d2565b8152602001908152602001600020610df687876124e7565b63ffffffff1660028110610e0c57610e0c613729565b6040805160608101825260079290920292909201805463ffffffff1682526001808201546020840152835161010081018552600283018054949593949386019391929091839160ff90911690811115610e6757610e676130d2565b6001811115610e7857610e786130d2565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a0100000000000000000000909104166060820152600182018054608090920191610ed090613758565b80601f0160208091040260200160405190810160405280929190818152602001828054610efc90613758565b8015610f495780601f10610f1e57610100808354040283529160200191610f49565b820191906000526020600020905b815481529060010190602001808311610f2c57829003601f168201915b50505050508152602001600282018054610f6290613758565b80601f0160208091040260200160405190810160405280929190818152602001828054610f8e90613758565b8015610fdb5780601f10610fb057610100808354040283529160200191610fdb565b820191906000526020600020905b815481529060010190602001808311610fbe57829003601f168201915b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b8282101561116957838290600052602060002090600302016040518060600160405290816000820154815260200160018201805461104690613758565b80601f016020809104026020016040519081016040528092919081815260200182805461107290613758565b80156110bf5780601f10611094576101008083540402835291602001916110bf565b820191906000526020600020905b8154815290600101906020018083116110a257829003601f168201915b505050505081526020016002820180546110d890613758565b80601f016020809104026020016040519081016040528092919081815260200182805461110490613758565b80156111515780601f1061112657610100808354040283529160200191611151565b820191906000526020600020905b81548152906001019060200180831161113457829003601f168201915b50505050508152505081526020019060010190611009565b50505050815260200160048201805461118190613758565b80601f01602080910402602001604051908101604052809291908181526020018280546111ad90613758565b80156111fa5780601f106111cf576101008083540402835291602001916111fa565b820191906000526020600020905b8154815290600101906020018083116111dd57829003601f168201915b50505091909252505050905250602081015190915015611218578092505b50505b9250929050565b63ffffffff8216600090815260056020526040812081908184600181111561124c5761124c6130d2565b600181111561125d5761125d6130d2565b81526020019081526020016000206112758585612490565b63ffffffff166002811061128b5761128b613729565b6007020160010154600560008663ffffffff1663ffffffff16815260200190815260200160002060008560018111156112c6576112c66130d2565b60018111156112d7576112d76130d2565b81526020019081526020016000206112ef86866124e7565b63ffffffff166002811061130557611305613729565b6007020160010154915091509250929050565b611320612542565b8115801561132c575080155b15611363576040517f7b4d1e4f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061136f85856124e7565b63ffffffff86811660009081526005602052604081209290911692508491908660018111156113a0576113a06130d2565b60018111156113b1576113b16130d2565b815260200190815260200160002082600281106113d0576113d0613729565b6007020160010154146114845763ffffffff8516600090815260056020526040812090856001811115611405576114056130d2565b6001811115611416576114166130d2565b8152602001908152602001600020816002811061143557611435613729565b6007020160010154836040517f93df584c00000000000000000000000000000000000000000000000000000000815260040161147b929190918252602082015260400190565b60405180910390fd5b63ffffffff85166000908152600560205260408120818660018111156114ac576114ac6130d2565b60018111156114bd576114bd6130d2565b81526020019081526020016000206114d58787612490565b63ffffffff16600281106114eb576114eb613729565b6007020190508281600101541461153e5760018101546040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101919091526024810184905260440161147b565b6000600180830182905563ffffffff881682526007602052604082209091878381111561156d5761156d6130d2565b600181111561157e5761157e6130d2565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000811663ffffffff918216939093181691909117905582156115f85760405183907f0b31c0055e2d464bef7781994b98c4ff9ef4ae0d05f59feb6a68c42de5e201b890600090a25b60405184907ffc3e98dbbd47c3fa7c1c05b6ec711caeaf70eca4554192b9ada8fc11a37f298e90600090a2505050505050565b63ffffffff8216600090815260056020526040812081836001811115611653576116536130d2565b6001811115611664576116646130d2565b815260200190815260200160002061167c8484612490565b63ffffffff166002811061169257611692613729565b6007020160010154905092915050565b6116aa612542565b806116e1576040517f0849d8cc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006116ed84846124e7565b63ffffffff858116600090815260056020526040812092909116925083919085600181111561171e5761171e6130d2565b600181111561172f5761172f6130d2565b8152602001908152602001600020826002811061174e5761174e613729565b6007020160010154146117f95763ffffffff8416600090815260056020526040812090846001811115611783576117836130d2565b6001811115611794576117946130d2565b815260200190815260200160002081600281106117b3576117b3613729565b6007020160010154826040517f93df584c00000000000000000000000000000000000000000000000000000000815260040161147b929190918252602082015260400190565b60405182907f53f5d9228f0a4173bea6e5931c9b3afe6eeb6692ede1d182952970f152534e3b90600090a263ffffffff841660009081526005602052604081209084600181111561184c5761184c6130d2565b600181111561185d5761185d6130d2565b8152602001908152602001600020816002811061187c5761187c613729565b600702016001016000905550505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146118de576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6000611967600361257d565b905090565b63ffffffff8216600090815260056020526040812081836001811115611994576119946130d2565b60018111156119a5576119a56130d2565b815260200190815260200160002061167c84846124e7565b606060006119cb600361257d565b905060006119d984866137da565b90508315806119e85750818110155b15611a28576040805160008082526020820190925290611a1e565b611a0b612eb7565b815260200190600190039081611a035790505b5092505050610422565b6000611a348583613820565b905082811115611a415750815b6000611a4d8383613833565b67ffffffffffffffff811115611a6557611a656137f1565b604051908082528060200260200182016040528015611a9e57816020015b611a8b612eb7565b815260200190600190039081611a835790505b509050825b82811015611c17576000611ab8600383612587565b60408051808201825267ffffffffffffffff83168082526000908152600260209081529083902083518154608081850283018101909652606082018181529697509395928601949093919284929091849190840182828015611b3957602002820191906000526020600020905b815481526020019060010190808311611b25575b5050509183525050600182015460ff166020820152600282018054604090920191611b6390613758565b80601f0160208091040260200160405190810160405280929190818152602001828054611b8f90613758565b8015611bdc5780601f10611bb157610100808354040283529160200191611bdc565b820191906000526020600020905b815481529060010190602001808311611bbf57829003601f168201915b50505091909252505050905283611bf38785613833565b81518110611c0357611c03613729565b602090810291909101015250600101611aa3565b509695505050505050565b6000611c2c612542565b611c3d611c3884613a61565b61259a565b6000611c49868661196c565b9050828114611c8e576040517f93df584c000000000000000000000000000000000000000000000000000000008152600481018290526024810184905260440161147b565b8015611cc05760405183907f53f5d9228f0a4173bea6e5931c9b3afe6eeb6692ede1d182952970f152534e3b90600090a25b60068054600091908290611cd99063ffffffff16613b5d565b91906101000a81548163ffffffff021916908363ffffffff16021790559050611d23878787604051602001611d0e9190613e39565b60405160208183030381529060405284612a08565b63ffffffff881660009081526005602052604081209194509081886001811115611d4f57611d4f6130d2565b6001811115611d6057611d606130d2565b8152602001908152602001600020611d7889896124e7565b63ffffffff1660028110611d8e57611d8e613729565b600702016001810185905580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff841617815590508560028201611dd8828261431f565b905050837f94f085b7c57ec2a270befd0b7b2ec7452580040edee8bb0fb04609c81f0359c68388604051611e0d9291906144e6565b60405180910390a2505050949350505050565b611e28612ac8565b611e3181612b19565b50565b611e3c612ac8565b60005b8381101561202257611e83858583818110611e5c57611e5c613729565b9050602002016020810190611e71919061450d565b60039067ffffffffffffffff16612bdd565b611eed57848482818110611e9957611e99613729565b9050602002016020810190611eae919061450d565b6040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161147b565b60026000868684818110611f0357611f03613729565b9050602002016020810190611f18919061450d565b67ffffffffffffffff1681526020810191909152604001600090812090611f3f8282612efa565b6001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055611f77600283016000612f18565b5050611fb5858583818110611f8e57611f8e613729565b9050602002016020810190611fa3919061450d565b60039067ffffffffffffffff16612bf5565b507f2a680691fef3b2d105196805935232c661ce703e92d464ef0b94a7bc62d714f0858583818110611fe957611fe9613729565b9050602002016020810190611ffe919061450d565b60405167ffffffffffffffff909116815260200160405180910390a1600101611e3f565b5060005b818110156121cc57600083838381811061204257612042613729565b9050602002810190612054919061452a565b612062906020810190614082565b61206b9061455e565b9050600084848481811061208157612081613729565b9050602002810190612093919061452a565b6120a190602081019061450d565b90506120b08260000151612c01565b816020015160ff166000036120f1576040517fa9b3766e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600260209081526040909120835180518593612121928492910190612f52565b5060208201516001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff9092169190911790556040820151600282019061216e9082614630565b5061218891506003905067ffffffffffffffff8316612cc3565b507f05dd57854af2c291a94ea52e7c43d80bc3be7fa73022f98b735dea86642fa5e081836040516121ba92919061472c565b60405180910390a15050600101612026565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614612242576040517fac7a7efd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612251600482868861474f565b61225a91614779565b90507fffffffff0000000000000000000000000000000000000000000000000000000081167fbae4e0fa00000000000000000000000000000000000000000000000000000000148015906122f057507fffffffff0000000000000000000000000000000000000000000000000000000081167f7524051a0000000000000000000000000000000000000000000000000000000014155b801561233e57507fffffffff0000000000000000000000000000000000000000000000000000000081167f5a837f970000000000000000000000000000000000000000000000000000000014155b15612399576040517f12ba286f0000000000000000000000000000000000000000000000000000000081527fffffffff000000000000000000000000000000000000000000000000000000008216600482015260240161147b565b60006123a960246004878961474f565b8101906123b691906147c1565b90508263ffffffff168114612407576040517f8a6e4ce800000000000000000000000000000000000000000000000000000000815263ffffffff80831660048301528416602482015260440161147b565b6000803073ffffffffffffffffffffffffffffffffffffffff1688886040516124319291906147da565b6000604051808303816000865af19150503d806000811461246e576040519150601f19603f3d011682016040523d82523d6000602084013e612473565b606091505b509150915081612484573d60208201fd5b50505050505050505050565b63ffffffff82166000908152600760205260408120818360018111156124b8576124b86130d2565b60018111156124c9576124c96130d2565b815260208101919091526040016000205463ffffffff169392505050565b63ffffffff821660009081526007602052604081208183600181111561250f5761250f6130d2565b6001811115612520576125206130d2565b815260208101919091526040016000205463ffffffff16600118905092915050565b33301461257b576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6000610422825490565b60006125938383612ccf565b9392505050565b806020015167ffffffffffffffff166000036125e2576040517f698cf8e000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815160018111156125f7576125f76130d2565b141580156126185750600181516001811115612615576126156130d2565b14155b1561264f576040517f3302dbd700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b608081015151158061268c575060408051600060208201520160405160208183030381529060405280519060200120816080015180519060200120145b156126c3576040517f358c192700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a08101515115806127005750604080516000602082015201604051602081830303815290604052805190602001208160a0015180519060200120145b15612737576040517fdee9857400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101516127529060039067ffffffffffffffff16612bdd565b61279a5760208101516040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161147b565b60408082015160208084015167ffffffffffffffff1660009081526002909152919091206001015460ff91821691168181111561280d576040517f2db22040000000000000000000000000000000000000000000000000000000008152600481018290526024810183905260440161147b565b60c08301515161010081111561284f576040517f1b925da600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61285a8360036137da565b8111612892576040517f4856694e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808267ffffffffffffffff8111156128ae576128ae6137f1565b6040519080825280602002602001820160405280156128d7578160200160208202803683370190505b50905060005b838110156129975760008760c0015182815181106128fd576128fd613729565b60200260200101519050806040015151600014612922578361291e816147ea565b9450505b602081015151158061293357508051155b1561296c57806040517f9fa4031400000000000000000000000000000000000000000000000000000000815260040161147b9190614822565b806000015183838151811061298357612983613729565b6020908102919091010152506001016128dd565b5060006129a58560036137da565b6129b0906001613820565b9050808310156129f6576040517f548dd21f000000000000000000000000000000000000000000000000000000008152600481018490526024810182905260440161147b565b6129ff82612c01565b50505050505050565b6040516000907dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90612a66907f45564d000000000000000000000000000000000000000000000000000000000090469030908a908a908990602001614835565b60408051601f1981840301815290829052612a8591869060200161488e565b60408051808303601f190181529190528051602090910120167e0a0000000000000000000000000000000000000000000000000000000000001795945050505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461257b576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603612b68576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120541515612593565b60006125938383612cf9565b805115611e31576040517f05a5196600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906305a5196690612c7a9084906004016148bd565b600060405180830381865afa158015612c97573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612cbf919081019061493a565b5050565b60006125938383612dec565b6000826000018281548110612ce657612ce6613729565b9060005260206000200154905092915050565b60008181526001830160205260408120548015612de2576000612d1d600183613833565b8554909150600090612d3190600190613833565b9050808214612d96576000866000018281548110612d5157612d51613729565b9060005260206000200154905080876000018481548110612d7457612d74613729565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612da757612da7614a96565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610422565b6000915050610422565b6000818152600183016020526040812054612e3357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610422565b506000610422565b6040805160608101825260008082526020820152908101612eb26040805161010081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff168152602001606081526020016060815260200160608152602001606081525090565b905290565b6040518060400160405280600067ffffffffffffffff168152602001612eb2604051806060016040528060608152602001600060ff168152602001606081525090565b5080546000825590600052602060002090810190611e319190612f9d565b508054612f2490613758565b6000825580601f10612f34575050565b601f016020900490600052602060002090810190611e319190612f9d565b828054828255906000526020600020908101928215612f8d579160200282015b82811115612f8d578251825591602001919060010190612f72565b50612f99929150612f9d565b5090565b5b80821115612f995760008155600101612f9e565b600060208284031215612fc457600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461259357600080fd5b60005b8381101561300f578181015183820152602001612ff7565b50506000910152565b60008151808452613030816020860160208601612ff4565b601f01601f19169290920160200192915050565b6020815260006125936020830184613018565b63ffffffff81168114611e3157600080fd5b803561307481613057565b919050565b60028110611e3157600080fd5b803561307481613079565b6000806000606084860312156130a657600080fd5b83356130b181613057565b925060208401356130c181613079565b929592945050506040919091013590565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60028110613138577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b80518252600060208201516060602085015261315b6060850182613018565b9050604083015184820360408601526131748282613018565b95945050505050565b60008282518085526020808601955060208260051b8401016020860160005b848110156131ca57601f198684030189526131b883835161313c565b9884019892509083019060010161319c565b5090979650505050505050565b63ffffffff8151168252602081015160208301526000604082015160606040850152613207606085018251613101565b602081015167ffffffffffffffff8116608086015250604081015160ff811660a086015250606081015167ffffffffffffffff811660c08601525060808101516101008060e087015261325e610160870183613018565b915060a08301517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08088850301838901526132998483613018565b935060c0850151925080888503016101208901526132b7848461317d565b935060e0850151945080888503016101408901525050506131748183613018565b6040815260006132eb60408301856131d7565b905082151560208301529392505050565b6000806040838503121561330f57600080fd5b823561331a81613057565b9150602083013561332a81613079565b809150509250929050565b60408152600061334860408301856131d7565b828103602084015261317481856131d7565b6000806000806080858703121561337057600080fd5b843561337b81613057565b9350602085013561338b81613079565b93969395505050506040820135916060013590565b6000602082840312156133b257600080fd5b813561259381613057565b600080604083850312156133d057600080fd5b50508035926020909101359150565b60008151808452602080850194506020840160005b83811015613410578151875295820195908201906001016133f4565b509495945050505050565b600081516060845261343060608501826133df565b905060ff6020840151166020850152604083015184820360408601526131748282613018565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b838110156134e6578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805167ffffffffffffffff1684528701518784018790526134d38785018261341b565b958801959350509086019060010161347f565b509098975050505050505050565b6000806000806080858703121561350a57600080fd5b843561351581613057565b9350602085013561352581613079565b9250604085013567ffffffffffffffff81111561354157600080fd5b8501610100818803121561355457600080fd5b9396929550929360600135925050565b60006020828403121561357657600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461259357600080fd5b60008083601f8401126135ac57600080fd5b50813567ffffffffffffffff8111156135c457600080fd5b6020830191508360208260051b850101111561121b57600080fd5b600080600080604085870312156135f557600080fd5b843567ffffffffffffffff8082111561360d57600080fd5b6136198883890161359a565b9096509450602087013591508082111561363257600080fd5b5061363f8782880161359a565b95989497509550505050565b67ffffffffffffffff81168114611e3157600080fd5b80356130748161364b565b6000806000806000806080878903121561368557600080fd5b863567ffffffffffffffff8082111561369d57600080fd5b6136a98a838b0161359a565b909850965060208901359150808211156136c257600080fd5b818901915089601f8301126136d657600080fd5b8135818111156136e557600080fd5b8a60208285010111156136f757600080fd5b60208301965080955050505061370f60408801613661565b915061371d60608801613069565b90509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c9082168061376c57607f821691505b6020821081036137a5577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610422576104226137ab565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b80820180821115610422576104226137ab565b81810381811115610422576104226137ab565b6040516060810167ffffffffffffffff81118282101715613869576138696137f1565b60405290565b604051610100810167ffffffffffffffff81118282101715613869576138696137f1565b604051601f8201601f1916810167ffffffffffffffff811182821017156138bc576138bc6137f1565b604052919050565b60ff81168114611e3157600080fd5b8035613074816138c4565b600082601f8301126138ef57600080fd5b813567ffffffffffffffff811115613909576139096137f1565b61391c6020601f19601f84011601613893565b81815284602083860101111561393157600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff821115613968576139686137f1565b5060051b60200190565b600082601f83011261398357600080fd5b813560206139986139938361394e565b613893565b82815260059290921b840181019181810190868411156139b757600080fd5b8286015b84811015611c1757803567ffffffffffffffff808211156139dc5760008081fd5b8189019150606080601f19848d030112156139f75760008081fd5b6139ff613846565b87840135815260408085013584811115613a195760008081fd5b613a278e8b838901016138de565b838b015250918401359183831115613a3f5760008081fd5b613a4d8d8a858801016138de565b9082015286525050509183019183016139bb565b60006101008236031215613a7457600080fd5b613a7c61386f565b613a8583613086565b8152613a9360208401613661565b6020820152613aa4604084016138d3565b6040820152613ab560608401613661565b6060820152608083013567ffffffffffffffff80821115613ad557600080fd5b613ae1368387016138de565b608084015260a0850135915080821115613afa57600080fd5b613b06368387016138de565b60a084015260c0850135915080821115613b1f57600080fd5b613b2b36838701613972565b60c084015260e0850135915080821115613b4457600080fd5b50613b51368286016138de565b60e08301525092915050565b600063ffffffff808316818103613b7657613b766137ab565b6001019392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613bb557600080fd5b830160208101925035905067ffffffffffffffff811115613bd557600080fd5b80360382131561121b57600080fd5b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613c4457600080fd5b830160208101925035905067ffffffffffffffff811115613c6457600080fd5b8060051b360382131561121b57600080fd5b60008383855260208086019550808560051b830101846000805b88811015613d3457601f19868503018a5282357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1893603018112613cd2578283fd5b8801803585526060613ce687830183613b80565b8289890152613cf88389018284613be4565b925050506040613d0a81840184613b80565b935087830382890152613d1e838583613be4565b9d89019d97505050938601935050600101613c90565b509198975050505050505050565b6000610100613d5984613d5485613086565b613101565b613d6560208401613661565b67ffffffffffffffff166020850152613d80604084016138d3565b60ff166040850152613d9460608401613661565b67ffffffffffffffff166060850152613db06080840184613b80565b826080870152613dc38387018284613be4565b92505050613dd460a0840184613b80565b85830360a0870152613de7838284613be4565b92505050613df860c0840184613c0f565b85830360c0870152613e0b838284613c76565b92505050613e1c60e0840184613b80565b85830360e0870152613e2f838284613be4565b9695505050505050565b6020815260006125936020830184613d42565b600081356104228161364b565b60008135610422816138c4565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613e9b57600080fd5b83018035915067ffffffffffffffff821115613eb657600080fd5b60200191503681900382131561121b57600080fd5b5b81811015612cbf5760008155600101613ecc565b601f821115613f1957806000526020600020601f840160051c81016020851015613f075750805b6121cc601f850160051c830182613ecb565b505050565b67ffffffffffffffff831115613f3657613f366137f1565b613f4a83613f448354613758565b83613ee0565b6000601f841160018114613f9c5760008515613f665750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556121cc565b600083815260209020601f19861690835b82811015613fcd5786850135825560209485019460019092019101613fad565b5086821015614008577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261404f57600080fd5b83018035915067ffffffffffffffff82111561406a57600080fd5b6020019150600581901b360382131561121b57600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18336030181126140b657600080fd5b9190910192915050565b6140ca8154613758565b8015612cbf57601f8111600181146140e457505060009055565b826000526020600020614102601f840160051c820160018301613ecb565b60008085559055505050565b81358155600180820160206141266020860186613e66565b67ffffffffffffffff81111561413e5761413e6137f1565b6141528161414c8654613758565b86613ee0565b6000601f8211600181146141a4576000831561416e5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600385901b1c1916600184901b178655614219565b600086815260209020601f19841690835b828110156141d257868501358255938701939089019087016141b5565b508482101561420d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88660031b161c19848701351681555b505060018360011b0186555b5050505050505061422d6040830183613e66565b61423b818360028601613f1e565b50505050565b6801000000000000000083111561425a5761425a6137f1565b8054838255808410156142d95760038160030260038104831461427f5761427f6137ab565b85600302600381048714614295576142956137ab565b6000858152602081209283019291909101905b828210156142d4578082556142bf600183016140c0565b6142cb600283016140c0565b908301906142a8565b505050505b5060008181526020812083915b85811015614317576143016142fb8487614082565b8361410e565b60209290920191600391909101906001016142e6565b505050505050565b813561432a81613079565b60028110614361577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541660ff82168117835550506143d861439e60208401613e4c565b82547fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff1660089190911b68ffffffffffffffff0016178255565b6144226143e760408401613e59565b82547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff1660489190911b69ff00000000000000000016178255565b61447461443160608401613e4c565b82547fffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffff1660509190911b71ffffffffffffffff0000000000000000000016178255565b6144816080830183613e66565b61448f818360018601613f1e565b505061449e60a0830183613e66565b6144ac818360028601613f1e565b50506144bb60c083018361401a565b6144c9818360038601614241565b50506144d860e0830183613e66565b61423b818360048601613f1e565b63ffffffff831681526040602082015260006145056040830184613d42565b949350505050565b60006020828403121561451f57600080fd5b81356125938161364b565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126140b657600080fd5b60006060823603121561457057600080fd5b614578613846565b823567ffffffffffffffff8082111561459057600080fd5b9084019036601f8301126145a357600080fd5b813560206145b36139938361394e565b82815260059290921b840181019181810190368411156145d257600080fd5b948201945b838610156145f0578535825294820194908201906145d7565b8652506145fe8782016138d3565b9085015250604085013591508082111561461757600080fd5b50614624368286016138de565b60408301525092915050565b815167ffffffffffffffff81111561464a5761464a6137f1565b61465e816146588454613758565b84613ee0565b602080601f8311600181146146b1576000841561467b5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555614317565b600085815260208120601f198616915b828110156146e0578886015182559484019460019091019084016146c1565b508582101561471c57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff83168152604060208201526000614505604083018461341b565b6000808585111561475f57600080fd5b8386111561476c57600080fd5b5050820193919092039150565b7fffffffff0000000000000000000000000000000000000000000000000000000081358181169160048510156147b95780818660040360031b1b83161692505b505092915050565b6000602082840312156147d357600080fd5b5035919050565b8183823760009101908152919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361481b5761481b6137ab565b5060010190565b602081526000612593602083018461313c565b8681526020810186905273ffffffffffffffffffffffffffffffffffffffff8516604082015263ffffffff848116606083015260c082019061487a6080840186613101565b80841660a084015250979650505050505050565b600083516148a0818460208801612ff4565b8351908301906148b4818360208801612ff4565b01949350505050565b60208152600061259360208301846133df565b805161307481613057565b600082601f8301126148ec57600080fd5b815160206148fc6139938361394e565b8083825260208201915060208460051b87010193508684111561491e57600080fd5b602086015b84811015611c175780518352918301918301614923565b6000602080838503121561494d57600080fd5b825167ffffffffffffffff8082111561496557600080fd5b818501915085601f83011261497957600080fd5b81516149876139938261394e565b81815260059190911b830184019084810190888311156149a657600080fd5b8585015b83811015614a89578051858111156149c157600080fd5b8601610100818c03601f19018113156149d957600080fd5b6149e161386f565b6149ec8a84016148d0565b81526149fa604084016148d0565b8a820152614a0a606084016148d0565b60408201526080830151606082015260a0830151608082015260c083015160a082015260e08084015189811115614a415760008081fd5b614a4f8f8d838801016148db565b60c084015250918301519188831115614a685760008081fd5b614a768e8c858701016148db565b90820152855250509186019186016149aa565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"capabilitiesRegistry\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainSelectorNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ChainSelectorNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expectedConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"gotConfigDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"callDonId\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"capabilityRegistryDonId\",\"type\":\"uint32\"}],\"name\":\"DONIdMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FChainMustBePositive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fChain\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"FRoleDON\",\"type\":\"uint256\"}],\"name\":\"FChainTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node\",\"name\":\"node\",\"type\":\"tuple\"}],\"name\":\"InvalidNode\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPluginType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"}],\"name\":\"InvalidSelector\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoOpStateTransitionNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimum\",\"type\":\"uint256\"}],\"name\":\"NotEnoughTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OfframpAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCapabilitiesRegistryCanCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RMNHomeAddressCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RevokingZeroDigestNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManySigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ActiveConfigRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"CandidateConfigRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CapabilityConfigurationSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainConfigRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structCCIPHome.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigPromoted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"FRoleDON\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rmnHomeAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structCCIPHome.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"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\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"chainSelectorRemoves\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPHome.ChainConfigArgs[]\",\"name\":\"chainConfigAdds\",\"type\":\"tuple[]\"}],\"name\":\"applyChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"update\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"beforeCapabilityConfigSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getActiveDigest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"pageIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"pageSize\",\"type\":\"uint256\"}],\"name\":\"getAllChainConfigs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.ChainConfig\",\"name\":\"chainConfig\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPHome.ChainConfigArgs[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getAllConfigs\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"FRoleDON\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rmnHomeAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPHome.VersionedConfig\",\"name\":\"activeConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"FRoleDON\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rmnHomeAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPHome.VersionedConfig\",\"name\":\"candidateConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getCandidateDigest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"getCapabilityConfiguration\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"configuration\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilityRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32[]\",\"name\":\"readers\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"fChain\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.ChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"FRoleDON\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rmnHomeAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"internalType\":\"structCCIPHome.VersionedConfig\",\"name\":\"versionedConfig\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"ok\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"}],\"name\":\"getConfigDigests\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"activeConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"candidateConfigDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNumChainConfigurations\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"digestToPromote\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"digestToRevoke\",\"type\":\"bytes32\"}],\"name\":\"promoteCandidateAndRevokeActive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"revokeCandidate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"enumInternal.OCRPluginType\",\"name\":\"pluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"FRoleDON\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offrampAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"rmnHomeAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signerKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"transmitterKey\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structCCIPHome.OCR3Config\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"digestToOverwrite\",\"type\":\"bytes32\"}],\"name\":\"setCandidate\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"newConfigDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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: "0x60a06040526006805463ffffffff191690553480156200001e57600080fd5b5060405162004e0238038062004e0283398101604081905262000041916200014c565b336000816200006357604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038481169190911790915581161562000096576200009681620000d2565b50506001600160a01b038116620000c0576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03166080526200017e565b336001600160a01b03821603620000fc57604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200015f57600080fd5b81516001600160a01b03811681146200017757600080fd5b9392505050565b608051614c5a620001a86000396000818161019b015281816123600152612dba0152614c5a6000f3fe608060405234801561001057600080fd5b506004361061016c5760003560e01c80637ac0d41e116100cd578063b74b235611610081578063f2fde38b11610066578063f2fde38b14610391578063f442c89a146103a4578063fba64a7c146103b757600080fd5b8063b74b23561461035e578063bae4e0fa1461037e57600080fd5b80638da5cb5b116100b25780638da5cb5b1461030d578063922ea4061461032b578063b149092b1461033e57600080fd5b80637ac0d41e146102e45780638318ed5d146102ec57600080fd5b80634851d549116101245780635f1edd9c116101095780635f1edd9c146102a85780637524051a146102c957806379ba5097146102dc57600080fd5b80634851d5491461026b5780635a837f971461029357600080fd5b8063181f5a7711610155578063181f5a77146101e057806333d9704a146102295780633df45a721461024a57600080fd5b806301ffc9a714610171578063020330e614610199575b600080fd5b61018461017f366004613127565b6103ca565b60405190151581526020015b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610190565b61021c6040518060400160405280601281526020017f43434950486f6d6520312e362e302d646576000000000000000000000000000081525081565b60405161019091906131b9565b61023c610237366004613206565b610463565b60405161019092919061344d565b61025d610258366004613471565b61095d565b6040516101909291906134aa565b61027e610279366004613471565b61125d565b60408051928352602083019190915201610190565b6102a66102a13660046134cf565b611353565b005b6102bb6102b6366004613471565b611666565b604051908152602001610190565b6102a66102d7366004613206565b6116dd565b6102a66118c8565b6102bb611996565b61021c6102fa366004613515565b5060408051602081019091526000815290565b60015473ffffffffffffffffffffffffffffffffffffffff166101bb565b6102bb610339366004613471565b6119a7565b61035161034c366004613553565b6119f8565b60405161019091906135e7565b61037161036c3660046135fa565b611b32565b604051610190919061361c565b6102bb61038c3660046136ba565b611d97565b6102a661039f36600461372a565b611f95565b6102a66103b23660046137a5565b611fa9565b6102a66103c5366004613811565b612348565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f78bea72100000000000000000000000000000000000000000000000000000000148061045d57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b61046b612fb0565b6000805b600281101561094f5763ffffffff8616600090815260056020526040812085918760018111156104a1576104a1613247565b60018111156104b2576104b2613247565b815260200190815260200160002082600281106104d1576104d16138ce565b60070201600101541480156104e557508315155b156109475763ffffffff861660009081526005602052604081209086600181111561051257610512613247565b600181111561052357610523613247565b81526020019081526020016000208160028110610542576105426138ce565b6040805160608101825260079290920292909201805463ffffffff1682526001808201546020840152835161010081018552600283018054939592949386938501929190829060ff168781111561059b5761059b613247565b60018111156105ac576105ac613247565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a0100000000000000000000909104166060820152600182018054608090920191610604906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610630906138fd565b801561067d5780601f106106525761010080835404028352916020019161067d565b820191906000526020600020905b81548152906001019060200180831161066057829003601f168201915b50505050508152602001600282018054610696906138fd565b80601f01602080910402602001604051908101604052809291908181526020018280546106c2906138fd565b801561070f5780601f106106e45761010080835404028352916020019161070f565b820191906000526020600020905b8154815290600101906020018083116106f257829003601f168201915b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b8282101561089d57838290600052602060002090600302016040518060600160405290816000820154815260200160018201805461077a906138fd565b80601f01602080910402602001604051908101604052809291908181526020018280546107a6906138fd565b80156107f35780601f106107c8576101008083540402835291602001916107f3565b820191906000526020600020905b8154815290600101906020018083116107d657829003601f168201915b5050505050815260200160028201805461080c906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610838906138fd565b80156108855780601f1061085a57610100808354040283529160200191610885565b820191906000526020600020905b81548152906001019060200180831161086857829003601f168201915b5050505050815250508152602001906001019061073d565b5050505081526020016004820180546108b5906138fd565b80601f01602080910402602001604051908101604052809291908181526020018280546108e1906138fd565b801561092e5780601f106109035761010080835404028352916020019161092e565b820191906000526020600020905b81548152906001019060200180831161091157829003601f168201915b5050505050815250508152505091509250925050610955565b60010161046f565b50600090505b935093915050565b610965612fb0565b61096d612fb0565b63ffffffff841660009081526005602052604081208185600181111561099557610995613247565b60018111156109a6576109a6613247565b81526020019081526020016000206109be8686612605565b63ffffffff16600281106109d4576109d46138ce565b6040805160608101825260079290920292909201805463ffffffff1682526001808201546020840152835161010081018552600283018054949593949386019391929091839160ff90911690811115610a2f57610a2f613247565b6001811115610a4057610a40613247565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a0100000000000000000000909104166060820152600182018054608090920191610a98906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610ac4906138fd565b8015610b115780601f10610ae657610100808354040283529160200191610b11565b820191906000526020600020905b815481529060010190602001808311610af457829003601f168201915b50505050508152602001600282018054610b2a906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610b56906138fd565b8015610ba35780601f10610b7857610100808354040283529160200191610ba3565b820191906000526020600020905b815481529060010190602001808311610b8657829003601f168201915b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b82821015610d31578382906000526020600020906003020160405180606001604052908160008201548152602001600182018054610c0e906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610c3a906138fd565b8015610c875780601f10610c5c57610100808354040283529160200191610c87565b820191906000526020600020905b815481529060010190602001808311610c6a57829003601f168201915b50505050508152602001600282018054610ca0906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610ccc906138fd565b8015610d195780601f10610cee57610100808354040283529160200191610d19565b820191906000526020600020905b815481529060010190602001808311610cfc57829003601f168201915b50505050508152505081526020019060010190610bd1565b505050508152602001600482018054610d49906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610d75906138fd565b8015610dc25780601f10610d9757610100808354040283529160200191610dc2565b820191906000526020600020905b815481529060010190602001808311610da557829003601f168201915b50505091909252505050905250602081015190915015610de0578092505b63ffffffff8516600090815260056020526040812081866001811115610e0857610e08613247565b6001811115610e1957610e19613247565b8152602001908152602001600020610e31878761265c565b63ffffffff1660028110610e4757610e476138ce565b6040805160608101825260079290920292909201805463ffffffff1682526001808201546020840152835161010081018552600283018054949593949386019391929091839160ff90911690811115610ea257610ea2613247565b6001811115610eb357610eb3613247565b8152815467ffffffffffffffff61010082048116602084015260ff690100000000000000000083041660408401526a0100000000000000000000909104166060820152600182018054608090920191610f0b906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610f37906138fd565b8015610f845780601f10610f5957610100808354040283529160200191610f84565b820191906000526020600020905b815481529060010190602001808311610f6757829003601f168201915b50505050508152602001600282018054610f9d906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610fc9906138fd565b80156110165780601f10610feb57610100808354040283529160200191611016565b820191906000526020600020905b815481529060010190602001808311610ff957829003601f168201915b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b828210156111a4578382906000526020600020906003020160405180606001604052908160008201548152602001600182018054611081906138fd565b80601f01602080910402602001604051908101604052809291908181526020018280546110ad906138fd565b80156110fa5780601f106110cf576101008083540402835291602001916110fa565b820191906000526020600020905b8154815290600101906020018083116110dd57829003601f168201915b50505050508152602001600282018054611113906138fd565b80601f016020809104026020016040519081016040528092919081815260200182805461113f906138fd565b801561118c5780601f106111615761010080835404028352916020019161118c565b820191906000526020600020905b81548152906001019060200180831161116f57829003601f168201915b50505050508152505081526020019060010190611044565b5050505081526020016004820180546111bc906138fd565b80601f01602080910402602001604051908101604052809291908181526020018280546111e8906138fd565b80156112355780601f1061120a57610100808354040283529160200191611235565b820191906000526020600020905b81548152906001019060200180831161121857829003601f168201915b50505091909252505050905250602081015190915015611253578092505b50505b9250929050565b63ffffffff8216600090815260056020526040812081908184600181111561128757611287613247565b600181111561129857611298613247565b81526020019081526020016000206112b08585612605565b63ffffffff16600281106112c6576112c66138ce565b6007020160010154600560008663ffffffff1663ffffffff168152602001908152602001600020600085600181111561130157611301613247565b600181111561131257611312613247565b815260200190815260200160002061132a868661265c565b63ffffffff1660028110611340576113406138ce565b6007020160010154915091509250929050565b61135b6126b7565b81158015611367575080155b1561139e576040517f7b4d1e4f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006113aa858561265c565b63ffffffff86811660009081526005602052604081209290911692508491908660018111156113db576113db613247565b60018111156113ec576113ec613247565b8152602001908152602001600020826002811061140b5761140b6138ce565b6007020160010154146114bf5763ffffffff851660009081526005602052604081209085600181111561144057611440613247565b600181111561145157611451613247565b81526020019081526020016000208160028110611470576114706138ce565b6007020160010154836040517f93df584c0000000000000000000000000000000000000000000000000000000081526004016114b6929190918252602082015260400190565b60405180910390fd5b63ffffffff85166000908152600560205260408120818660018111156114e7576114e7613247565b60018111156114f8576114f8613247565b81526020019081526020016000206115108787612605565b63ffffffff1660028110611526576115266138ce565b600702019050828160010154146115795760018101546040517f93df584c0000000000000000000000000000000000000000000000000000000081526004810191909152602481018490526044016114b6565b6000600180830182905563ffffffff88168252600760205260408220909187838111156115a8576115a8613247565b60018111156115b9576115b9613247565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000811663ffffffff918216939093181691909117905582156116335760405183907f0b31c0055e2d464bef7781994b98c4ff9ef4ae0d05f59feb6a68c42de5e201b890600090a25b60405184907ffc3e98dbbd47c3fa7c1c05b6ec711caeaf70eca4554192b9ada8fc11a37f298e90600090a2505050505050565b63ffffffff821660009081526005602052604081208183600181111561168e5761168e613247565b600181111561169f5761169f613247565b81526020019081526020016000206116b78484612605565b63ffffffff16600281106116cd576116cd6138ce565b6007020160010154905092915050565b6116e56126b7565b8061171c576040517f0849d8cc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611728848461265c565b63ffffffff858116600090815260056020526040812092909116925083919085600181111561175957611759613247565b600181111561176a5761176a613247565b81526020019081526020016000208260028110611789576117896138ce565b6007020160010154146118345763ffffffff84166000908152600560205260408120908460018111156117be576117be613247565b60018111156117cf576117cf613247565b815260200190815260200160002081600281106117ee576117ee6138ce565b6007020160010154826040517f93df584c0000000000000000000000000000000000000000000000000000000081526004016114b6929190918252602082015260400190565b60405182907f53f5d9228f0a4173bea6e5931c9b3afe6eeb6692ede1d182952970f152534e3b90600090a263ffffffff841660009081526005602052604081209084600181111561188757611887613247565b600181111561189857611898613247565b815260200190815260200160002081600281106118b7576118b76138ce565b600702016001016000905550505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611919576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60006119a260036126f2565b905090565b63ffffffff82166000908152600560205260408120818360018111156119cf576119cf613247565b60018111156119e0576119e0613247565b81526020019081526020016000206116b7848461265c565b6040805160608082018352808252600060208301529181019190915267ffffffffffffffff821660009081526002602090815260409182902082518154608093810282018401909452606081018481529093919284928491840182828015611a7f57602002820191906000526020600020905b815481526020019060010190808311611a6b575b5050509183525050600182015460ff166020820152600282018054604090920191611aa9906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054611ad5906138fd565b8015611b225780601f10611af757610100808354040283529160200191611b22565b820191906000526020600020905b815481529060010190602001808311611b0557829003601f168201915b5050505050815250509050919050565b60606000611b4060036126f2565b90506000611b4e848661397f565b9050831580611b5d5750818110155b15611b9d576040805160008082526020820190925290611b93565b611b8061302c565b815260200190600190039081611b785790505b509250505061045d565b6000611ba985836139c5565b905082811115611bb65750815b6000611bc283836139d8565b67ffffffffffffffff811115611bda57611bda613996565b604051908082528060200260200182016040528015611c1357816020015b611c0061302c565b815260200190600190039081611bf85790505b509050825b82811015611d8c576000611c2d6003836126fc565b60408051808201825267ffffffffffffffff83168082526000908152600260209081529083902083518154608081850283018101909652606082018181529697509395928601949093919284929091849190840182828015611cae57602002820191906000526020600020905b815481526020019060010190808311611c9a575b5050509183525050600182015460ff166020820152600282018054604090920191611cd8906138fd565b80601f0160208091040260200160405190810160405280929190818152602001828054611d04906138fd565b8015611d515780601f10611d2657610100808354040283529160200191611d51565b820191906000526020600020905b815481529060010190602001808311611d3457829003601f168201915b50505091909252505050905283611d6887856139d8565b81518110611d7857611d786138ce565b602090810291909101015250600101611c18565b509695505050505050565b6000611da16126b7565b611db2611dad84613c06565b61270f565b6000611dbe86866119a7565b9050828114611e03576040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101829052602481018490526044016114b6565b8015611e355760405183907f53f5d9228f0a4173bea6e5931c9b3afe6eeb6692ede1d182952970f152534e3b90600090a25b60068054600091908290611e4e9063ffffffff16613d02565b91906101000a81548163ffffffff021916908363ffffffff16021790559050611e98878787604051602001611e839190613fde565b60405160208183030381529060405284612b7d565b63ffffffff881660009081526005602052604081209194509081886001811115611ec457611ec4613247565b6001811115611ed557611ed5613247565b8152602001908152602001600020611eed898961265c565b63ffffffff1660028110611f0357611f036138ce565b600702016001810185905580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff841617815590508560028201611f4d82826144c4565b905050837f94f085b7c57ec2a270befd0b7b2ec7452580040edee8bb0fb04609c81f0359c68388604051611f8292919061468b565b60405180910390a2505050949350505050565b611f9d612c3d565b611fa681612c8e565b50565b611fb1612c3d565b60005b8381101561219757611ff8858583818110611fd157611fd16138ce565b9050602002016020810190611fe69190613553565b60039067ffffffffffffffff16612d52565b6120625784848281811061200e5761200e6138ce565b90506020020160208101906120239190613553565b6040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016114b6565b60026000868684818110612078576120786138ce565b905060200201602081019061208d9190613553565b67ffffffffffffffff16815260208101919091526040016000908120906120b4828261306f565b6001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556120ec60028301600061308d565b505061212a858583818110612103576121036138ce565b90506020020160208101906121189190613553565b60039067ffffffffffffffff16612d6a565b507f2a680691fef3b2d105196805935232c661ce703e92d464ef0b94a7bc62d714f085858381811061215e5761215e6138ce565b90506020020160208101906121739190613553565b60405167ffffffffffffffff909116815260200160405180910390a1600101611fb4565b5060005b818110156123415760008383838181106121b7576121b76138ce565b90506020028101906121c991906146b2565b6121d7906020810190614227565b6121e0906146e6565b905060008484848181106121f6576121f66138ce565b905060200281019061220891906146b2565b612216906020810190613553565b90506122258260000151612d76565b816020015160ff16600003612266576040517fa9b3766e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff811660009081526002602090815260409091208351805185936122969284929101906130c7565b5060208201516001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055604082015160028201906122e390826147b8565b506122fd91506003905067ffffffffffffffff8316612e38565b507f05dd57854af2c291a94ea52e7c43d80bc3be7fa73022f98b735dea86642fa5e0818360405161232f9291906148b4565b60405180910390a1505060010161219b565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146123b7576040517fac7a7efd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006123c660048286886148d7565b6123cf91614901565b90507fffffffff0000000000000000000000000000000000000000000000000000000081167fbae4e0fa000000000000000000000000000000000000000000000000000000001480159061246557507fffffffff0000000000000000000000000000000000000000000000000000000081167f7524051a0000000000000000000000000000000000000000000000000000000014155b80156124b357507fffffffff0000000000000000000000000000000000000000000000000000000081167f5a837f970000000000000000000000000000000000000000000000000000000014155b1561250e576040517f12ba286f0000000000000000000000000000000000000000000000000000000081527fffffffff00000000000000000000000000000000000000000000000000000000821660048201526024016114b6565b600061251e6024600487896148d7565b81019061252b9190614949565b90508263ffffffff16811461257c576040517f8a6e4ce800000000000000000000000000000000000000000000000000000000815263ffffffff8083166004830152841660248201526044016114b6565b6000803073ffffffffffffffffffffffffffffffffffffffff1688886040516125a6929190614962565b6000604051808303816000865af19150503d80600081146125e3576040519150601f19603f3d011682016040523d82523d6000602084013e6125e8565b606091505b5091509150816125f9573d60208201fd5b50505050505050505050565b63ffffffff821660009081526007602052604081208183600181111561262d5761262d613247565b600181111561263e5761263e613247565b815260208101919091526040016000205463ffffffff169392505050565b63ffffffff821660009081526007602052604081208183600181111561268457612684613247565b600181111561269557612695613247565b815260208101919091526040016000205463ffffffff16600118905092915050565b3330146126f0576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600061045d825490565b60006127088383612e44565b9392505050565b806020015167ffffffffffffffff16600003612757576040517f698cf8e000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008151600181111561276c5761276c613247565b1415801561278d575060018151600181111561278a5761278a613247565b14155b156127c4576040517f3302dbd700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6080810151511580612801575060408051600060208201520160405160208183030381529060405280519060200120816080015180519060200120145b15612838576040517f358c192700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a08101515115806128755750604080516000602082015201604051602081830303815290604052805190602001208160a0015180519060200120145b156128ac576040517fdee9857400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101516128c79060039067ffffffffffffffff16612d52565b61290f5760208101516040517f1bd4d2d200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016114b6565b60408082015160208084015167ffffffffffffffff1660009081526002909152919091206001015460ff918216911681811115612982576040517f2db2204000000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016114b6565b60c0830151516101008111156129c4576040517f1b925da600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129cf83600361397f565b8111612a07576040517f4856694e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808267ffffffffffffffff811115612a2357612a23613996565b604051908082528060200260200182016040528015612a4c578160200160208202803683370190505b50905060005b83811015612b0c5760008760c001518281518110612a7257612a726138ce565b60200260200101519050806040015151600014612a975783612a9381614972565b9450505b6020810151511580612aa857508051155b15612ae157806040517f9fa403140000000000000000000000000000000000000000000000000000000081526004016114b691906149aa565b8060000151838381518110612af857612af86138ce565b602090810291909101015250600101612a52565b506000612b1a85600361397f565b612b259060016139c5565b905080831015612b6b576040517f548dd21f00000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044016114b6565b612b7482612d76565b50505050505050565b6040516000907dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90612bdb907f45564d000000000000000000000000000000000000000000000000000000000090469030908a908a9089906020016149bd565b60408051601f1981840301815290829052612bfa918690602001614a16565b60408051808303601f190181529190528051602090910120167e0a0000000000000000000000000000000000000000000000000000000000001795945050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146126f0576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821603612cdd576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120541515612708565b60006127088383612e6e565b805115611fa6576040517f05a5196600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906305a5196690612def908490600401614a45565b600060405180830381865afa158015612e0c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e349190810190614ac2565b5050565b60006127088383612f61565b6000826000018281548110612e5b57612e5b6138ce565b9060005260206000200154905092915050565b60008181526001830160205260408120548015612f57576000612e926001836139d8565b8554909150600090612ea6906001906139d8565b9050808214612f0b576000866000018281548110612ec657612ec66138ce565b9060005260206000200154905080876000018481548110612ee957612ee96138ce565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612f1c57612f1c614c1e565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061045d565b600091505061045d565b6000818152600183016020526040812054612fa85750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561045d565b50600061045d565b60408051606081018252600080825260208201529081016130276040805161010081019091528060008152602001600067ffffffffffffffff168152602001600060ff168152602001600067ffffffffffffffff168152602001606081526020016060815260200160608152602001606081525090565b905290565b6040518060400160405280600067ffffffffffffffff168152602001613027604051806060016040528060608152602001600060ff168152602001606081525090565b5080546000825590600052602060002090810190611fa69190613112565b508054613099906138fd565b6000825580601f106130a9575050565b601f016020900490600052602060002090810190611fa69190613112565b828054828255906000526020600020908101928215613102579160200282015b828111156131025782518255916020019190600101906130e7565b5061310e929150613112565b5090565b5b8082111561310e5760008155600101613113565b60006020828403121561313957600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461270857600080fd5b60005b8381101561318457818101518382015260200161316c565b50506000910152565b600081518084526131a5816020860160208601613169565b601f01601f19169290920160200192915050565b602081526000612708602083018461318d565b63ffffffff81168114611fa657600080fd5b80356131e9816131cc565b919050565b60028110611fa657600080fd5b80356131e9816131ee565b60008060006060848603121561321b57600080fd5b8335613226816131cc565b92506020840135613236816131ee565b929592945050506040919091013590565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600281106132ad577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b8051825260006020820151606060208501526132d0606085018261318d565b9050604083015184820360408601526132e9828261318d565b95945050505050565b60008282518085526020808601955060208260051b8401016020860160005b8481101561333f57601f1986840301895261332d8383516132b1565b98840198925090830190600101613311565b5090979650505050505050565b63ffffffff815116825260208101516020830152600060408201516060604085015261337c606085018251613276565b602081015167ffffffffffffffff8116608086015250604081015160ff811660a086015250606081015167ffffffffffffffff811660c08601525060808101516101008060e08701526133d361016087018361318d565b915060a08301517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa080888503018389015261340e848361318d565b935060c08501519250808885030161012089015261342c84846132f2565b935060e0850151945080888503016101408901525050506132e9818361318d565b604081526000613460604083018561334c565b905082151560208301529392505050565b6000806040838503121561348457600080fd5b823561348f816131cc565b9150602083013561349f816131ee565b809150509250929050565b6040815260006134bd604083018561334c565b82810360208401526132e9818561334c565b600080600080608085870312156134e557600080fd5b84356134f0816131cc565b93506020850135613500816131ee565b93969395505050506040820135916060013590565b60006020828403121561352757600080fd5b8135612708816131cc565b67ffffffffffffffff81168114611fa657600080fd5b80356131e981613532565b60006020828403121561356557600080fd5b813561270881613532565b60008151808452602080850194506020840160005b838110156135a157815187529582019590820190600101613585565b509495945050505050565b60008151606084526135c16060850182613570565b905060ff6020840151166020850152604083015184820360408601526132e9828261318d565b60208152600061270860208301846135ac565b6000806040838503121561360d57600080fd5b50508035926020909101359150565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b838110156136ac578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805167ffffffffffffffff168452870151878401879052613699878501826135ac565b9588019593505090860190600101613645565b509098975050505050505050565b600080600080608085870312156136d057600080fd5b84356136db816131cc565b935060208501356136eb816131ee565b9250604085013567ffffffffffffffff81111561370757600080fd5b8501610100818803121561371a57600080fd5b9396929550929360600135925050565b60006020828403121561373c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461270857600080fd5b60008083601f84011261377257600080fd5b50813567ffffffffffffffff81111561378a57600080fd5b6020830191508360208260051b850101111561125657600080fd5b600080600080604085870312156137bb57600080fd5b843567ffffffffffffffff808211156137d357600080fd5b6137df88838901613760565b909650945060208701359150808211156137f857600080fd5b5061380587828801613760565b95989497509550505050565b6000806000806000806080878903121561382a57600080fd5b863567ffffffffffffffff8082111561384257600080fd5b61384e8a838b01613760565b9098509650602089013591508082111561386757600080fd5b818901915089601f83011261387b57600080fd5b81358181111561388a57600080fd5b8a602082850101111561389c57600080fd5b6020830196508095505050506138b460408801613548565b91506138c2606088016131de565b90509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c9082168061391157607f821691505b60208210810361394a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761045d5761045d613950565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8082018082111561045d5761045d613950565b8181038181111561045d5761045d613950565b6040516060810167ffffffffffffffff81118282101715613a0e57613a0e613996565b60405290565b604051610100810167ffffffffffffffff81118282101715613a0e57613a0e613996565b604051601f8201601f1916810167ffffffffffffffff81118282101715613a6157613a61613996565b604052919050565b60ff81168114611fa657600080fd5b80356131e981613a69565b600082601f830112613a9457600080fd5b813567ffffffffffffffff811115613aae57613aae613996565b613ac16020601f19601f84011601613a38565b818152846020838601011115613ad657600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff821115613b0d57613b0d613996565b5060051b60200190565b600082601f830112613b2857600080fd5b81356020613b3d613b3883613af3565b613a38565b82815260059290921b84018101918181019086841115613b5c57600080fd5b8286015b84811015611d8c57803567ffffffffffffffff80821115613b815760008081fd5b8189019150606080601f19848d03011215613b9c5760008081fd5b613ba46139eb565b87840135815260408085013584811115613bbe5760008081fd5b613bcc8e8b83890101613a83565b838b015250918401359183831115613be45760008081fd5b613bf28d8a85880101613a83565b908201528652505050918301918301613b60565b60006101008236031215613c1957600080fd5b613c21613a14565b613c2a836131fb565b8152613c3860208401613548565b6020820152613c4960408401613a78565b6040820152613c5a60608401613548565b6060820152608083013567ffffffffffffffff80821115613c7a57600080fd5b613c8636838701613a83565b608084015260a0850135915080821115613c9f57600080fd5b613cab36838701613a83565b60a084015260c0850135915080821115613cc457600080fd5b613cd036838701613b17565b60c084015260e0850135915080821115613ce957600080fd5b50613cf636828601613a83565b60e08301525092915050565b600063ffffffff808316818103613d1b57613d1b613950565b6001019392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613d5a57600080fd5b830160208101925035905067ffffffffffffffff811115613d7a57600080fd5b80360382131561125657600080fd5b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613de957600080fd5b830160208101925035905067ffffffffffffffff811115613e0957600080fd5b8060051b360382131561125657600080fd5b60008383855260208086019550808560051b830101846000805b88811015613ed957601f19868503018a5282357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1893603018112613e77578283fd5b8801803585526060613e8b87830183613d25565b8289890152613e9d8389018284613d89565b925050506040613eaf81840184613d25565b935087830382890152613ec3838583613d89565b9d89019d97505050938601935050600101613e35565b509198975050505050505050565b6000610100613efe84613ef9856131fb565b613276565b613f0a60208401613548565b67ffffffffffffffff166020850152613f2560408401613a78565b60ff166040850152613f3960608401613548565b67ffffffffffffffff166060850152613f556080840184613d25565b826080870152613f688387018284613d89565b92505050613f7960a0840184613d25565b85830360a0870152613f8c838284613d89565b92505050613f9d60c0840184613db4565b85830360c0870152613fb0838284613e1b565b92505050613fc160e0840184613d25565b85830360e0870152613fd4838284613d89565b9695505050505050565b6020815260006127086020830184613ee7565b6000813561045d81613532565b6000813561045d81613a69565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261404057600080fd5b83018035915067ffffffffffffffff82111561405b57600080fd5b60200191503681900382131561125657600080fd5b5b81811015612e345760008155600101614071565b601f8211156140be57806000526020600020601f840160051c810160208510156140ac5750805b612341601f850160051c830182614070565b505050565b67ffffffffffffffff8311156140db576140db613996565b6140ef836140e983546138fd565b83614085565b6000601f841160018114614141576000851561410b5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355612341565b600083815260209020601f19861690835b828110156141725786850135825560209485019460019092019101614152565b50868210156141ad577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126141f457600080fd5b83018035915067ffffffffffffffff82111561420f57600080fd5b6020019150600581901b360382131561125657600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa183360301811261425b57600080fd5b9190910192915050565b61426f81546138fd565b8015612e3457601f81116001811461428957505060009055565b8260005260206000206142a7601f840160051c820160018301614070565b60008085559055505050565b81358155600180820160206142cb602086018661400b565b67ffffffffffffffff8111156142e3576142e3613996565b6142f7816142f186546138fd565b86614085565b6000601f82116001811461434957600083156143135750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600385901b1c1916600184901b1786556143be565b600086815260209020601f19841690835b82811015614377578685013582559387019390890190870161435a565b50848210156143b2577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88660031b161c19848701351681555b505060018360011b0186555b505050505050506143d2604083018361400b565b6143e08183600286016140c3565b50505050565b680100000000000000008311156143ff576143ff613996565b80548382558084101561447e5760038160030260038104831461442457614424613950565b8560030260038104871461443a5761443a613950565b6000858152602081209283019291909101905b828210156144795780825561446460018301614265565b61447060028301614265565b9083019061444d565b505050505b5060008181526020812083915b858110156144bc576144a66144a08487614227565b836142b3565b602092909201916003919091019060010161448b565b505050505050565b81356144cf816131ee565b60028110614506577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541660ff821681178355505061457d61454360208401613ff1565b82547fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff1660089190911b68ffffffffffffffff0016178255565b6145c761458c60408401613ffe565b82547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff1660489190911b69ff00000000000000000016178255565b6146196145d660608401613ff1565b82547fffffffffffffffffffffffffffff0000000000000000ffffffffffffffffffff1660509190911b71ffffffffffffffff0000000000000000000016178255565b614626608083018361400b565b6146348183600186016140c3565b505061464360a083018361400b565b6146518183600286016140c3565b505061466060c08301836141bf565b61466e8183600386016143e6565b505061467d60e083018361400b565b6143e08183600486016140c3565b63ffffffff831681526040602082015260006146aa6040830184613ee7565b949350505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261425b57600080fd5b6000606082360312156146f857600080fd5b6147006139eb565b823567ffffffffffffffff8082111561471857600080fd5b9084019036601f83011261472b57600080fd5b8135602061473b613b3883613af3565b82815260059290921b8401810191818101903684111561475a57600080fd5b948201945b838610156147785785358252948201949082019061475f565b865250614786878201613a78565b9085015250604085013591508082111561479f57600080fd5b506147ac36828601613a83565b60408301525092915050565b815167ffffffffffffffff8111156147d2576147d2613996565b6147e6816147e084546138fd565b84614085565b602080601f83116001811461483957600084156148035750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556144bc565b600085815260208120601f198616915b8281101561486857888601518255948401946001909101908401614849565b50858210156148a457878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff831681526040602082015260006146aa60408301846135ac565b600080858511156148e757600080fd5b838611156148f457600080fd5b5050820193919092039150565b7fffffffff0000000000000000000000000000000000000000000000000000000081358181169160048510156149415780818660040360031b1b83161692505b505092915050565b60006020828403121561495b57600080fd5b5035919050565b8183823760009101908152919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036149a3576149a3613950565b5060010190565b60208152600061270860208301846132b1565b8681526020810186905273ffffffffffffffffffffffffffffffffffffffff8516604082015263ffffffff848116606083015260c0820190614a026080840186613276565b80841660a084015250979650505050505050565b60008351614a28818460208801613169565b835190830190614a3c818360208801613169565b01949350505050565b6020815260006127086020830184613570565b80516131e9816131cc565b600082601f830112614a7457600080fd5b81516020614a84613b3883613af3565b8083825260208201915060208460051b870101935086841115614aa657600080fd5b602086015b84811015611d8c5780518352918301918301614aab565b60006020808385031215614ad557600080fd5b825167ffffffffffffffff80821115614aed57600080fd5b818501915085601f830112614b0157600080fd5b8151614b0f613b3882613af3565b81815260059190911b83018401908481019088831115614b2e57600080fd5b8585015b83811015614c1157805185811115614b4957600080fd5b8601610100818c03601f1901811315614b6157600080fd5b614b69613a14565b614b748a8401614a58565b8152614b8260408401614a58565b8a820152614b9260608401614a58565b60408201526080830151606082015260a0830151608082015260c083015160a082015260e08084015189811115614bc95760008081fd5b614bd78f8d83880101614a63565b60c084015250918301519188831115614bf05760008081fd5b614bfe8e8c85870101614a63565b9082015285525050918601918601614b32565b5098975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var CCIPHomeABI = CCIPHomeMetaData.ABI @@ -345,6 +345,28 @@ func (_CCIPHome *CCIPHomeCallerSession) GetCapabilityRegistry() (common.Address, return _CCIPHome.Contract.GetCapabilityRegistry(&_CCIPHome.CallOpts) } +func (_CCIPHome *CCIPHomeCaller) GetChainConfig(opts *bind.CallOpts, chainSelector uint64) (CCIPHomeChainConfig, error) { + var out []interface{} + err := _CCIPHome.contract.Call(opts, &out, "getChainConfig", chainSelector) + + if err != nil { + return *new(CCIPHomeChainConfig), err + } + + out0 := *abi.ConvertType(out[0], new(CCIPHomeChainConfig)).(*CCIPHomeChainConfig) + + return out0, err + +} + +func (_CCIPHome *CCIPHomeSession) GetChainConfig(chainSelector uint64) (CCIPHomeChainConfig, error) { + return _CCIPHome.Contract.GetChainConfig(&_CCIPHome.CallOpts, chainSelector) +} + +func (_CCIPHome *CCIPHomeCallerSession) GetChainConfig(chainSelector uint64) (CCIPHomeChainConfig, error) { + return _CCIPHome.Contract.GetChainConfig(&_CCIPHome.CallOpts, chainSelector) +} + func (_CCIPHome *CCIPHomeCaller) GetConfig(opts *bind.CallOpts, donId uint32, pluginType uint8, configDigest [32]byte) (GetConfig, error) { @@ -1804,6 +1826,8 @@ type CCIPHomeInterface interface { GetCapabilityRegistry(opts *bind.CallOpts) (common.Address, error) + GetChainConfig(opts *bind.CallOpts, chainSelector uint64) (CCIPHomeChainConfig, error) + GetConfig(opts *bind.CallOpts, donId uint32, pluginType uint8, configDigest [32]byte) (GetConfig, error) diff --git a/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go b/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go index 32edf6ef6c3..fa5a6a4cdac 100644 --- a/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go +++ b/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go @@ -81,8 +81,8 @@ type TokenPoolChainUpdate struct { } var LockReleaseTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"localTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferLiquidity\",\"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\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101206040523480156200001257600080fd5b506040516200511f3803806200511f8339810160408190526200003591620005bb565b8585858584336000816200005c57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008f576200008f81620001f3565b50506001600160a01b0385161580620000af57506001600160a01b038116155b80620000c257506001600160a01b038216155b15620000e1576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808616608081905290831660c0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa92505050801562000151575060408051601f3d908101601f191682019092526200014e91810190620006ee565b60015b1562000191578060ff168560ff16146200018f576040516332ad3e0760e11b815260ff80871660048301528216602482015260440160405180910390fd5b505b60ff841660a052600480546001600160a01b0319166001600160a01b038316179055825115801560e052620001db57604080516000815260208101909152620001db90846200026d565b5050505091151561010052506200075a945050505050565b336001600160a01b038216036200021d57604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e0516200028e576040516335f4a7b360e01b815260040160405180910390fd5b60005b825181101562000319576000838281518110620002b257620002b26200070c565b60209081029190910101519050620002cc600282620003ca565b156200030f576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000291565b5060005b8151811015620003c55760008282815181106200033e576200033e6200070c565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200036a5750620003bc565b62000377600282620003ea565b15620003ba576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6001016200031d565b505050565b6000620003e1836001600160a01b03841662000401565b90505b92915050565b6000620003e1836001600160a01b03841662000505565b60008181526001830160205260408120548015620004fa5760006200042860018362000722565b85549091506000906200043e9060019062000722565b9050808214620004aa5760008660000182815481106200046257620004626200070c565b90600052602060002001549050808760000184815481106200048857620004886200070c565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004be57620004be62000744565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003e4565b6000915050620003e4565b60008181526001830160205260408120546200054e57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003e4565b506000620003e4565b6001600160a01b03811681146200056d57600080fd5b50565b805160ff811681146200058257600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b8051620005828162000557565b805180151581146200058257600080fd5b60008060008060008060c08789031215620005d557600080fd5b8651620005e28162000557565b95506020620005f388820162000570565b60408901519096506001600160401b03808211156200061157600080fd5b818a0191508a601f8301126200062657600080fd5b8151818111156200063b576200063b62000587565b8060051b604051601f19603f8301168101818110858211171562000663576200066362000587565b60405291825284820192508381018501918d8311156200068257600080fd5b938501935b82851015620006ab576200069b856200059d565b8452938501939285019262000687565b809950505050505050620006c2606088016200059d565b9250620006d260808801620005aa565b9150620006e260a088016200059d565b90509295509295509295565b6000602082840312156200070157600080fd5b620003e18262000570565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003e457634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e051610100516148f46200082b600039600081816105a40152611ac601526000818161063e015281816123180152612e3101526000818161061801528181611e35015261260401526000818161036701528181610e6b01528181611fde01528181612098015281816120cc015281816120ff01528181612164015281816121bd015261225f0152600081816102ce015281816103230152818161077f015281816108510152818161094501528181611b8801528181612dc7015261301c01526148f46000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c80638da5cb5b11610145578063c0d78655116100bd578063dc0bd9711161008c578063e8a1da1711610071578063e8a1da1714610662578063eb521a4c14610675578063f2fde38b1461068857600080fd5b8063dc0bd97114610616578063e0351e131461063c57600080fd5b8063c0d78655146105c8578063c4bffe2b146105db578063c75eea9c146105f0578063cf7401f31461060357600080fd5b8063acfecf9111610114578063b0f479a1116100f9578063b0f479a114610571578063b79465801461058f578063bb98546b146105a257600080fd5b8063acfecf91146104ef578063af58d59f1461050257600080fd5b80638da5cb5b1461047c5780639a4575b91461049a578063a42a7b8b146104ba578063a7cd63b7146104da57600080fd5b80634c5ef0ed116101d85780636cfd1553116101a757806379ba50971161018c57806379ba50971461044e5780637d54534e146104565780638926f54f1461046957600080fd5b80636cfd15531461041d5780636d3d1a581461043057600080fd5b80634c5ef0ed146103d157806354c8a4f3146103e457806362ddd3c4146103f7578063663200871461040a57600080fd5b8063240028e811610214578063240028e81461031357806324f65ee7146103605780633907753714610391578063432a6ba3146103b357600080fd5b806301ffc9a7146102465780630a861f2a1461026e578063181f5a771461028357806321df0da7146102cc575b600080fd5b6102596102543660046139e3565b61069b565b60405190151581526020015b60405180910390f35b61028161027c366004613a25565b6106f7565b005b6102bf6040518060400160405280601a81526020017f4c6f636b52656c65617365546f6b656e506f6f6c20312e352e3100000000000081525081565b6040516102659190613aac565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610265565b610259610321366004613ae1565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610265565b6103a461039f366004613afe565b6108a8565b60405190518152602001610265565b600a5473ffffffffffffffffffffffffffffffffffffffff166102ee565b6102596103df366004613b57565b6109f6565b6102816103f2366004613c26565b610a40565b610281610405366004613b57565b610abb565b610281610418366004613c92565b610b53565b61028161042b366004613ae1565b610c2f565b60095473ffffffffffffffffffffffffffffffffffffffff166102ee565b610281610c7e565b610281610464366004613ae1565b610d4c565b610259610477366004613cbe565b610dcd565b60015473ffffffffffffffffffffffffffffffffffffffff166102ee565b6104ad6104a8366004613cd9565b610de4565b6040516102659190613d14565b6104cd6104c8366004613cbe565b610eb0565b6040516102659190613d6b565b6104e261101b565b6040516102659190613ded565b6102816104fd366004613b57565b61102c565b610515610510366004613cbe565b611144565b604051610265919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102ee565b6102bf61059d366004613cbe565b611219565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102816105d6366004613ae1565b6112c9565b6105e36113a4565b6040516102659190613e47565b6105156105fe366004613cbe565b61145c565b610281610611366004613fcf565b61152e565b7f00000000000000000000000000000000000000000000000000000000000000006102ee565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b610281610670366004613c26565b6115b2565b610281610683366004613a25565b611ac4565b610281610696366004613ae1565b611be0565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d405660000000000000000000000000000000000000000000000000000000014806106f157506106f182611bf4565b92915050565b600a5473ffffffffffffffffffffffffffffffffffffffff16331461074f576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156107db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ff9190614014565b1015610837576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61087873ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611cd8565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040805160208101909152600081526108c082611dac565b600061091960608401356109146108da60c087018761402d565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611fd092505050565b612094565b905061096c61092e6060850160408601613ae1565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169083611cd8565b61097c6060840160408501613ae1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52836040516109da91815260200190565b60405180910390a3604080516020810190915290815292915050565b6000610a388383604051610a0b929190614092565b604080519182900390912067ffffffffffffffff87166000908152600760205291909120600501906122a8565b949350505050565b610a486122c3565b610ab58484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061231692505050565b50505050565b610ac36122c3565b610acc83610dcd565b610b0e576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610746565b610b4e8383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506124cc92505050565b505050565b610b5b6122c3565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610bc357600080fd5b505af1158015610bd7573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167f6fa7abcf1345d1d478e5ea0da6b5f26a90eadb0546ef15ed3833944fbfd1db6282604051610c2391815260200190565b60405180910390a25050565b610c376122c3565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ccf576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610d546122c3565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b60006106f1600567ffffffffffffffff84166122a8565b6040805180820190915260608082526020820152610e01826125c6565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a26040518060400160405280610e5b84602001602081019061059d9190613cbe565b8152602001610ea86040805160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260609101604051602081830303815290604052905090565b905292915050565b67ffffffffffffffff8116600090815260076020526040812060609190610ed990600501612752565b90506000815167ffffffffffffffff811115610ef757610ef7613e89565b604051908082528060200260200182016040528015610f2a57816020015b6060815260200190600190039081610f155790505b50905060005b82518110156110135760086000848381518110610f4f57610f4f6140a2565b602002602001015181526020019081526020016000208054610f70906140d1565b80601f0160208091040260200160405190810160405280929190818152602001828054610f9c906140d1565b8015610fe95780601f10610fbe57610100808354040283529160200191610fe9565b820191906000526020600020905b815481529060010190602001808311610fcc57829003601f168201915b5050505050828281518110611000576110006140a2565b6020908102919091010152600101610f30565b509392505050565b60606110276002612752565b905090565b6110346122c3565b61103d83610dcd565b61107f576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610746565b6110bf8282604051611092929190614092565b604080519182900390912067ffffffffffffffff861660009081526007602052919091206005019061275f565b6110fb578282826040517f74f23c7c0000000000000000000000000000000000000000000000000000000081526004016107469392919061416d565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d768383604051611137929190614191565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526106f19061276b565b67ffffffffffffffff81166000908152600760205260409020600401805460609190611244906140d1565b80601f0160208091040260200160405190810160405280929190818152602001828054611270906140d1565b80156112bd5780601f10611292576101008083540402835291602001916112bd565b820191906000526020600020905b8154815290600101906020018083116112a057829003601f168201915b50505050509050919050565b6112d16122c3565b73ffffffffffffffffffffffffffffffffffffffff811661131e576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006113b26005612752565b90506000815167ffffffffffffffff8111156113d0576113d0613e89565b6040519080825280602002602001820160405280156113f9578160200160208202803683370190505b50905060005b82518110156114555782818151811061141a5761141a6140a2565b6020026020010151828281518110611434576114346140a2565b67ffffffffffffffff909216602092830291909101909101526001016113ff565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526106f19061276b565b60095473ffffffffffffffffffffffffffffffffffffffff16331480159061156e575060015473ffffffffffffffffffffffffffffffffffffffff163314155b156115a7576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610746565b610b4e83838361281d565b6115ba6122c3565b60005b838110156117a75760008585838181106115d9576115d96140a2565b90506020020160208101906115ee9190613cbe565b9050611605600567ffffffffffffffff831661275f565b611647576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610746565b67ffffffffffffffff8116600090815260076020526040812061166c90600501612752565b905060005b81518110156116d8576116cf82828151811061168f5761168f6140a2565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060050161275f90919063ffffffff16565b50600101611671565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906117416004830182613976565b600582016000818161175382826139b0565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d85991694506020019250611795915050565b60405180910390a150506001016115bd565b5060005b81811015611abd5760008383838181106117c7576117c76140a2565b90506020028101906117d991906141a5565b6117e290614271565b90506117f381606001516000612907565b61180281608001516000612907565b806040015151600003611841576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516118599060059067ffffffffffffffff16612a44565b61189e5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610746565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a909102999093161717909416959095179092559092029091176003820155908201516004820190611a2190826143e8565b5060005b826020015151811015611a6557611a5d836000015184602001518381518110611a5057611a506140a2565b60200260200101516124cc565b600101611a25565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c28260000151836040015184606001518560800151604051611aab9493929190614502565b60405180910390a150506001016117ab565b5050505050565b7f0000000000000000000000000000000000000000000000000000000000000000611b1b576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a5473ffffffffffffffffffffffffffffffffffffffff163314611b6e576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610746565b611bb073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612a50565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611be86122c3565b611bf181612aae565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf000000000000000000000000000000000000000000000000000000001480611c8757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806106f157507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610b4e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612b72565b611dbf61032160a0830160808401613ae1565b611e1e57611dd360a0820160808301613ae1565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610746565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb611e6a6040840160208501613cbe565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611edb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eff919061459b565b15611f36576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f4e611f496040830160208401613cbe565b612c7e565b611f6e611f616040830160208401613cbe565b6103df60a084018461402d565b611fb357611f7f60a082018261402d565b6040517f24eb47e5000000000000000000000000000000000000000000000000000000008152600401610746929190614191565b611bf1611fc66040830160208401613cbe565b8260600135612da4565b6000815160000361200257507f0000000000000000000000000000000000000000000000000000000000000000919050565b815160201461203f57816040517f953576f70000000000000000000000000000000000000000000000000000000081526004016107469190613aac565b6000828060200190518101906120559190614014565b905060ff8111156106f157826040517f953576f70000000000000000000000000000000000000000000000000000000081526004016107469190613aac565b60007f000000000000000000000000000000000000000000000000000000000000000060ff168260ff16036120ca5750816106f1565b7f000000000000000000000000000000000000000000000000000000000000000060ff168260ff1611156121b55760006121247f0000000000000000000000000000000000000000000000000000000000000000846145e7565b9050604d8160ff161115612198576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f000000000000000000000000000000000000000000000000000000000000000016602482015260448101859052606401610746565b6121a381600a614720565b6121ad908561472f565b9150506106f1565b60006121e1837f00000000000000000000000000000000000000000000000000000000000000006145e7565b9050604d8160ff16118061222857506121fb81600a614720565b612225907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61472f565b84115b15612293576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f000000000000000000000000000000000000000000000000000000000000000016602482015260448101859052606401610746565b61229e81600a614720565b610a38908561476a565b600081815260018301602052604081205415155b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314612314576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f000000000000000000000000000000000000000000000000000000000000000061236d576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561240357600083828151811061238d5761238d6140a2565b602002602001015190506123ab816002612deb90919063ffffffff16565b156123fa5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101612370565b5060005b8151811015610b4e576000828281518110612424576124246140a2565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361246857506124c4565b612473600282612e0d565b156124c25760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101612407565b8051600003612507576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff84166000908152600790925260409091206125399060050182612a44565b6125735782826040517f393b8ad2000000000000000000000000000000000000000000000000000000008152600401610746929190614781565b600081815260086020526040902061258b83826143e8565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea836040516111379190613aac565b6125d961032160a0830160808401613ae1565b6125ed57611dd360a0820160808301613ae1565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6126396040840160208501613cbe565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa1580156126aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ce919061459b565b15612705576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61271d6127186060830160408401613ae1565b612e2f565b6127356127306040830160208401613cbe565b612eae565b611bf16127486040830160208401613cbe565b8260600135612ffc565b606060006122bc83613040565b60006122bc838361309b565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526127f982606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426127dd91906147a4565b85608001516fffffffffffffffffffffffffffffffff1661318e565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61282683610dcd565b612868576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610746565b612873826000612907565b67ffffffffffffffff8316600090815260076020526040902061289690836131b6565b6128a1816000612907565b67ffffffffffffffff831660009081526007602052604090206128c790600201826131b6565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516128fa939291906147b7565b60405180910390a1505050565b8151156129d25781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff1610158061295d575060408201516fffffffffffffffffffffffffffffffff16155b1561299657816040517f8020d124000000000000000000000000000000000000000000000000000000008152600401610746919061483a565b80156129ce576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580612a0b575060208201516fffffffffffffffffffffffffffffffff1615155b156129ce57816040517fd68af9cc000000000000000000000000000000000000000000000000000000008152600401610746919061483a565b60006122bc8383613358565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610ab59085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611d2a565b3373ffffffffffffffffffffffffffffffffffffffff821603612afd576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612bd4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166133a79092919063ffffffff16565b805190915015610b4e5780806020019051810190612bf2919061459b565b610b4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610746565b612c8781610dcd565b612cc9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610746565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612d48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d6c919061459b565b611bf1576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610746565b67ffffffffffffffff821660009081526007602052604090206129ce90600201827f00000000000000000000000000000000000000000000000000000000000000006133b6565b60006122bc8373ffffffffffffffffffffffffffffffffffffffff841661309b565b60006122bc8373ffffffffffffffffffffffffffffffffffffffff8416613358565b7f000000000000000000000000000000000000000000000000000000000000000015611bf157612e60600282613739565b611bf1576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610746565b612eb781610dcd565b612ef9576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610746565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612f72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f969190614876565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611bf1576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610746565b67ffffffffffffffff821660009081526007602052604090206129ce90827f00000000000000000000000000000000000000000000000000000000000000006133b6565b6060816000018054806020026020016040519081016040528092919081815260200182805480156112bd57602002820191906000526020600020905b81548152602001906001019080831161307c5750505050509050919050565b600081815260018301602052604081205480156131845760006130bf6001836147a4565b85549091506000906130d3906001906147a4565b90508082146131385760008660000182815481106130f3576130f36140a2565b9060005260206000200154905080876000018481548110613116576131166140a2565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061314957613149614893565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106f1565b60009150506106f1565b60006131ad8561319e848661476a565b6131a890876148c2565b613768565b95945050505050565b81546000906131df90700100000000000000000000000000000000900463ffffffff16426147a4565b905080156132815760018301548354613227916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661318e565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546132a7916fffffffffffffffffffffffffffffffff9081169116613768565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906128fa90849061483a565b600081815260018301602052604081205461339f575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106f1565b5060006106f1565b6060610a38848460008561377e565b825474010000000000000000000000000000000000000000900460ff1615806133dd575081155b156133e757505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061342d90700100000000000000000000000000000000900463ffffffff16426147a4565b905080156134ed578183111561346f576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546134a99083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661318e565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156135a45773ffffffffffffffffffffffffffffffffffffffff841661354c576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610746565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610746565b848310156136b75760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906135e890826147a4565b6135f2878a6147a4565b6135fc91906148c2565b613606919061472f565b905073ffffffffffffffffffffffffffffffffffffffff861661365f576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610746565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610746565b6136c185846147a4565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156122bc565b600081831061377757816122bc565b5090919050565b606082471015613810576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610746565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161383991906148d5565b60006040518083038185875af1925050503d8060008114613876576040519150601f19603f3d011682016040523d82523d6000602084013e61387b565b606091505b509150915061388c87838387613897565b979650505050505050565b6060831561392d5782516000036139265773ffffffffffffffffffffffffffffffffffffffff85163b613926576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610746565b5081610a38565b610a3883838151156139425781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107469190613aac565b508054613982906140d1565b6000825580601f10613992575050565b601f016020900490600052602060002090810190611bf191906139ca565b5080546000825590600052602060002090810190611bf191905b5b808211156139df57600081556001016139cb565b5090565b6000602082840312156139f557600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146122bc57600080fd5b600060208284031215613a3757600080fd5b5035919050565b60005b83811015613a59578181015183820152602001613a41565b50506000910152565b60008151808452613a7a816020860160208601613a3e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006122bc6020830184613a62565b73ffffffffffffffffffffffffffffffffffffffff81168114611bf157600080fd5b600060208284031215613af357600080fd5b81356122bc81613abf565b600060208284031215613b1057600080fd5b813567ffffffffffffffff811115613b2757600080fd5b820161010081850312156122bc57600080fd5b803567ffffffffffffffff81168114613b5257600080fd5b919050565b600080600060408486031215613b6c57600080fd5b613b7584613b3a565b9250602084013567ffffffffffffffff80821115613b9257600080fd5b818601915086601f830112613ba657600080fd5b813581811115613bb557600080fd5b876020828501011115613bc757600080fd5b6020830194508093505050509250925092565b60008083601f840112613bec57600080fd5b50813567ffffffffffffffff811115613c0457600080fd5b6020830191508360208260051b8501011115613c1f57600080fd5b9250929050565b60008060008060408587031215613c3c57600080fd5b843567ffffffffffffffff80821115613c5457600080fd5b613c6088838901613bda565b90965094506020870135915080821115613c7957600080fd5b50613c8687828801613bda565b95989497509550505050565b60008060408385031215613ca557600080fd5b8235613cb081613abf565b946020939093013593505050565b600060208284031215613cd057600080fd5b6122bc82613b3a565b600060208284031215613ceb57600080fd5b813567ffffffffffffffff811115613d0257600080fd5b820160a081850312156122bc57600080fd5b602081526000825160406020840152613d306060840182613a62565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526131ad8282613a62565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015613de0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452613dce858351613a62565b94509285019290850190600101613d94565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613e3b57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613e09565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613e3b57835167ffffffffffffffff1683529284019291840191600101613e63565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715613edb57613edb613e89565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613f2857613f28613e89565b604052919050565b8015158114611bf157600080fd5b80356fffffffffffffffffffffffffffffffff81168114613b5257600080fd5b600060608284031215613f7057600080fd5b6040516060810181811067ffffffffffffffff82111715613f9357613f93613e89565b6040529050808235613fa481613f30565b8152613fb260208401613f3e565b6020820152613fc360408401613f3e565b60408201525092915050565b600080600060e08486031215613fe457600080fd5b613fed84613b3a565b9250613ffc8560208601613f5e565b915061400b8560808601613f5e565b90509250925092565b60006020828403121561402657600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261406257600080fd5b83018035915067ffffffffffffffff82111561407d57600080fd5b602001915036819003821315613c1f57600080fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c908216806140e557607f821691505b60208210810361411e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b67ffffffffffffffff841681526040602082015260006131ad604083018486614124565b602081526000610a38602083018486614124565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee18336030181126141d957600080fd5b9190910192915050565b600082601f8301126141f457600080fd5b813567ffffffffffffffff81111561420e5761420e613e89565b61423f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613ee1565b81815284602083860101111561425457600080fd5b816020850160208301376000918101602001919091529392505050565b6000610120823603121561428457600080fd5b61428c613eb8565b61429583613b3a565b815260208084013567ffffffffffffffff808211156142b357600080fd5b9085019036601f8301126142c657600080fd5b8135818111156142d8576142d8613e89565b8060051b6142e7858201613ee1565b918252838101850191858101903684111561430157600080fd5b86860192505b8383101561433d5782358581111561431f5760008081fd5b61432d3689838a01016141e3565b8352509186019190860190614307565b808789015250505050604086013592508083111561435a57600080fd5b5050614368368286016141e3565b60408301525061437b3660608501613f5e565b606082015261438d3660c08501613f5e565b608082015292915050565b601f821115610b4e576000816000526020600020601f850160051c810160208610156143c15750805b601f850160051c820191505b818110156143e0578281556001016143cd565b505050505050565b815167ffffffffffffffff81111561440257614402613e89565b6144168161441084546140d1565b84614398565b602080601f83116001811461446957600084156144335750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556143e0565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156144b657888601518255948401946001909101908401614497565b50858210156144f257878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff8716835280602084015261452681840187613a62565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506145649050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526131ad565b6000602082840312156145ad57600080fd5b81516122bc81613f30565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff82811682821603908111156106f1576106f16145b8565b600181815b8085111561465957817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561463f5761463f6145b8565b8085161561464c57918102915b93841c9390800290614605565b509250929050565b600082614670575060016106f1565b8161467d575060006106f1565b8160018114614693576002811461469d576146b9565b60019150506106f1565b60ff8411156146ae576146ae6145b8565b50506001821b6106f1565b5060208310610133831016604e8410600b84101617156146dc575081810a6106f1565b6146e68383614600565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614718576147186145b8565b029392505050565b60006122bc60ff841683614661565b600082614765577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176106f1576106f16145b8565b67ffffffffffffffff83168152604060208201526000610a386040830184613a62565b818103818111156106f1576106f16145b8565b67ffffffffffffffff8416815260e0810161480360208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152610a38565b606081016106f182848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561488857600080fd5b81516122bc81613abf565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b808201808211156106f1576106f16145b8565b600082516141d9818460208701613a3e56fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"localTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MismatchedArrayLengths\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectors\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config[]\",\"name\":\"outboundConfigs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config[]\",\"name\":\"inboundConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setChainRateLimiterConfigs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferLiquidity\",\"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\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101206040523480156200001257600080fd5b50604051620053a2380380620053a28339810160408190526200003591620005bb565b8585858584336000816200005c57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008f576200008f81620001f3565b50506001600160a01b0385161580620000af57506001600160a01b038116155b80620000c257506001600160a01b038216155b15620000e1576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808616608081905290831660c0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa92505050801562000151575060408051601f3d908101601f191682019092526200014e91810190620006ee565b60015b1562000191578060ff168560ff16146200018f576040516332ad3e0760e11b815260ff80871660048301528216602482015260440160405180910390fd5b505b60ff841660a052600480546001600160a01b0319166001600160a01b038316179055825115801560e052620001db57604080516000815260208101909152620001db90846200026d565b5050505091151561010052506200075a945050505050565b336001600160a01b038216036200021d57604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e0516200028e576040516335f4a7b360e01b815260040160405180910390fd5b60005b825181101562000319576000838281518110620002b257620002b26200070c565b60209081029190910101519050620002cc600282620003ca565b156200030f576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000291565b5060005b8151811015620003c55760008282815181106200033e576200033e6200070c565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200036a5750620003bc565b62000377600282620003ea565b15620003ba576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6001016200031d565b505050565b6000620003e1836001600160a01b03841662000401565b90505b92915050565b6000620003e1836001600160a01b03841662000505565b60008181526001830160205260408120548015620004fa5760006200042860018362000722565b85549091506000906200043e9060019062000722565b9050808214620004aa5760008660000182815481106200046257620004626200070c565b90600052602060002001549050808760000184815481106200048857620004886200070c565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620004be57620004be62000744565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620003e4565b6000915050620003e4565b60008181526001830160205260408120546200054e57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003e4565b506000620003e4565b6001600160a01b03811681146200056d57600080fd5b50565b805160ff811681146200058257600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b8051620005828162000557565b805180151581146200058257600080fd5b60008060008060008060c08789031215620005d557600080fd5b8651620005e28162000557565b95506020620005f388820162000570565b60408901519096506001600160401b03808211156200061157600080fd5b818a0191508a601f8301126200062657600080fd5b8151818111156200063b576200063b62000587565b8060051b604051601f19603f8301168101818110858211171562000663576200066362000587565b60405291825284820192508381018501918d8311156200068257600080fd5b938501935b82851015620006ab576200069b856200059d565b8452938501939285019262000687565b809950505050505050620006c2606088016200059d565b9250620006d260808801620005aa565b9150620006e260a088016200059d565b90509295509295509295565b6000602082840312156200070157600080fd5b620003e18262000570565b634e487b7160e01b600052603260045260246000fd5b81810381811115620003e457634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e05161010051614b776200082b600039600081816105d20152611c4e01526000818161066c015281816124a0015261315b01526000818161064601528181611fbd015261287601526000818161038201528181610ff301528181612166015281816122200152818161225401528181612287015281816122ec0152818161234501526123e70152600081816102e90152818161033e015281816107ad0152818161087f0152818161097301528181611d1001528181612f4f01526133460152614b776000f3fe608060405234801561001057600080fd5b506004361061025c5760003560e01c8063962d402011610145578063c0d78655116100bd578063dc0bd9711161008c578063e8a1da1711610071578063e8a1da1714610690578063eb521a4c146106a3578063f2fde38b146106b657600080fd5b8063dc0bd97114610644578063e0351e131461066a57600080fd5b8063c0d78655146105f6578063c4bffe2b14610609578063c75eea9c1461061e578063cf7401f31461063157600080fd5b8063acfecf9111610114578063b0f479a1116100f9578063b0f479a11461059f578063b7946580146105bd578063bb98546b146105d057600080fd5b8063acfecf911461051d578063af58d59f1461053057600080fd5b8063962d4020146104b55780639a4575b9146104c8578063a42a7b8b146104e8578063a7cd63b71461050857600080fd5b806354c8a4f3116101d85780636d3d1a58116101a75780637d54534e1161018c5780637d54534e146104715780638926f54f146104845780638da5cb5b1461049757600080fd5b80636d3d1a581461044b57806379ba50971461046957600080fd5b806354c8a4f3146103ff57806362ddd3c41461041257806366320087146104255780636cfd15531461043857600080fd5b8063240028e81161022f578063390775371161021457806339077537146103ac578063432a6ba3146103ce5780634c5ef0ed146103ec57600080fd5b8063240028e81461032e57806324f65ee71461037b57600080fd5b806301ffc9a7146102615780630a861f2a14610289578063181f5a771461029e57806321df0da7146102e7575b600080fd5b61027461026f366004613b6b565b6106c9565b60405190151581526020015b60405180910390f35b61029c610297366004613bad565b610725565b005b6102da6040518060400160405280601a81526020017f4c6f636b52656c65617365546f6b656e506f6f6c20312e352e3100000000000081525081565b6040516102809190613c34565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610280565b61027461033c366004613c69565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610280565b6103bf6103ba366004613c86565b6108d6565b60405190518152602001610280565b600a5473ffffffffffffffffffffffffffffffffffffffff16610309565b6102746103fa366004613cdf565b610a24565b61029c61040d366004613dae565b610a6e565b61029c610420366004613cdf565b610ae9565b61029c610433366004613e1a565b610b81565b61029c610446366004613c69565b610c5d565b60095473ffffffffffffffffffffffffffffffffffffffff16610309565b61029c610cac565b61029c61047f366004613c69565b610d7a565b610274610492366004613e46565b610dfb565b60015473ffffffffffffffffffffffffffffffffffffffff16610309565b61029c6104c3366004613ea6565b610e12565b6104db6104d6366004613f40565b610f6c565b6040516102809190613f7b565b6104fb6104f6366004613e46565b611038565b6040516102809190613fd2565b6105106111a3565b6040516102809190614054565b61029c61052b366004613cdf565b6111b4565b61054361053e366004613e46565b6112cc565b604051610280919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610309565b6102da6105cb366004613e46565b6113a1565b7f0000000000000000000000000000000000000000000000000000000000000000610274565b61029c610604366004613c69565b611451565b61061161152c565b60405161028091906140ae565b61054361062c366004613e46565b6115e4565b61029c61063f366004614236565b6116b6565b7f0000000000000000000000000000000000000000000000000000000000000000610309565b7f0000000000000000000000000000000000000000000000000000000000000000610274565b61029c61069e366004613dae565b61173a565b61029c6106b1366004613bad565b611c4c565b61029c6106c4366004613c69565b611d68565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d4056600000000000000000000000000000000000000000000000000000000148061071f575061071f82611d7c565b92915050565b600a5473ffffffffffffffffffffffffffffffffffffffff16331461077d576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610809573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061082d919061427b565b1015610865576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108a673ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611e60565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040805160208101909152600081526108ee82611f34565b6000610947606084013561094261090860c0870187614294565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061215892505050565b61221c565b905061099a61095c6060850160408601613c69565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169083611e60565b6109aa6060840160408501613c69565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f5283604051610a0891815260200190565b60405180910390a3604080516020810190915290815292915050565b6000610a668383604051610a399291906142f9565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190612430565b949350505050565b610a7661244b565b610ae38484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061249e92505050565b50505050565b610af161244b565b610afa83610dfb565b610b3c576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610774565b610b7c8383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061265492505050565b505050565b610b8961244b565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610bf157600080fd5b505af1158015610c05573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167f6fa7abcf1345d1d478e5ea0da6b5f26a90eadb0546ef15ed3833944fbfd1db6282604051610c5191815260200190565b60405180910390a25050565b610c6561244b565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cfd576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610d8261244b565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b600061071f600567ffffffffffffffff8416612430565b60095473ffffffffffffffffffffffffffffffffffffffff163314801590610e52575060015473ffffffffffffffffffffffffffffffffffffffff163314155b15610e8b576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610774565b8483141580610e9a5750848114155b15610ed1576040517f568efce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b85811015610f6357610f5b878783818110610ef157610ef1614309565b9050602002016020810190610f069190613e46565b868684818110610f1857610f18614309565b905060600201803603810190610f2e9190614338565b858585818110610f4057610f40614309565b905060600201803603810190610f569190614338565b61274e565b600101610ed4565b50505050505050565b6040805180820190915260608082526020820152610f8982612838565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a26040518060400160405280610fe38460200160208101906105cb9190613e46565b81526020016110306040805160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260609101604051602081830303815290604052905090565b905292915050565b67ffffffffffffffff8116600090815260076020526040812060609190611061906005016129c4565b90506000815167ffffffffffffffff81111561107f5761107f6140f0565b6040519080825280602002602001820160405280156110b257816020015b606081526020019060019003908161109d5790505b50905060005b825181101561119b57600860008483815181106110d7576110d7614309565b6020026020010151815260200190815260200160002080546110f890614354565b80601f016020809104026020016040519081016040528092919081815260200182805461112490614354565b80156111715780601f1061114657610100808354040283529160200191611171565b820191906000526020600020905b81548152906001019060200180831161115457829003601f168201915b505050505082828151811061118857611188614309565b60209081029190910101526001016110b8565b509392505050565b60606111af60026129c4565b905090565b6111bc61244b565b6111c583610dfb565b611207576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610774565b611247828260405161121a9291906142f9565b604080519182900390912067ffffffffffffffff86166000908152600760205291909120600501906129d1565b611283578282826040517f74f23c7c000000000000000000000000000000000000000000000000000000008152600401610774939291906143f0565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d7683836040516112bf929190614414565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261071f906129dd565b67ffffffffffffffff811660009081526007602052604090206004018054606091906113cc90614354565b80601f01602080910402602001604051908101604052809291908181526020018280546113f890614354565b80156114455780601f1061141a57610100808354040283529160200191611445565b820191906000526020600020905b81548152906001019060200180831161142857829003601f168201915b50505050509050919050565b61145961244b565b73ffffffffffffffffffffffffffffffffffffffff81166114a6576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b6060600061153a60056129c4565b90506000815167ffffffffffffffff811115611558576115586140f0565b604051908082528060200260200182016040528015611581578160200160208202803683370190505b50905060005b82518110156115dd578281815181106115a2576115a2614309565b60200260200101518282815181106115bc576115bc614309565b67ffffffffffffffff90921660209283029190910190910152600101611587565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261071f906129dd565b60095473ffffffffffffffffffffffffffffffffffffffff1633148015906116f6575060015473ffffffffffffffffffffffffffffffffffffffff163314155b1561172f576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610774565b610b7c83838361274e565b61174261244b565b60005b8381101561192f57600085858381811061176157611761614309565b90506020020160208101906117769190613e46565b905061178d600567ffffffffffffffff83166129d1565b6117cf576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610774565b67ffffffffffffffff811660009081526007602052604081206117f4906005016129c4565b905060005b81518110156118605761185782828151811061181757611817614309565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206005016129d190919063ffffffff16565b506001016117f9565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906118c96004830182613afe565b60058201600081816118db8282613b38565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169450602001925061191d915050565b60405180910390a15050600101611745565b5060005b81811015611c4557600083838381811061194f5761194f614309565b90506020028101906119619190614428565b61196a906144f4565b905061197b81606001516000612a8f565b61198a81608001516000612a8f565b8060400151516000036119c9576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516119e19060059067ffffffffffffffff16612bcc565b611a265780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610774565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a909102999093161717909416959095179092559092029091176003820155908201516004820190611ba9908261466b565b5060005b826020015151811015611bed57611be5836000015184602001518381518110611bd857611bd8614309565b6020026020010151612654565b600101611bad565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c28260000151836040015184606001518560800151604051611c339493929190614785565b60405180910390a15050600101611933565b5050505050565b7f0000000000000000000000000000000000000000000000000000000000000000611ca3576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a5473ffffffffffffffffffffffffffffffffffffffff163314611cf6576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610774565b611d3873ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612bd8565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611d7061244b565b611d7981612c36565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf000000000000000000000000000000000000000000000000000000001480611e0f57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061071f57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610b7c9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612cfa565b611f4761033c60a0830160808401613c69565b611fa657611f5b60a0820160808301613c69565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610774565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb611ff26040840160208501613e46565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015612063573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612087919061481e565b156120be576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120d66120d16040830160208401613e46565b612e06565b6120f66120e96040830160208401613e46565b6103fa60a0840184614294565b61213b5761210760a0820182614294565b6040517f24eb47e5000000000000000000000000000000000000000000000000000000008152600401610774929190614414565b611d7961214e6040830160208401613e46565b8260600135612f2c565b6000815160000361218a57507f0000000000000000000000000000000000000000000000000000000000000000919050565b81516020146121c757816040517f953576f70000000000000000000000000000000000000000000000000000000081526004016107749190613c34565b6000828060200190518101906121dd919061427b565b905060ff81111561071f57826040517f953576f70000000000000000000000000000000000000000000000000000000081526004016107749190613c34565b60007f000000000000000000000000000000000000000000000000000000000000000060ff168260ff160361225257508161071f565b7f000000000000000000000000000000000000000000000000000000000000000060ff168260ff16111561233d5760006122ac7f00000000000000000000000000000000000000000000000000000000000000008461486a565b9050604d8160ff161115612320576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f000000000000000000000000000000000000000000000000000000000000000016602482015260448101859052606401610774565b61232b81600a6149a3565b61233590856149b2565b91505061071f565b6000612369837f000000000000000000000000000000000000000000000000000000000000000061486a565b9050604d8160ff1611806123b0575061238381600a6149a3565b6123ad907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6149b2565b84115b1561241b576040517fa9cb113d00000000000000000000000000000000000000000000000000000000815260ff80851660048301527f000000000000000000000000000000000000000000000000000000000000000016602482015260448101859052606401610774565b61242681600a6149a3565b610a6690856149ed565b600081815260018301602052604081205415155b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461249c576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f00000000000000000000000000000000000000000000000000000000000000006124f5576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561258b57600083828151811061251557612515614309565b60200260200101519050612533816002612f7390919063ffffffff16565b156125825760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016124f8565b5060005b8151811015610b7c5760008282815181106125ac576125ac614309565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036125f0575061264c565b6125fb600282612f95565b1561264a5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010161258f565b805160000361268f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff84166000908152600790925260409091206126c19060050182612bcc565b6126fb5782826040517f393b8ad2000000000000000000000000000000000000000000000000000000008152600401610774929190614a04565b6000818152600860205260409020612713838261466b565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea836040516112bf9190613c34565b61275783610dfb565b612799576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610774565b6127a4826000612a8f565b67ffffffffffffffff831660009081526007602052604090206127c79083612fb7565b6127d2816000612a8f565b67ffffffffffffffff831660009081526007602052604090206127f89060020182612fb7565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161282b93929190614a27565b60405180910390a1505050565b61284b61033c60a0830160808401613c69565b61285f57611f5b60a0820160808301613c69565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6128ab6040840160208501613e46565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa15801561291c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612940919061481e565b15612977576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61298f61298a6060830160408401613c69565b613159565b6129a76129a26040830160208401613e46565b6131d8565b611d796129ba6040830160208401613e46565b8260600135613326565b606060006124448361336a565b600061244483836133c5565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152612a6b82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642612a4f9190614aaa565b85608001516fffffffffffffffffffffffffffffffff166134b8565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b815115612b5a5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612ae5575060408201516fffffffffffffffffffffffffffffffff16155b15612b1e57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107749190614abd565b8015612b56576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580612b93575060208201516fffffffffffffffffffffffffffffffff1615155b15612b5657816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107749190614abd565b600061244483836134e0565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610ae39085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611eb2565b3373ffffffffffffffffffffffffffffffffffffffff821603612c85576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612d5c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661352f9092919063ffffffff16565b805190915015610b7c5780806020019051810190612d7a919061481e565b610b7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610774565b612e0f81610dfb565b612e51576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610774565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612ed0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ef4919061481e565b611d79576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610774565b67ffffffffffffffff82166000908152600760205260409020612b5690600201827f000000000000000000000000000000000000000000000000000000000000000061353e565b60006124448373ffffffffffffffffffffffffffffffffffffffff84166133c5565b60006124448373ffffffffffffffffffffffffffffffffffffffff84166134e0565b8154600090612fe090700100000000000000000000000000000000900463ffffffff1642614aaa565b905080156130825760018301548354613028916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166134b8565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546130a8916fffffffffffffffffffffffffffffffff90811691166138c1565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061282b908490614abd565b7f000000000000000000000000000000000000000000000000000000000000000015611d795761318a6002826138d7565b611d79576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610774565b6131e181610dfb565b613223576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610774565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561329c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132c09190614af9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611d79576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610774565b67ffffffffffffffff82166000908152600760205260409020612b5690827f000000000000000000000000000000000000000000000000000000000000000061353e565b60608160000180548060200260200160405190810160405280929190818152602001828054801561144557602002820191906000526020600020905b8154815260200190600101908083116133a65750505050509050919050565b600081815260018301602052604081205480156134ae5760006133e9600183614aaa565b85549091506000906133fd90600190614aaa565b905080821461346257600086600001828154811061341d5761341d614309565b906000526020600020015490508087600001848154811061344057613440614309565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061347357613473614b16565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061071f565b600091505061071f565b60006134d7856134c884866149ed565b6134d29087614b45565b6138c1565b95945050505050565b60008181526001830160205260408120546135275750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561071f565b50600061071f565b6060610a668484600085613906565b825474010000000000000000000000000000000000000000900460ff161580613565575081155b1561356f57505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906135b590700100000000000000000000000000000000900463ffffffff1642614aaa565b9050801561367557818311156135f7576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546136319083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166134b8565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b8482101561372c5773ffffffffffffffffffffffffffffffffffffffff84166136d4576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610774565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610774565b8483101561383f5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906137709082614aaa565b61377a878a614aaa565b6137849190614b45565b61378e91906149b2565b905073ffffffffffffffffffffffffffffffffffffffff86166137e7576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610774565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610774565b6138498584614aaa565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60008183106138d05781612444565b5090919050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515612444565b606082471015613998576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610774565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516139c19190614b58565b60006040518083038185875af1925050503d80600081146139fe576040519150601f19603f3d011682016040523d82523d6000602084013e613a03565b606091505b5091509150613a1487838387613a1f565b979650505050505050565b60608315613ab5578251600003613aae5773ffffffffffffffffffffffffffffffffffffffff85163b613aae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610774565b5081610a66565b610a668383815115613aca5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107749190613c34565b508054613b0a90614354565b6000825580601f10613b1a575050565b601f016020900490600052602060002090810190611d799190613b52565b5080546000825590600052602060002090810190611d7991905b5b80821115613b675760008155600101613b53565b5090565b600060208284031215613b7d57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461244457600080fd5b600060208284031215613bbf57600080fd5b5035919050565b60005b83811015613be1578181015183820152602001613bc9565b50506000910152565b60008151808452613c02816020860160208601613bc6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006124446020830184613bea565b73ffffffffffffffffffffffffffffffffffffffff81168114611d7957600080fd5b600060208284031215613c7b57600080fd5b813561244481613c47565b600060208284031215613c9857600080fd5b813567ffffffffffffffff811115613caf57600080fd5b8201610100818503121561244457600080fd5b803567ffffffffffffffff81168114613cda57600080fd5b919050565b600080600060408486031215613cf457600080fd5b613cfd84613cc2565b9250602084013567ffffffffffffffff80821115613d1a57600080fd5b818601915086601f830112613d2e57600080fd5b813581811115613d3d57600080fd5b876020828501011115613d4f57600080fd5b6020830194508093505050509250925092565b60008083601f840112613d7457600080fd5b50813567ffffffffffffffff811115613d8c57600080fd5b6020830191508360208260051b8501011115613da757600080fd5b9250929050565b60008060008060408587031215613dc457600080fd5b843567ffffffffffffffff80821115613ddc57600080fd5b613de888838901613d62565b90965094506020870135915080821115613e0157600080fd5b50613e0e87828801613d62565b95989497509550505050565b60008060408385031215613e2d57600080fd5b8235613e3881613c47565b946020939093013593505050565b600060208284031215613e5857600080fd5b61244482613cc2565b60008083601f840112613e7357600080fd5b50813567ffffffffffffffff811115613e8b57600080fd5b602083019150836020606083028501011115613da757600080fd5b60008060008060008060608789031215613ebf57600080fd5b863567ffffffffffffffff80821115613ed757600080fd5b613ee38a838b01613d62565b90985096506020890135915080821115613efc57600080fd5b613f088a838b01613e61565b90965094506040890135915080821115613f2157600080fd5b50613f2e89828a01613e61565b979a9699509497509295939492505050565b600060208284031215613f5257600080fd5b813567ffffffffffffffff811115613f6957600080fd5b820160a0818503121561244457600080fd5b602081526000825160406020840152613f976060840182613bea565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160408501526134d78282613bea565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015614047577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452614035858351613bea565b94509285019290850190600101613ffb565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b818110156140a257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614070565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156140a257835167ffffffffffffffff16835292840192918401916001016140ca565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715614142576141426140f0565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561418f5761418f6140f0565b604052919050565b8015158114611d7957600080fd5b80356fffffffffffffffffffffffffffffffff81168114613cda57600080fd5b6000606082840312156141d757600080fd5b6040516060810181811067ffffffffffffffff821117156141fa576141fa6140f0565b604052905080823561420b81614197565b8152614219602084016141a5565b602082015261422a604084016141a5565b60408201525092915050565b600080600060e0848603121561424b57600080fd5b61425484613cc2565b925061426385602086016141c5565b915061427285608086016141c5565b90509250925092565b60006020828403121561428d57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126142c957600080fd5b83018035915067ffffffffffffffff8211156142e457600080fd5b602001915036819003821315613da757600080fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006060828403121561434a57600080fd5b61244483836141c5565b600181811c9082168061436857607f821691505b6020821081036143a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b67ffffffffffffffff841681526040602082015260006134d76040830184866143a7565b602081526000610a666020830184866143a7565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee183360301811261445c57600080fd5b9190910192915050565b600082601f83011261447757600080fd5b813567ffffffffffffffff811115614491576144916140f0565b6144c260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614148565b8181528460208386010111156144d757600080fd5b816020850160208301376000918101602001919091529392505050565b6000610120823603121561450757600080fd5b61450f61411f565b61451883613cc2565b815260208084013567ffffffffffffffff8082111561453657600080fd5b9085019036601f83011261454957600080fd5b81358181111561455b5761455b6140f0565b8060051b61456a858201614148565b918252838101850191858101903684111561458457600080fd5b86860192505b838310156145c0578235858111156145a25760008081fd5b6145b03689838a0101614466565b835250918601919086019061458a565b80878901525050505060408601359250808311156145dd57600080fd5b50506145eb36828601614466565b6040830152506145fe36606085016141c5565b60608201526146103660c085016141c5565b608082015292915050565b601f821115610b7c576000816000526020600020601f850160051c810160208610156146445750805b601f850160051c820191505b8181101561466357828155600101614650565b505050505050565b815167ffffffffffffffff811115614685576146856140f0565b614699816146938454614354565b8461461b565b602080601f8311600181146146ec57600084156146b65750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555614663565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156147395788860151825594840194600190910190840161471a565b508582101561477557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526147a981840187613bea565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506147e79050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e08301526134d7565b60006020828403121561483057600080fd5b815161244481614197565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff828116828216039081111561071f5761071f61483b565b600181815b808511156148dc57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156148c2576148c261483b565b808516156148cf57918102915b93841c9390800290614888565b509250929050565b6000826148f35750600161071f565b816149005750600061071f565b816001811461491657600281146149205761493c565b600191505061071f565b60ff8411156149315761493161483b565b50506001821b61071f565b5060208310610133831016604e8410600b841016171561495f575081810a61071f565b6149698383614883565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561499b5761499b61483b565b029392505050565b600061244460ff8416836148e4565b6000826149e8577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761071f5761071f61483b565b67ffffffffffffffff83168152604060208201526000610a666040830184613bea565b67ffffffffffffffff8416815260e08101614a7360208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152610a66565b8181038181111561071f5761071f61483b565b6060810161071f82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060208284031215614b0b57600080fd5b815161244481613c47565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8082018082111561071f5761071f61483b565b6000825161445c818460208701613bc656fea164736f6c6343000818000a", } var LockReleaseTokenPoolABI = LockReleaseTokenPoolMetaData.ABI @@ -769,6 +769,18 @@ func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) SetChainRate return _LockReleaseTokenPool.Contract.SetChainRateLimiterConfig(&_LockReleaseTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) } +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "setChainRateLimiterConfigs", remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetChainRateLimiterConfigs(&_LockReleaseTokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.SetChainRateLimiterConfigs(&_LockReleaseTokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) { return _LockReleaseTokenPool.contract.Transact(opts, "setRateLimitAdmin", rateLimitAdmin) } @@ -3549,6 +3561,8 @@ type LockReleaseTokenPoolInterface interface { SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) + SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) SetRebalancer(opts *bind.TransactOpts, rebalancer common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/offramp/offramp.go b/core/gethwrappers/ccip/generated/offramp/offramp.go index b582b60cff6..830dcaf7bf4 100644 --- a/core/gethwrappers/ccip/generated/offramp/offramp.go +++ b/core/gethwrappers/ccip/generated/offramp/offramp.go @@ -148,15 +148,16 @@ type OffRampSourceChainConfigArgs struct { } type OffRampStaticConfig struct { - ChainSelector uint64 - RmnRemote common.Address - TokenAdminRegistry common.Address - NonceManager common.Address + ChainSelector uint64 + GasForCallExactCheck uint16 + RmnRemote common.Address + TokenAdminRegistry common.Address + NonceManager common.Address } var OffRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRMNRemote\",\"name\":\"rmnRemote\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isRMNVerificationDisabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"messageInterceptor\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reportOnRamp\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"configOnRamp\",\"type\":\"bytes\"}],\"name\":\"CommitOnRampMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyBatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"tokenIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"oldLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenGasOverride\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionTokenGasOverride\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidOnRampUpdate\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionGasAmountCountMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignatureVerificationNotAllowedInExecutionPlugin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignatureVerificationRequiredInCommitPlugin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"reportSourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"messageSourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRampAddress\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"maxSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structInternal.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isRMNVerificationDisabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"messageInterceptor\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"name\":\"ExecutionStateChanged\",\"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\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SkippedReportExecution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRMNRemote\",\"name\":\"rmnRemote\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[2]\",\"name\":\"reportContext\",\"type\":\"bytes32[2]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[2]\",\"name\":\"reportContext\",\"type\":\"bytes32[2]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"destTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destGasAmount\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.Any2EVMTokenTransfer[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"uint32[]\",\"name\":\"tokenGasOverrides\",\"type\":\"uint32[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllSourceChainConfigs\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isRMNVerificationDisabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"messageInterceptor\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"contractIRMNRemote\",\"name\":\"rmnRemote\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"destTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destGasAmount\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.Any2EVMTokenTransfer[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receiverExecutionGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint32[]\",\"name\":\"tokenGasOverrides\",\"type\":\"uint32[]\"}],\"internalType\":\"structOffRamp.GasLimitOverride[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"tuple[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isRMNVerificationDisabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"messageInterceptor\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"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: "0x6101206040523480156200001257600080fd5b5060405162006be738038062006be7833981016040819052620000359162000880565b336000816200005757604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008a576200008a81620001c4565b50504660805260208301516001600160a01b03161580620000b6575060408301516001600160a01b0316155b80620000cd575060608301516001600160a01b0316155b15620000ec576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b0316600003620001185760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a052602080850180516001600160a01b0390811660c05260408088018051831660e0526060808a01805185166101005283518b519098168852945184169587019590955251821690850152905116908201527f683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d89060800160405180910390a1620001b0826200023e565b620001bb816200032c565b50505062000c72565b336001600160a01b03821603620001ee57604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b031662000267576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516001600160a01b039889166001600160c01b03199097168717600160a01b63ffffffff958616021760ff60c01b1916600160c01b911515919091021790965560608089018051600580546001600160a01b031916918b169190911790558251968752935190921693850193909352935115159183019190915251909216908201527fcbb53bda7106a610de67df506ac86b65c44d5afac0fd2b11070dc2d61a6f2dee9060800160405180910390a150565b60005b8151811015620005c1576000828281518110620003505762000350620009aa565b60200260200101519050600081602001519050806001600160401b03166000036200038e5760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b0316620003b7576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b03811660009081526008602052604090206060830151600182018054620003e590620009c0565b905060000362000448578154600160a81b600160e81b031916600160a81b1782556040516001600160401b03841681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620004b9565b8154600160a81b90046001600160401b03166001148015906200048b57508051602082012060405162000480906001850190620009fc565b604051809103902014155b15620004b957604051632105803760e11b81526001600160401b038416600482015260240160405180910390fd5b80511580620004ef5750604080516000602082015201604051602081830303815290604052805190602001208180519060200120145b156200050e576040516342bcdf7f60e11b815260040160405180910390fd5b600182016200051e828262000acf565b506040840151825485516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b0319909116171782556200056d60066001600160401b038516620005c5565b50826001600160401b03167f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b83604051620005a9919062000b9b565b60405180910390a2505050508060010190506200032f565b5050565b6000620005d38383620005dc565b90505b92915050565b60008181526001830160205260408120546200062557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620005d6565b506000620005d6565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156200066957620006696200062e565b60405290565b604051601f8201601f191681016001600160401b03811182821017156200069a576200069a6200062e565b604052919050565b80516001600160401b0381168114620006ba57600080fd5b919050565b6001600160a01b0381168114620006d557600080fd5b50565b80518015158114620006ba57600080fd5b6000601f83601f840112620006fd57600080fd5b825160206001600160401b03808311156200071c576200071c6200062e565b8260051b6200072d8382016200066f565b93845286810183019383810190898611156200074857600080fd5b84890192505b858310156200087357825184811115620007685760008081fd5b89016080601f19828d038101821315620007825760008081fd5b6200078c62000644565b888401516200079b81620006bf565b81526040620007ac858201620006a2565b8a8301526060620007bf818701620006d8565b83830152938501519389851115620007d75760008081fd5b84860195508f603f870112620007ef57600094508485fd5b8a8601519450898511156200080857620008086200062e565b620008198b858f880116016200066f565b93508484528f82868801011115620008315760008081fd5b60005b8581101562000851578681018301518582018d01528b0162000834565b5060009484018b0194909452509182015283525091840191908401906200074e565b9998505050505050505050565b60008060008385036101208112156200089857600080fd5b6080811215620008a757600080fd5b620008b162000644565b620008bc86620006a2565b81526020860151620008ce81620006bf565b60208201526040860151620008e381620006bf565b60408201526060860151620008f881620006bf565b606082015293506080607f19820112156200091257600080fd5b506200091d62000644565b60808501516200092d81620006bf565b815260a085015163ffffffff811681146200094757600080fd5b60208201526200095a60c08601620006d8565b604082015260e08501516200096f81620006bf565b60608201526101008501519092506001600160401b038111156200099257600080fd5b620009a086828701620006e9565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c90821680620009d557607f821691505b602082108103620009f657634e487b7160e01b600052602260045260246000fd5b50919050565b600080835462000a0c81620009c0565b6001828116801562000a27576001811462000a3d5762000a6e565b60ff198416875282151583028701945062000a6e565b8760005260208060002060005b8581101562000a655781548a82015290840190820162000a4a565b50505082870194505b50929695505050505050565b601f82111562000aca576000816000526020600020601f850160051c8101602086101562000aa55750805b601f850160051c820191505b8181101562000ac65782815560010162000ab1565b5050505b505050565b81516001600160401b0381111562000aeb5762000aeb6200062e565b62000b038162000afc8454620009c0565b8462000a7a565b602080601f83116001811462000b3b576000841562000b225750858301515b600019600386901b1c1916600185901b17855562000ac6565b600085815260208120601f198616915b8281101562000b6c5788860151825594840194600190910190840162000b4b565b508582101562000b8b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000bf081620009c0565b8060a089015260c0600183166000811462000c14576001811462000c315762000c63565b60ff19841660c08b015260c083151560051b8b0101945062000c63565b85600052602060002060005b8481101562000c5a5781548c820185015290880190890162000c3d565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e05161010051615ef862000cef600039600081816102070152612a4a0152600081816101d80152612cf20152600081816101a901528181610f7501528181611125015261244a01526000818161017a015281816125f501526126ac01526000818161190401526119370152615ef86000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c80637edf52f4116100ad578063de5e0b9a11610071578063de5e0b9a146104b2578063e9d68a8e146104c5578063f2fde38b146104e5578063f58e03fc146104f8578063f716f99f1461050b57600080fd5b80637edf52f41461041257806385572ffb146104255780638da5cb5b14610433578063c673e5841461044e578063ccd37ba31461046e57600080fd5b80635e36480c116100f45780635e36480c146103075780635e7bb0081461032757806360987c201461033a5780637437ff9f1461034d57806379ba50971461040a57600080fd5b806304666f9c1461013157806306285c6914610146578063181f5a771461028d5780633f4b04aa146102d65780635215505b146102f1575b600080fd5b61014461013f366004613e1c565b61051e565b005b61023760408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160401b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b604051610284919081516001600160401b031681526020808301516001600160a01b0390811691830191909152604080840151821690830152606092830151169181019190915260800190565b60405180910390f35b6102c96040518060400160405280601181526020017f4f666652616d7020312e362e302d64657600000000000000000000000000000081525081565b6040516102849190613f8a565b600b546040516001600160401b039091168152602001610284565b6102f9610532565b604051610284929190613fe4565b61031a610315366004614085565b61078d565b60405161028491906140e2565b61014461033536600461464b565b6107e2565b6101446103483660046148da565b610a76565b6103c360408051608081018252600080825260208201819052918101829052606081019190915250604080516080810182526004546001600160a01b038082168352600160a01b820463ffffffff166020840152600160c01b90910460ff16151592820192909252600554909116606082015290565b604051610284919081516001600160a01b03908116825260208084015163ffffffff1690830152604080840151151590830152606092830151169181019190915260800190565b610144610d33565b61014461042036600461496e565b610db6565b61014461012c3660046149d3565b6001546040516001600160a01b039091168152602001610284565b61046161045c366004614a1e565b610dc7565b6040516102849190614a7e565b6104a461047c366004614af3565b6001600160401b03919091166000908152600a60209081526040808320938352929052205490565b604051908152602001610284565b6101446104c0366004614b6f565b610f25565b6104d86104d3366004614c21565b611428565b6040516102849190614c3c565b6101446104f3366004614c4f565b611534565b610144610506366004614c6c565b611545565b610144610519366004614d27565b6115ae565b6105266115f0565b61052f8161161d565b50565b606080600061054160066118a6565b6001600160401b0381111561055857610558613c3c565b6040519080825280602002602001820160405280156105a957816020015b60408051608081018252600080825260208083018290529282015260608082015282526000199092019101816105765790505b50905060006105b860066118a6565b6001600160401b038111156105cf576105cf613c3c565b6040519080825280602002602001820160405280156105f8578160200160208202803683370190505b50905060005b61060860066118a6565b8110156107845761061a6006826118b0565b82828151811061062c5761062c614e64565b60200260200101906001600160401b031690816001600160401b0316815250506008600083838151811061066257610662614e64565b6020908102919091018101516001600160401b039081168352828201939093526040918201600020825160808101845281546001600160a01b038116825260ff600160a01b820416151593820193909352600160a81b909204909316918101919091526001820180549192916060840191906106dd90614e7a565b80601f016020809104026020016040519081016040528092919081815260200182805461070990614e7a565b80156107565780601f1061072b57610100808354040283529160200191610756565b820191906000526020600020905b81548152906001019060200180831161073957829003601f168201915b50505050508152505083828151811061077157610771614e64565b60209081029190910101526001016105fe565b50939092509050565b600061079b60016004614eca565b60026107a8608085614ef3565b6001600160401b03166107bb9190614f19565b6107c585856118bc565b901c1660038111156107d9576107d96140b8565b90505b92915050565b6107ea611901565b81518151811461080d576040516320f8fd5960e21b815260040160405180910390fd5b60005b81811015610a6657600084828151811061082c5761082c614e64565b6020026020010151905060008160200151519050600085848151811061085457610854614e64565b602002602001015190508051821461087f576040516320f8fd5960e21b815260040160405180910390fd5b60005b82811015610a5757600082828151811061089e5761089e614e64565b60200260200101516000015190506000856020015183815181106108c4576108c4614e64565b602002602001015190508160001461091d57806080015182101561091d578551815151604051633a98d46360e11b81526001600160401b0390921660048301526024820152604481018390526064015b60405180910390fd5b83838151811061092f5761092f614e64565b602002602001015160200151518160a00151511461097c57805180516060909101516040516370a193fd60e01b815260048101929092526001600160401b03166024820152604401610914565b60005b8160a0015151811015610a495760008585815181106109a0576109a0614e64565b60200260200101516020015182815181106109bd576109bd614e64565b602002602001015163ffffffff16905080600014610a405760008360a0015183815181106109ed576109ed614e64565b60200260200101516040015163ffffffff16905080821015610a3e578351516040516348e617b360e01b81526004810191909152602481018490526044810182905260648101839052608401610914565b505b5060010161097f565b505050806001019050610882565b50505050806001019050610810565b50610a718383611969565b505050565b333014610a96576040516306e34e6560e31b815260040160405180910390fd5b6040805160008082526020820190925281610ad3565b6040805180820190915260008082526020820152815260200190600190039081610aac5790505b5060a08701515190915015610b0957610b068660a001518760200151886060015189600001516020015189898989611a2c565b90505b6040805160a081018252875151815287516020908101516001600160401b03168183015288015181830152908701516060820152608081018290526005546001600160a01b03168015610bfc576040516308d450a160e01b81526001600160a01b038216906308d450a190610b82908590600401614fdd565b600060405180830381600087803b158015610b9c57600080fd5b505af1925050508015610bad575060015b610bfc573d808015610bdb576040519150601f19603f3d011682016040523d82523d6000602084013e610be0565b606091505b50806040516309c2532560e01b81526004016109149190613f8a565b604088015151158015610c1157506080880151155b80610c28575060608801516001600160a01b03163b155b80610c4f57506060880151610c4d906001600160a01b03166385572ffb60e01b611bdd565b155b15610c5c57505050610d2c565b87516020908101516001600160401b03166000908152600890915260408082205460808b015160608c01519251633cf9798360e01b815284936001600160a01b0390931692633cf9798392610cba9289926113889291600401614ff0565b6000604051808303816000875af1158015610cd9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d01919081019061502c565b509150915081610d2657806040516302a35ba360e21b81526004016109149190613f8a565b50505050505b5050505050565b6000546001600160a01b03163314610d5e5760405163015aa1e360e11b815260040160405180910390fd5b600180546001600160a01b0319808216339081179093556000805490911681556040516001600160a01b03909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610dbe6115f0565b61052f81611bf9565b610e0a6040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610eb357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e95575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610f1557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ef7575b5050505050815250509050919050565b6000610f33878901896152d9565b6004805491925090600160c01b900460ff16610fdd5760208201515115610fdd5760208201516040808401519051633854844f60e11b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016926370a9089e92610fac9230929190600401615501565b60006040518083038186803b158015610fc457600080fd5b505afa158015610fd8573d6000803e3d6000fd5b505050505b81515151151580610ff357508151602001515115155b156110be57600b5460208b0135906001600160401b038083169116101561109657600b805467ffffffffffffffff19166001600160401b03831617905581548351604051633937306f60e01b81526001600160a01b0390921691633937306f9161105f91600401615614565b600060405180830381600087803b15801561107957600080fd5b505af115801561108d573d6000803e3d6000fd5b505050506110bc565b8260200151516000036110bc57604051632261116760e01b815260040160405180910390fd5b505b60005b826020015151811015611374576000836020015182815181106110e6576110e6614e64565b60209081029190910101518051604051632cbc26bb60e01b815267ffffffffffffffff60801b608083901b166004820152919250906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa15801561116c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111909190615627565b156111b957604051637edeb53960e11b81526001600160401b0382166004820152602401610914565b60006111c482611cfe565b9050806001016040516111d79190615644565b6040518091039020836020015180519060200120146112145782602001518160010160405163b80d8fa960e01b8152600401610914929190615737565b60408301518154600160a81b90046001600160401b039081169116141580611255575082606001516001600160401b031683604001516001600160401b0316115b1561129a57825160408085015160608601519151636af0786b60e11b81526001600160401b039384166004820152908316602482015291166044820152606401610914565b6080830151806112bd5760405163504570e360e01b815260040160405180910390fd5b83516001600160401b03166000908152600a60209081526040808320848452909152902054156113155783516040516332cf0cbf60e01b81526001600160401b03909116600482015260248101829052604401610914565b606084015161132590600161575c565b825467ffffffffffffffff60a81b1916600160a81b6001600160401b0392831602179092559251166000908152600a6020908152604080832094835293905291909120429055506001016110c1565b50602082015182516040517f35c02761bcd3ef995c6a601a1981f4ed3934dcbe5041e24e286c89f5531d17e4926113ac929091615783565b60405180910390a1610d2660008b8b8b8b8b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808f0282810182019093528e82529093508e92508d9182918501908490808284376000920191909152508c9250611d4a915050565b60408051608080820183526000808352602080840182905283850182905260608085018190526001600160401b03878116845260088352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b9092049092169483019490945260018401805493949293918401916114b490614e7a565b80601f01602080910402602001604051908101604052809291908181526020018280546114e090614e7a565b8015610f155780601f1061150257610100808354040283529160200191610f15565b820191906000526020600020905b81548152906001019060200180831161151057505050919092525091949350505050565b61153c6115f0565b61052f81612043565b611585611554828401846157a8565b604080516000808252602082019092529061157f565b606081526020019060019003908161156a5790505b50611969565b6040805160008082526020820190925290506115a8600185858585866000611d4a565b50505050565b6115b66115f0565b60005b81518110156115ec576115e48282815181106115d7576115d7614e64565b60200260200101516120bc565b6001016115b9565b5050565b6001546001600160a01b0316331461161b576040516315ae3a6f60e11b815260040160405180910390fd5b565b60005b81518110156115ec57600082828151811061163d5761163d614e64565b60200260200101519050600081602001519050806001600160401b031660000361167a5760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166116a2576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b038116600090815260086020526040902060608301516001820180546116ce90614e7a565b905060000361173057815467ffffffffffffffff60a81b1916600160a81b1782556040516001600160401b03841681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1611799565b8154600160a81b90046001600160401b0316600114801590611770575080516020820120604051611765906001850190615644565b604051809103902014155b1561179957604051632105803760e11b81526001600160401b0384166004820152602401610914565b805115806117ce5750604080516000602082015201604051602081830303815290604052805190602001208180519060200120145b156117ec576040516342bcdf7f60e11b815260040160405180910390fd5b600182016117fa828261582c565b506040840151825485516001600160a01b03166001600160a01b0319921515600160a01b029290921674ffffffffffffffffffffffffffffffffffffffffff199091161717825561185560066001600160401b0385166123e6565b50826001600160401b03167f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b8360405161188f91906158eb565b60405180910390a250505050806001019050611620565b60006107dc825490565b60006107d983836123f2565b6001600160401b0382166000908152600960205260408120816118e0608085615939565b6001600160401b031681526020810191909152604001600020549392505050565b467f00000000000000000000000000000000000000000000000000000000000000001461161b57604051630f01ce8560e01b81527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610914565b815160000361198b5760405163c2e5347d60e01b815260040160405180910390fd5b805160408051600080825260208201909252911591816119ce565b6040805180820190915260008152606060208201528152602001906001900390816119a65790505b50905060005b8451811015610d2c57611a248582815181106119f2576119f2614e64565b602002602001015184611a1e57858381518110611a1157611a11614e64565b602002602001015161241c565b8361241c565b6001016119d4565b606088516001600160401b03811115611a4757611a47613c3c565b604051908082528060200260200182016040528015611a8c57816020015b6040805180820190915260008082526020820152815260200190600190039081611a655790505b509050811560005b8a51811015611bcf5781611b2c57848482818110611ab457611ab4614e64565b9050602002016020810190611ac9919061595f565b63ffffffff1615611b2c57848482818110611ae657611ae6614e64565b9050602002016020810190611afb919061595f565b8b8281518110611b0d57611b0d614e64565b60200260200101516040019063ffffffff16908163ffffffff16815250505b611baa8b8281518110611b4157611b41614e64565b60200260200101518b8b8b8b8b87818110611b5e57611b5e614e64565b9050602002810190611b70919061597a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612cb792505050565b838281518110611bbc57611bbc614e64565b6020908102919091010152600101611a94565b505098975050505050505050565b6000611be883612f99565b80156107d957506107d98383612fcc565b80516001600160a01b0316611c21576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516001600160a01b039889167fffffffffffffffff0000000000000000000000000000000000000000000000009097168717600160a01b63ffffffff958616021760ff60c01b1916600160c01b911515919091021790965560608089018051600580546001600160a01b031916918b169190911790558251968752935190921693850193909352935115159183019190915251909216908201527fcbb53bda7106a610de67df506ac86b65c44d5afac0fd2b11070dc2d61a6f2dee9060800160405180910390a150565b6001600160401b03811660009081526008602052604081208054600160a01b900460ff166107dc5760405163ed053c5960e01b81526001600160401b0384166004820152602401610914565b60ff87811660009081526002602090815260408083208151608081018352815481526001909101548086169382019390935261010083048516918101919091526201000090910490921615156060830152873590611da98760846159c0565b9050826060015115611df1578451611dc2906020614f19565b8651611dcf906020614f19565b611dda9060a06159c0565b611de491906159c0565b611dee90826159c0565b90505b368114611e1a57604051638e1192e160e01b815260048101829052366024820152604401610914565b5081518114611e495781516040516324f7d61360e21b8152600481019190915260248101829052604401610914565b611e51611901565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611e9f57611e9f6140b8565b6002811115611eb057611eb06140b8565b9052509050600281602001516002811115611ecd57611ecd6140b8565b148015611f215750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611f0957611f09614e64565b6000918252602090912001546001600160a01b031633145b611f3e57604051631b41e11d60e31b815260040160405180910390fd5b50816060015115611fee576020820151611f599060016159d3565b60ff16855114611f7c576040516371253a2560e01b815260040160405180910390fd5b8351855114611f9e5760405163a75d88af60e01b815260040160405180910390fd5b60008787604051611fb09291906159ec565b604051908190038120611fc7918b906020016159fc565b604051602081830303815290604052805190602001209050611fec8a82888888613056565b505b6040805182815260208a8101356001600160401b03169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b336001600160a01b0382160361206c57604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff166000036120e7576000604051631b3fab5160e11b81526004016109149190615a10565b60208082015160ff80821660009081526002909352604083206001810154929390928392169003612138576060840151600182018054911515620100000262ff000019909216919091179055612174565b6060840151600182015460ff6201000090910416151590151514612174576040516321fd80df60e21b815260ff84166004820152602401610914565b60a0840151805161010010156121a0576001604051631b3fab5160e11b81526004016109149190615a10565b80516000036121c5576005604051631b3fab5160e11b81526004016109149190615a10565b61222b848460030180548060200260200160405190810160405280929190818152602001828054801561222157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612203575b5050505050613209565b84606001511561235b576122998484600201805480602002602001604051908101604052809291908181526020018280548015612221576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311612203575050505050613209565b6080850151805161010010156122c5576002604051631b3fab5160e11b81526004016109149190615a10565b60408601516122d5906003615a2a565b60ff168151116122fb576003604051631b3fab5160e11b81526004016109149190615a10565b815181511015612321576001604051631b3fab5160e11b81526004016109149190615a10565b805160018401805461ff00191661010060ff84160217905561234c9060028601906020840190613bc2565b5061235985826001613272565b505b61236784826002613272565b805161237c9060038501906020840190613bc2565b5060408581015160018401805460ff191660ff8316179055865180855560a088015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f547936123d59389939260028a01929190615a46565b60405180910390a1610d2c846133cd565b60006107d98383613450565b600082600001828154811061240957612409614e64565b9060005260206000200154905092915050565b81518151604051632cbc26bb60e01b8152608083901b67ffffffffffffffff60801b166004820152901515907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa158015612499573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124bd9190615627565b1561252e5780156124ec57604051637edeb53960e11b81526001600160401b0383166004820152602401610914565b6040516001600160401b03831681527faab522ed53d887e56ed53dd37398a01aeef6a58e0fa77c2173beb9512d8949339060200160405180910390a150505050565b602084015151600081900361256457845160405163676cf24b60e11b81526001600160401b039091166004820152602401610914565b8460400151518114612589576040516357e0e08360e01b815260040160405180910390fd5b6000816001600160401b038111156125a3576125a3613c3c565b6040519080825280602002602001820160405280156125cc578160200160208202803683370190505b50905060007f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f857f000000000000000000000000000000000000000000000000000000000000000061261d88611cfe565b60010160405161262d9190615644565b604051908190038120612665949392916020019384526001600160401b03928316602085015291166040830152606082015260800190565b60405160208183030381529060405280519060200120905060005b8381101561279b576000886020015182815181106126a0576126a0614e64565b602002602001015190507f00000000000000000000000000000000000000000000000000000000000000006001600160401b03168160000151604001516001600160401b0316146127175780516040908101519051631c21951160e11b81526001600160401b039091166004820152602401610914565b866001600160401b03168160000151602001516001600160401b03161461276b57805160200151604051636c95f1eb60e01b81526001600160401b03808a1660048301529091166024820152604401610914565b612775818461349f565b84838151811061278757612787614e64565b602090810291909101015250600101612680565b505060006127b3858389606001518a608001516135a7565b9050806000036127e157604051633ee8bd3f60e11b81526001600160401b0386166004820152602401610914565b60005b83811015612cad5760005a905060008960200151838151811061280957612809614e64565b6020026020010151905060006128278983600001516060015161078d565b9050600081600381111561283d5761283d6140b8565b148061285a57506003816003811115612858576128586140b8565b145b6128b057815160600151604080516001600160401b03808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c910160405180910390a1505050612ca5565b6060881561298f578a85815181106128ca576128ca614e64565b6020908102919091018101510151600454909150600090600160a01b900463ffffffff166128f88842614eca565b119050808061291857506003836003811115612916576129166140b8565b145b612940576040516354e7e43160e11b81526001600160401b038c166004820152602401610914565b8b868151811061295257612952614e64565b602002602001015160000151600014612989578b868151811061297757612977614e64565b60209081029190910101515160808501525b506129fb565b60008260038111156129a3576129a36140b8565b146129fb57825160600151604080516001600160401b03808e16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe65120910160405180910390a150505050612ca5565b8251608001516001600160401b031615612ad1576000826003811115612a2357612a236140b8565b03612ad15782516080015160208401516040516370701e5760e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612a81928f929190600401615af8565b6020604051808303816000875af1158015612aa0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ac49190615627565b612ad15750505050612ca5565b60008c604001518681518110612ae957612ae9614e64565b6020026020010151905080518460a001515114612b3357835160600151604051631cfe6d8b60e01b81526001600160401b03808e1660048301529091166024820152604401610914565b612b478b85600001516060015160016135e4565b600080612b55868486613689565b91509150612b6c8d876000015160600151846135e4565b8b15612bc3576003826003811115612b8657612b866140b8565b03612bc3576000856003811115612b9f57612b9f6140b8565b14612bc357855151604051632b11b8d960e01b815261091491908390600401615b24565b6002826003811115612bd757612bd76140b8565b14612c18576003826003811115612bf057612bf06140b8565b14612c18578551606001516040516349362d1f60e11b8152610914918f918590600401615b3d565b8560000151600001518660000151606001516001600160401b03168e6001600160401b03167f05665fe9ad095383d018353f4cbcba77e84db27dd215081bbf7cdf9ae6fbe48b8d8c81518110612c7057612c70614e64565b602002602001015186865a612c85908f614eca565b604051612c959493929190615b62565b60405180910390a4505050505050505b6001016127e4565b5050505050505050565b6040805180820190915260008082526020820152602086015160405163bbe4f6db60e01b81526001600160a01b0380831660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa158015612d3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d5f9190615b99565b90506001600160a01b0381161580612d8e5750612d8c6001600160a01b03821663aff2afbf60e01b611bdd565b155b15612db75760405163ae9b4ce960e01b81526001600160a01b0382166004820152602401610914565b600080612dcf88858c6040015163ffffffff1661373d565b915091506000806000612e826040518061010001604052808e81526020018c6001600160401b031681526020018d6001600160a01b031681526020018f608001518152602001896001600160a01b031681526020018f6000015181526020018f6060015181526020018b815250604051602401612e4c9190615bb6565b60408051601f198184030181529190526020810180516001600160e01b0316633907753760e01b17905287866113886084613822565b92509250925082612eaa578582604051634ff17cad60e11b8152600401610914929190615c82565b8151602014612ed9578151604051631e3be00960e21b8152602060048201526024810191909152604401610914565b600082806020019051810190612eef9190615ca4565b9050866001600160a01b03168c6001600160a01b031614612f6b576000612f208d8a612f1b868a614eca565b61373d565b50905086811080612f3a575081612f378883614eca565b14155b15612f695760405163a966e21f60e01b8152600481018390526024810188905260448101829052606401610914565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000612fac826301ffc9a760e01b612fcc565b80156107dc5750612fc5826001600160e01b0319612fcc565b1592915050565b6040516001600160e01b031982166024820152600090819060440160408051601f19818403018152919052602080820180516001600160e01b03166301ffc9a760e01b178152825192935060009283928392909183918a617530fa92503d9150600051905082801561303f575060208210155b801561304b5750600081115b979650505050505050565b8251600090815b81811015612cad57600060018886846020811061307c5761307c614e64565b61308991901a601b6159d3565b89858151811061309b5761309b614e64565b60200260200101518986815181106130b5576130b5614e64565b6020026020010151604051600081526020016040526040516130f3949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015613115573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b03851683528152858220858701909652855480841686529397509095509293928401916101009004166002811115613176576131766140b8565b6002811115613187576131876140b8565b90525090506001816020015160028111156131a4576131a46140b8565b146131c257604051636518c33d60e11b815260040160405180910390fd5b8051600160ff9091161b8516156131ec57604051633d9ef1f160e21b815260040160405180910390fd5b806000015160ff166001901b85179450505080600101905061305d565b60005b8151811015610a715760ff83166000908152600360205260408120835190919084908490811061323e5761323e614e64565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff1916905560010161320c565b60005b82518110156115a857600083828151811061329257613292614e64565b60200260200101519050600060028111156132af576132af6140b8565b60ff80871660009081526003602090815260408083206001600160a01b038716845290915290205461010090041660028111156132ee576132ee6140b8565b1461330f576004604051631b3fab5160e11b81526004016109149190615a10565b6001600160a01b0381166133365760405163d6c62c9b60e01b815260040160405180910390fd5b60405180604001604052808360ff16815260200184600281111561335c5761335c6140b8565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff1916176101008360028111156133b9576133b96140b8565b021790555090505050806001019050613275565b60ff818116600081815260026020526040902060010154620100009004909116906134255780613410576040516317bd8dd160e11b815260040160405180910390fd5b600b805467ffffffffffffffff191690555050565b60001960ff8316016115ec5780156115ec576040516307b8c74d60e51b815260040160405180910390fd5b6000818152600183016020526040812054613497575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556107dc565b5060006107dc565b81518051606080850151908301516080808701519401516040516000958695889561350395919490939192916020019485526001600160a01b039390931660208501526001600160401b039182166040850152606084015216608082015260a00190565b604051602081830303815290604052805190602001208560200151805190602001208660400151805190602001208760a001516040516020016135469190615d5e565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e0015b60405160208183030381529060405280519060200120905092915050565b6000806135b58585856138fc565b6001600160401b0387166000908152600a6020908152604080832093835292905220549150505b949350505050565b600060026135f3608085614ef3565b6001600160401b03166136069190614f19565b9050600061361485856118bc565b90508161362360016004614eca565b901b19168183600381111561363a5761363a6140b8565b6001600160401b03871660009081526009602052604081209190921b92909217918291613668608088615939565b6001600160401b031681526020810191909152604001600020555050505050565b604051630304c3e160e51b815260009060609030906360987c20906136b690889088908890600401615df5565b600060405180830381600087803b1580156136d057600080fd5b505af19250505080156136e1575060015b613720573d80801561370f576040519150601f19603f3d011682016040523d82523d6000602084013e613714565b606091505b50600392509050613735565b50506040805160208101909152600081526002905b935093915050565b600080600080600061379e8860405160240161376891906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166370a0823160e01b17905288886113886084613822565b925092509250826137c6578682604051634ff17cad60e11b8152600401610914929190615c82565b60208251146137f5578151604051631e3be00960e21b8152602060048201526024810191909152604401610914565b818060200190518101906138099190615ca4565b6138138288614eca565b94509450505050935093915050565b6000606060008361ffff166001600160401b0381111561384457613844613c3c565b6040519080825280601f01601f19166020018201604052801561386e576020820181803683370190505b509150863b6138885763030ed58f60e21b60005260046000fd5b5a858110156138a257632be8ca8b60e21b60005260046000fd5b85900360408104810387106138c2576337c3be2960e01b60005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d848111156138e55750835b808352806000602085013e50955095509592505050565b825182516000919081830361392457604051630469ac9960e21b815260040160405180910390fd5b610101821180159061393857506101018111155b613955576040516309bde33960e01b815260040160405180910390fd5b6000198282010161010081111561397f576040516309bde33960e01b815260040160405180910390fd5b806000036139ac578660008151811061399a5761399a614e64565b60200260200101519350505050613b7a565b6000816001600160401b038111156139c6576139c6613c3c565b6040519080825280602002602001820160405280156139ef578160200160208202803683370190505b50905060008080805b85811015613b195760006001821b8b811603613a535788851015613a3c578c5160018601958e918110613a2d57613a2d614e64565b60200260200101519050613a75565b8551600185019487918110613a2d57613a2d614e64565b8b5160018401938d918110613a6a57613a6a614e64565b602002602001015190505b600089861015613aa5578d5160018701968f918110613a9657613a96614e64565b60200260200101519050613ac7565b8651600186019588918110613abc57613abc614e64565b602002602001015190505b82851115613ae8576040516309bde33960e01b815260040160405180910390fd5b613af28282613b81565b878481518110613b0457613b04614e64565b602090810291909101015250506001016139f8565b506001850382148015613b2b57508683145b8015613b3657508581145b613b53576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613b6857613b68614e64565b60200260200101519750505050505050505b9392505050565b6000818310613b9957613b948284613b9f565b6107d9565b6107d983835b604080516001602082015290810183905260608101829052600090608001613589565b828054828255906000526020600020908101928215613c17579160200282015b82811115613c1757825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613be2565b50613c23929150613c27565b5090565b5b80821115613c235760008155600101613c28565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715613c7457613c74613c3c565b60405290565b60405160a081016001600160401b0381118282101715613c7457613c74613c3c565b60405160c081016001600160401b0381118282101715613c7457613c74613c3c565b604080519081016001600160401b0381118282101715613c7457613c74613c3c565b604051606081016001600160401b0381118282101715613c7457613c74613c3c565b604051601f8201601f191681016001600160401b0381118282101715613d2a57613d2a613c3c565b604052919050565b60006001600160401b03821115613d4b57613d4b613c3c565b5060051b60200190565b6001600160a01b038116811461052f57600080fd5b80356001600160401b0381168114613d8157600080fd5b919050565b801515811461052f57600080fd5b8035613d8181613d86565b60006001600160401b03821115613db857613db8613c3c565b50601f01601f191660200190565b600082601f830112613dd757600080fd5b8135613dea613de582613d9f565b613d02565b818152846020838601011115613dff57600080fd5b816020850160208301376000918101602001919091529392505050565b60006020808385031215613e2f57600080fd5b82356001600160401b0380821115613e4657600080fd5b818501915085601f830112613e5a57600080fd5b8135613e68613de582613d32565b81815260059190911b83018401908481019088831115613e8757600080fd5b8585015b83811015613f2d57803585811115613ea35760008081fd5b86016080818c03601f1901811315613ebb5760008081fd5b613ec3613c52565b89830135613ed081613d55565b81526040613edf848201613d6a565b8b830152606080850135613ef281613d86565b83830152928401359289841115613f0b57600091508182fd5b613f198f8d86880101613dc6565b908301525085525050918601918601613e8b565b5098975050505050505050565b60005b83811015613f55578181015183820152602001613f3d565b50506000910152565b60008151808452613f76816020860160208601613f3a565b601f01601f19169290920160200192915050565b6020815260006107d96020830184613f5e565b6001600160a01b0381511682526020810151151560208301526001600160401b03604082015116604083015260006060820151608060608501526135dc6080850182613f5e565b604080825283519082018190526000906020906060840190828701845b828110156140265781516001600160401b031684529284019290840190600101614001565b50505083810382850152845180825282820190600581901b8301840187850160005b8381101561407657601f19868403018552614064838351613f9d565b94870194925090860190600101614048565b50909998505050505050505050565b6000806040838503121561409857600080fd5b6140a183613d6a565b91506140af60208401613d6a565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b600481106140de576140de6140b8565b9052565b602081016107dc82846140ce565b600060a0828403121561410257600080fd5b61410a613c7a565b90508135815261411c60208301613d6a565b602082015261412d60408301613d6a565b604082015261413e60608301613d6a565b606082015261414f60808301613d6a565b608082015292915050565b8035613d8181613d55565b803563ffffffff81168114613d8157600080fd5b600082601f83011261418a57600080fd5b8135602061419a613de583613d32565b82815260059290921b840181019181810190868411156141b957600080fd5b8286015b848110156142895780356001600160401b03808211156141dd5760008081fd5b9088019060a0828b03601f19018113156141f75760008081fd5b6141ff613c7a565b87840135838111156142115760008081fd5b61421f8d8a83880101613dc6565b82525060408085013561423181613d55565b828a01526060614242868201614165565b8284015260809150818601358581111561425c5760008081fd5b61426a8f8c838a0101613dc6565b91840191909152509190930135908301525083529183019183016141bd565b509695505050505050565b600061014082840312156142a757600080fd5b6142af613c9c565b90506142bb83836140f0565b815260a08201356001600160401b03808211156142d757600080fd5b6142e385838601613dc6565b602084015260c08401359150808211156142fc57600080fd5b61430885838601613dc6565b604084015261431960e0850161415a565b6060840152610100840135608084015261012084013591508082111561433e57600080fd5b5061434b84828501614179565b60a08301525092915050565b600082601f83011261436857600080fd5b81356020614378613de583613d32565b82815260059290921b8401810191818101908684111561439757600080fd5b8286015b848110156142895780356001600160401b038111156143ba5760008081fd5b6143c88986838b0101614294565b84525091830191830161439b565b600082601f8301126143e757600080fd5b813560206143f7613de583613d32565b82815260059290921b8401810191818101908684111561441657600080fd5b8286015b848110156142895780356001600160401b038082111561443957600080fd5b818901915089603f83011261444d57600080fd5b8582013561445d613de582613d32565b81815260059190911b830160400190878101908c83111561447d57600080fd5b604085015b838110156144b65780358581111561449957600080fd5b6144a88f6040838a0101613dc6565b845250918901918901614482565b5087525050509284019250830161441a565b600082601f8301126144d957600080fd5b813560206144e9613de583613d32565b8083825260208201915060208460051b87010193508684111561450b57600080fd5b602086015b848110156142895780358352918301918301614510565b600082601f83011261453857600080fd5b81356020614548613de583613d32565b82815260059290921b8401810191818101908684111561456757600080fd5b8286015b848110156142895780356001600160401b038082111561458b5760008081fd5b9088019060a0828b03601f19018113156145a55760008081fd5b6145ad613c7a565b6145b8888501613d6a565b8152604080850135848111156145ce5760008081fd5b6145dc8e8b83890101614357565b8a84015250606080860135858111156145f55760008081fd5b6146038f8c838a01016143d6565b838501525060809150818601358581111561461e5760008081fd5b61462c8f8c838a01016144c8565b918401919091525091909301359083015250835291830191830161456b565b6000806040838503121561465e57600080fd5b6001600160401b038335111561467357600080fd5b6146808484358501614527565b91506001600160401b036020840135111561469a57600080fd5b6020830135830184601f8201126146b057600080fd5b6146bd613de58235613d32565b81358082526020808301929160051b8401018710156146db57600080fd5b602083015b6020843560051b850101811015614881576001600160401b038135111561470657600080fd5b87603f82358601011261471857600080fd5b61472b613de56020833587010135613d32565b81358501602081810135808452908301929160059190911b016040018a101561475357600080fd5b604083358701015b83358701602081013560051b01604001811015614871576001600160401b038135111561478757600080fd5b833587018135016040818d03603f190112156147a257600080fd5b6147aa613cbe565b604082013581526001600160401b03606083013511156147c957600080fd5b8c605f6060840135840101126147de57600080fd5b60406060830135830101356147f5613de582613d32565b808282526020820191508f60608460051b606088013588010101111561481a57600080fd5b6060808601358601015b60608460051b6060880135880101018110156148515761484381614165565b835260209283019201614824565b50806020850152505050808552505060208301925060208101905061475b565b50845250602092830192016146e0565b508093505050509250929050565b60008083601f8401126148a157600080fd5b5081356001600160401b038111156148b857600080fd5b6020830191508360208260051b85010111156148d357600080fd5b9250929050565b6000806000806000606086880312156148f257600080fd5b85356001600160401b038082111561490957600080fd5b61491589838a01614294565b9650602088013591508082111561492b57600080fd5b61493789838a0161488f565b9096509450604088013591508082111561495057600080fd5b5061495d8882890161488f565b969995985093965092949392505050565b60006080828403121561498057600080fd5b614988613c52565b823561499381613d55565b81526149a160208401614165565b602082015260408301356149b481613d86565b604082015260608301356149c781613d55565b60608201529392505050565b6000602082840312156149e557600080fd5b81356001600160401b038111156149fb57600080fd5b820160a08185031215613b7a57600080fd5b803560ff81168114613d8157600080fd5b600060208284031215614a3057600080fd5b6107d982614a0d565b60008151808452602080850194506020840160005b83811015614a735781516001600160a01b031687529582019590820190600101614a4e565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614acd60e0840182614a39565b90506040840151601f198483030160c0850152614aea8282614a39565b95945050505050565b60008060408385031215614b0657600080fd5b614b0f83613d6a565b946020939093013593505050565b80604081018310156107dc57600080fd5b60008083601f840112614b4057600080fd5b5081356001600160401b03811115614b5757600080fd5b6020830191508360208285010111156148d357600080fd5b60008060008060008060008060c0898b031215614b8b57600080fd5b614b958a8a614b1d565b975060408901356001600160401b0380821115614bb157600080fd5b614bbd8c838d01614b2e565b909950975060608b0135915080821115614bd657600080fd5b614be28c838d0161488f565b909750955060808b0135915080821115614bfb57600080fd5b50614c088b828c0161488f565b999c989b50969995989497949560a00135949350505050565b600060208284031215614c3357600080fd5b6107d982613d6a565b6020815260006107d96020830184613f9d565b600060208284031215614c6157600080fd5b8135613b7a81613d55565b600080600060608486031215614c8157600080fd5b614c8b8585614b1d565b925060408401356001600160401b03811115614ca657600080fd5b614cb286828701614b2e565b9497909650939450505050565b600082601f830112614cd057600080fd5b81356020614ce0613de583613d32565b8083825260208201915060208460051b870101935086841115614d0257600080fd5b602086015b84811015614289578035614d1a81613d55565b8352918301918301614d07565b60006020808385031215614d3a57600080fd5b82356001600160401b0380821115614d5157600080fd5b818501915085601f830112614d6557600080fd5b8135614d73613de582613d32565b81815260059190911b83018401908481019088831115614d9257600080fd5b8585015b83811015613f2d57803585811115614dad57600080fd5b860160c0818c03601f19011215614dc45760008081fd5b614dcc613c9c565b8882013581526040614ddf818401614a0d565b8a8301526060614df0818501614a0d565b8284015260809150614e03828501613d94565b9083015260a08381013589811115614e1b5760008081fd5b614e298f8d83880101614cbf565b838501525060c0840135915088821115614e435760008081fd5b614e518e8c84870101614cbf565b9083015250845250918601918601614d96565b634e487b7160e01b600052603260045260246000fd5b600181811c90821680614e8e57607f821691505b602082108103614eae57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b818103818111156107dc576107dc614eb4565b634e487b7160e01b600052601260045260246000fd5b60006001600160401b0380841680614f0d57614f0d614edd565b92169190910692915050565b80820281158282048414176107dc576107dc614eb4565b80518252600060206001600160401b0381840151168185015260408084015160a06040870152614f6360a0870182613f5e565b905060608501518682036060880152614f7c8282613f5e565b608087810151898303918a01919091528051808352908601935060009250908501905b80831015614fd157835180516001600160a01b0316835286015186830152928501926001929092019190840190614f9f565b50979650505050505050565b6020815260006107d96020830184614f30565b6080815260006150036080830187614f30565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b60008060006060848603121561504157600080fd5b835161504c81613d86565b60208501519093506001600160401b0381111561506857600080fd5b8401601f8101861361507957600080fd5b8051615087613de582613d9f565b81815287602083850101111561509c57600080fd5b6150ad826020830160208601613f3a565b809450505050604084015190509250925092565b80356001600160e01b0381168114613d8157600080fd5b600082601f8301126150e957600080fd5b813560206150f9613de583613d32565b82815260069290921b8401810191818101908684111561511857600080fd5b8286015b8481101561428957604081890312156151355760008081fd5b61513d613cbe565b61514682613d6a565b81526151538583016150c1565b8186015283529183019160400161511c565b600082601f83011261517657600080fd5b81356020615186613de583613d32565b82815260059290921b840181019181810190868411156151a557600080fd5b8286015b848110156142895780356001600160401b03808211156151c95760008081fd5b9088019060a0828b03601f19018113156151e35760008081fd5b6151eb613c7a565b6151f6888501613d6a565b81526040808501358481111561520c5760008081fd5b61521a8e8b83890101613dc6565b8a840152506060935061522e848601613d6a565b90820152608061523f858201613d6a565b938201939093529201359082015283529183019183016151a9565b600082601f83011261526b57600080fd5b8135602061527b613de583613d32565b82815260069290921b8401810191818101908684111561529a57600080fd5b8286015b8481101561428957604081890312156152b75760008081fd5b6152bf613cbe565b81358152848201358582015283529183019160400161529e565b600060208083850312156152ec57600080fd5b82356001600160401b038082111561530357600080fd5b908401906060828703121561531757600080fd5b61531f613ce0565b82358281111561532e57600080fd5b8301604081890381131561534157600080fd5b615349613cbe565b82358581111561535857600080fd5b8301601f81018b1361536957600080fd5b8035615377613de582613d32565b81815260069190911b8201890190898101908d83111561539657600080fd5b928a01925b828410156153e65785848f0312156153b35760008081fd5b6153bb613cbe565b84356153c681613d55565b81526153d3858d016150c1565b818d0152825292850192908a019061539b565b8452505050828701359150848211156153fe57600080fd5b61540a8a8385016150d8565b8188015283525050828401358281111561542357600080fd5b61542f88828601615165565b8583015250604083013593508184111561544857600080fd5b6154548785850161525a565b60408201529695505050505050565b600082825180855260208086019550808260051b84010181860160005b848110156154f457601f19868403018952815160a06001600160401b038083511686528683015182888801526154b883880182613f5e565b60408581015184169089015260608086015190931692880192909252506080928301519290950191909152509783019790830190600101615480565b5090979650505050505050565b6001600160a01b0384168152600060206060818401526155246060840186615463565b83810360408581019190915285518083528387019284019060005b818110156140765784518051845286015186840152938501939183019160010161553f565b805160408084528151848201819052600092602091908201906060870190855b818110156155bb57835180516001600160a01b031684528501516001600160e01b0316858401529284019291850191600101615584565b50508583015187820388850152805180835290840192506000918401905b80831015614fd157835180516001600160401b031683528501516001600160e01b0316858301529284019260019290920191908501906155d9565b6020815260006107d96020830184615564565b60006020828403121561563957600080fd5b8151613b7a81613d86565b600080835461565281614e7a565b6001828116801561566a576001811461567f576156ae565b60ff19841687528215158302870194506156ae565b8760005260208060002060005b858110156156a55781548a82015290840190820161568c565b50505082870194505b50929695505050505050565b600081546156c781614e7a565b8085526020600183811680156156e457600181146156fe5761572c565b60ff1985168884015283151560051b88018301955061572c565b866000528260002060005b858110156157245781548a8201860152908301908401615709565b890184019650505b505050505092915050565b60408152600061574a6040830185613f5e565b8281036020840152614aea81856156ba565b6001600160401b0381811683821601908082111561577c5761577c614eb4565b5092915050565b6040815260006157966040830185615463565b8281036020840152614aea8185615564565b6000602082840312156157ba57600080fd5b81356001600160401b038111156157d057600080fd5b6135dc84828501614527565b601f821115610a71576000816000526020600020601f850160051c810160208610156158055750805b601f850160051c820191505b8181101561582457828155600101615811565b505050505050565b81516001600160401b0381111561584557615845613c3c565b615859816158538454614e7a565b846157dc565b602080601f83116001811461588e57600084156158765750858301515b600019600386901b1c1916600185901b178555615824565b600085815260208120601f198616915b828110156158bd5788860151825594840194600190910190840161589e565b50858210156158db5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60208152600082546001600160a01b038116602084015260ff8160a01c16151560408401526001600160401b038160a81c166060840152506080808301526107d960a08301600185016156ba565b60006001600160401b038084168061595357615953614edd565b92169190910492915050565b60006020828403121561597157600080fd5b6107d982614165565b6000808335601e1984360301811261599157600080fd5b8301803591506001600160401b038211156159ab57600080fd5b6020019150368190038213156148d357600080fd5b808201808211156107dc576107dc614eb4565b60ff81811683821601908111156107dc576107dc614eb4565b8183823760009101908152919050565b828152604082602083013760600192915050565b6020810160068310615a2457615a246140b8565b91905290565b60ff818116838216029081169081811461577c5761577c614eb4565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615a9e5784546001600160a01b031683526001948501949284019201615a79565b50508481036060860152865180825290820192508187019060005b81811015615ade5782516001600160a01b031685529383019391830191600101615ab9565b50505060ff851660808501525090505b9695505050505050565b60006001600160401b03808616835280851660208401525060606040830152614aea6060830184613f5e565b8281526040602082015260006135dc6040830184613f5e565b6001600160401b03848116825283166020820152606081016135dc60408301846140ce565b848152615b7260208201856140ce565b608060408201526000615b886080830185613f5e565b905082606083015295945050505050565b600060208284031215615bab57600080fd5b8151613b7a81613d55565b6020815260008251610100806020850152615bd5610120850183613f5e565b91506020850151615bf160408601826001600160401b03169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615c2b60a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615c488483613f5e565b935060c08701519150808685030160e0870152615c658483613f5e565b935060e0870151915080868503018387015250615aee8382613f5e565b6001600160a01b03831681526040602082015260006135dc6040830184613f5e565b600060208284031215615cb657600080fd5b5051919050565b600082825180855260208086019550808260051b84010181860160005b848110156154f457601f19868403018952815160a08151818652615d0082870182613f5e565b9150506001600160a01b03868301511686860152604063ffffffff8184015116818701525060608083015186830382880152615d3c8382613f5e565b6080948501519790940196909652505098840198925090830190600101615cda565b6020815260006107d96020830184615cbd565b60008282518085526020808601955060208260051b8401016020860160005b848110156154f457601f19868403018952615dac838351613f5e565b98840198925090830190600101615d90565b60008151808452602080850194506020840160005b83811015614a7357815163ffffffff1687529582019590820190600101615dd3565b60608152600084518051606084015260208101516001600160401b0380821660808601528060408401511660a08601528060608401511660c08601528060808401511660e0860152505050602085015161014080610100850152615e5d6101a0850183613f5e565b91506040870151605f198086850301610120870152615e7c8483613f5e565b935060608901519150615e99838701836001600160a01b03169052565b608089015161016087015260a0890151925080868503016101808701525050615ec28282615cbd565b9150508281036020840152615ed78186615d71565b90508281036040840152615aee8185615dbe56fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"contractIRMNRemote\",\"name\":\"rmnRemote\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isRMNVerificationDisabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"messageInterceptor\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigs\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reportOnRamp\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"configOnRamp\",\"type\":\"bytes\"}],\"name\":\"CommitOnRampMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyBatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumMultiOCR3Base.InvalidConfigErrorType\",\"name\":\"errorType\",\"type\":\"uint8\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"got\",\"type\":\"uint256\"}],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"tokenIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"oldLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenGasOverride\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionTokenGasOverride\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"messageDestChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidMessageDestChainSelector\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidOnRampUpdate\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionGasAmountCountMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"errorReason\",\"type\":\"bytes\"}],\"name\":\"MessageValidationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"notPool\",\"type\":\"address\"}],\"name\":\"NotACompatiblePool\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountReleased\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePre\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balancePost\",\"type\":\"uint256\"}],\"name\":\"ReleaseOrMintBalanceMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignatureVerificationNotAllowedInExecutionPlugin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignatureVerificationRequiredInCommitPlugin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainNotEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"reportSourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"messageSourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"StaticConfigCannotBeChanged\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroChainSelectorNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRampAddress\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"maxSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structInternal.MerkleRoot[]\",\"name\":\"merkleRoots\",\"type\":\"tuple[]\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"CommitReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isRMNVerificationDisabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"messageInterceptor\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"DynamicConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"name\":\"ExecutionStateChanged\",\"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\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"SkippedAlreadyExecutedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SkippedReportExecution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"sourceConfig\",\"type\":\"tuple\"}],\"name\":\"SourceChainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"SourceChainSelectorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"contractIRMNRemote\",\"name\":\"rmnRemote\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"name\":\"StaticConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfigArgs[]\",\"name\":\"sourceChainConfigUpdates\",\"type\":\"tuple[]\"}],\"name\":\"applySourceChainConfigUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[2]\",\"name\":\"reportContext\",\"type\":\"bytes32[2]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[2]\",\"name\":\"reportContext\",\"type\":\"bytes32[2]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"destTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destGasAmount\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.Any2EVMTokenTransfer[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"uint32[]\",\"name\":\"tokenGasOverrides\",\"type\":\"uint32[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllSourceChainConfigs\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isRMNVerificationDisabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"messageInterceptor\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"getSourceChainConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIRouter\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"onRamp\",\"type\":\"bytes\"}],\"internalType\":\"structOffRamp.SourceChainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"contractIRMNRemote\",\"name\":\"rmnRemote\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAdminRegistry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nonceManager\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"n\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"}],\"internalType\":\"structMultiOCR3Base.ConfigInfo\",\"name\":\"configInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfig\",\"name\":\"ocrConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"internalType\":\"structInternal.RampMessageHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"destTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"destGasAmount\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.Any2EVMTokenTransfer[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.Any2EVMRampMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport[]\",\"name\":\"reports\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receiverExecutionGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint32[]\",\"name\":\"tokenGasOverrides\",\"type\":\"uint32[]\"}],\"internalType\":\"structOffRamp.GasLimitOverride[][]\",\"name\":\"gasLimitOverrides\",\"type\":\"tuple[][]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeQuoter\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isRMNVerificationDisabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"messageInterceptor\",\"type\":\"address\"}],\"internalType\":\"structOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"ocrPluginType\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"F\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"isSignatureVerificationEnabled\",\"type\":\"bool\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"}],\"internalType\":\"structMultiOCR3Base.OCRConfigArgs[]\",\"name\":\"ocrConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setOCR3Configs\",\"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: "0x6101406040523480156200001257600080fd5b5060405162006d0638038062006d06833981016040819052620000359162000936565b336000816200005757604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008a576200008a81620001dc565b50504660805260408301516001600160a01b03161580620000b6575060608301516001600160a01b0316155b80620000cd575060808301516001600160a01b0316155b15620000ec576040516342bcdf7f60e11b815260040160405180910390fd5b82516001600160401b0316600003620001185760405163c656089560e01b815260040160405180910390fd5b82516001600160401b0390811660a0908152604080860180516001600160a01b0390811660c05260608089018051831660e0526080808b0180518516610100526020808d01805161ffff9081166101205289518f51909c168c52905116908a0152945184169588019590955251821690860152905116908301527fb0fa1fb01508c5097c502ad056fd77018870c9be9a86d9e56b6b471862d7c5b7910160405180910390a1620001c88262000256565b620001d38162000344565b50505062000cde565b336001600160a01b038216036200020657604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03166200027f576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516001600160a01b039889166001600160c01b03199097168717600160a01b63ffffffff958616021760ff60c01b1916600160c01b911515919091021790965560608089018051600580546001600160a01b031916918b169190911790558251968752935190921693850193909352935115159183019190915251909216908201527fcbb53bda7106a610de67df506ac86b65c44d5afac0fd2b11070dc2d61a6f2dee9060800160405180910390a150565b60005b8151811015620005d957600082828151811062000368576200036862000a16565b60200260200101519050600081602001519050806001600160401b0316600003620003a65760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b0316620003cf576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b03811660009081526008602052604090206060830151600182018054620003fd9062000a2c565b905060000362000460578154600160a81b600160e81b031916600160a81b1782556040516001600160401b03841681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a1620004d1565b8154600160a81b90046001600160401b0316600114801590620004a35750805160208201206040516200049890600185019062000a68565b604051809103902014155b15620004d157604051632105803760e11b81526001600160401b038416600482015260240160405180910390fd5b80511580620005075750604080516000602082015201604051602081830303815290604052805190602001208180519060200120145b1562000526576040516342bcdf7f60e11b815260040160405180910390fd5b6001820162000536828262000b3b565b506040840151825485516001600160a01b03166001600160a01b0319921515600160a01b02929092166001600160a81b0319909116171782556200058560066001600160401b038516620005dd565b50826001600160401b03167f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b83604051620005c1919062000c07565b60405180910390a25050505080600101905062000347565b5050565b6000620005eb8383620005f4565b90505b92915050565b60008181526001830160205260408120546200063d57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620005ee565b506000620005ee565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b038111828210171562000681576200068162000646565b60405290565b60405160a081016001600160401b038111828210171562000681576200068162000646565b604051601f8201601f191681016001600160401b0381118282101715620006d757620006d762000646565b604052919050565b80516001600160401b0381168114620006f757600080fd5b919050565b6001600160a01b03811681146200071257600080fd5b50565b80518015158114620006f757600080fd5b6000608082840312156200073957600080fd5b620007436200065c565b905081516200075281620006fc565b8152602082015163ffffffff811681146200076c57600080fd5b60208201526200077f6040830162000715565b604082015260608201516200079481620006fc565b606082015292915050565b6000601f83601f840112620007b357600080fd5b825160206001600160401b0380831115620007d257620007d262000646565b8260051b620007e3838201620006ac565b9384528681018301938381019089861115620007fe57600080fd5b84890192505b8583101562000929578251848111156200081e5760008081fd5b89016080601f19828d038101821315620008385760008081fd5b620008426200065c565b888401516200085181620006fc565b8152604062000862858201620006df565b8a83015260606200087581870162000715565b838301529385015193898511156200088d5760008081fd5b84860195508f603f870112620008a557600094508485fd5b8a860151945089851115620008be57620008be62000646565b620008cf8b858f88011601620006ac565b93508484528f82868801011115620008e75760008081fd5b60005b8581101562000907578681018301518582018d01528b01620008ea565b5060009484018b01949094525091820152835250918401919084019062000804565b9998505050505050505050565b60008060008385036101408112156200094e57600080fd5b60a08112156200095d57600080fd5b506200096862000687565b6200097385620006df565b8152602085015161ffff811681146200098b57600080fd5b60208201526040850151620009a081620006fc565b60408201526060850151620009b581620006fc565b60608201526080850151620009ca81620006fc565b60808201529250620009e08560a0860162000726565b6101208501519092506001600160401b03811115620009fe57600080fd5b62000a0c868287016200079f565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000a4157607f821691505b60208210810362000a6257634e487b7160e01b600052602260045260246000fd5b50919050565b600080835462000a788162000a2c565b6001828116801562000a93576001811462000aa95762000ada565b60ff198416875282151583028701945062000ada565b8760005260208060002060005b8581101562000ad15781548a82015290840190820162000ab6565b50505082870194505b50929695505050505050565b601f82111562000b36576000816000526020600020601f850160051c8101602086101562000b115750805b601f850160051c820191505b8181101562000b325782815560010162000b1d565b5050505b505050565b81516001600160401b0381111562000b575762000b5762000646565b62000b6f8162000b68845462000a2c565b8462000ae6565b602080601f83116001811462000ba7576000841562000b8e5750858301515b600019600386901b1c1916600185901b17855562000b32565b600085815260208120601f198616915b8281101562000bd85788860151825594840194600190910190840162000bb7565b508582101562000bf75787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602080825282546001600160a01b0381168383015260a081901c60ff161515604084015260a81c6001600160401b0316606083015260808083015260018084018054600093929190849062000c5c8162000a2c565b8060a089015260c0600183166000811462000c80576001811462000c9d5762000ccf565b60ff19841660c08b015260c083151560051b8b0101945062000ccf565b85600052602060002060005b8481101562000cc65781548c820185015290880190890162000ca9565b8b0160c0019550505b50929998505050505050505050565b60805160a05160c05160e0516101005161012051615f8b62000d7b600039600081816101b001528181610ce801528181612ed1015261380b0152600081816102380152612aa10152600081816102090152612d490152600081816101da01528181610fcc0152818161117c01526124a10152600081816101810152818161264c015261270301526000818161195b015261198e0152615f8b6000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c80637edf52f4116100ad578063de5e0b9a11610071578063de5e0b9a146104eb578063e9d68a8e146104fe578063f2fde38b1461051e578063f58e03fc14610531578063f716f99f1461054457600080fd5b80637edf52f41461044b57806385572ffb1461045e5780638da5cb5b1461046c578063c673e58414610487578063ccd37ba3146104a757600080fd5b80635e36480c116100f45780635e36480c146103405780635e7bb0081461036057806360987c20146103735780637437ff9f1461038657806379ba50971461044357600080fd5b806304666f9c1461013157806306285c6914610146578063181f5a77146102c65780633f4b04aa1461030f5780635215505b1461032a575b600080fd5b61014461013f366004613eaf565b610557565b005b6102686040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040518060a001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160401b031681526020017f000000000000000000000000000000000000000000000000000000000000000061ffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b6040805182516001600160401b0316815260208084015161ffff1690820152828201516001600160a01b03908116928201929092526060808401518316908201526080928301519091169181019190915260a0015b60405180910390f35b6103026040518060400160405280601181526020017f4f666652616d7020312e362e302d64657600000000000000000000000000000081525081565b6040516102bd919061401d565b600b546040516001600160401b0390911681526020016102bd565b61033261056b565b6040516102bd929190614077565b61035361034e366004614118565b6107c6565b6040516102bd9190614175565b61014461036e3660046146de565b61081b565b61014461038136600461496d565b610aaf565b6103fc60408051608081018252600080825260208201819052918101829052606081019190915250604080516080810182526004546001600160a01b038082168352600160a01b820463ffffffff166020840152600160c01b90910460ff16151592820192909252600554909116606082015290565b6040516102bd919081516001600160a01b03908116825260208084015163ffffffff1690830152604080840151151590830152606092830151169181019190915260800190565b610144610d8a565b610144610459366004614a01565b610e0d565b61014461012c366004614a66565b6001546040516001600160a01b0390911681526020016102bd565b61049a610495366004614ab1565b610e1e565b6040516102bd9190614b11565b6104dd6104b5366004614b86565b6001600160401b03919091166000908152600a60209081526040808320938352929052205490565b6040519081526020016102bd565b6101446104f9366004614c02565b610f7c565b61051161050c366004614cb4565b61147f565b6040516102bd9190614ccf565b61014461052c366004614ce2565b61158b565b61014461053f366004614cff565b61159c565b610144610552366004614dba565b611605565b61055f611647565b61056881611674565b50565b606080600061057a60066118fd565b6001600160401b0381111561059157610591613ccf565b6040519080825280602002602001820160405280156105e257816020015b60408051608081018252600080825260208083018290529282015260608082015282526000199092019101816105af5790505b50905060006105f160066118fd565b6001600160401b0381111561060857610608613ccf565b604051908082528060200260200182016040528015610631578160200160208202803683370190505b50905060005b61064160066118fd565b8110156107bd57610653600682611907565b82828151811061066557610665614ef7565b60200260200101906001600160401b031690816001600160401b0316815250506008600083838151811061069b5761069b614ef7565b6020908102919091018101516001600160401b039081168352828201939093526040918201600020825160808101845281546001600160a01b038116825260ff600160a01b820416151593820193909352600160a81b9092049093169181019190915260018201805491929160608401919061071690614f0d565b80601f016020809104026020016040519081016040528092919081815260200182805461074290614f0d565b801561078f5780601f106107645761010080835404028352916020019161078f565b820191906000526020600020905b81548152906001019060200180831161077257829003601f168201915b5050505050815250508382815181106107aa576107aa614ef7565b6020908102919091010152600101610637565b50939092509050565b60006107d460016004614f5d565b60026107e1608085614f86565b6001600160401b03166107f49190614fac565b6107fe8585611913565b901c1660038111156108125761081261414b565b90505b92915050565b610823611958565b815181518114610846576040516320f8fd5960e21b815260040160405180910390fd5b60005b81811015610a9f57600084828151811061086557610865614ef7565b6020026020010151905060008160200151519050600085848151811061088d5761088d614ef7565b60200260200101519050805182146108b8576040516320f8fd5960e21b815260040160405180910390fd5b60005b82811015610a905760008282815181106108d7576108d7614ef7565b60200260200101516000015190506000856020015183815181106108fd576108fd614ef7565b6020026020010151905081600014610956578060800151821015610956578551815151604051633a98d46360e11b81526001600160401b0390921660048301526024820152604481018390526064015b60405180910390fd5b83838151811061096857610968614ef7565b602002602001015160200151518160a0015151146109b557805180516060909101516040516370a193fd60e01b815260048101929092526001600160401b0316602482015260440161094d565b60005b8160a0015151811015610a825760008585815181106109d9576109d9614ef7565b60200260200101516020015182815181106109f6576109f6614ef7565b602002602001015163ffffffff16905080600014610a795760008360a001518381518110610a2657610a26614ef7565b60200260200101516040015163ffffffff16905080821015610a77578351516040516348e617b360e01b8152600481019190915260248101849052604481018290526064810183905260840161094d565b505b506001016109b8565b5050508060010190506108bb565b50505050806001019050610849565b50610aaa83836119c0565b505050565b333014610acf576040516306e34e6560e31b815260040160405180910390fd5b6040805160008082526020820190925281610b0c565b6040805180820190915260008082526020820152815260200190600190039081610ae55790505b5060a08701515190915015610b4257610b3f8660a001518760200151886060015189600001516020015189898989611a83565b90505b6040805160a081018252875151815287516020908101516001600160401b03168183015288015181830152908701516060820152608081018290526005546001600160a01b03168015610c35576040516308d450a160e01b81526001600160a01b038216906308d450a190610bbb908590600401615070565b600060405180830381600087803b158015610bd557600080fd5b505af1925050508015610be6575060015b610c35573d808015610c14576040519150601f19603f3d011682016040523d82523d6000602084013e610c19565b606091505b50806040516309c2532560e01b815260040161094d919061401d565b604088015151158015610c4a57506080880151155b80610c61575060608801516001600160a01b03163b155b80610c8857506060880151610c86906001600160a01b03166385572ffb60e01b611c34565b155b15610c9557505050610d83565b87516020908101516001600160401b03166000908152600890915260408082205460808b015160608c01519251633cf9798360e01b815284936001600160a01b0390931692633cf9798392610d119289927f00000000000000000000000000000000000000000000000000000000000000009291600401615083565b6000604051808303816000875af1158015610d30573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d5891908101906150bf565b509150915081610d7d57806040516302a35ba360e21b815260040161094d919061401d565b50505050505b5050505050565b6000546001600160a01b03163314610db55760405163015aa1e360e11b815260040160405180910390fd5b600180546001600160a01b0319808216339081179093556000805490911681556040516001600160a01b03909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e15611647565b61056881611c50565b610e616040805160e081019091526000606082018181526080830182905260a0830182905260c08301919091528190815260200160608152602001606081525090565b60ff808316600090815260026020818152604092839020835160e081018552815460608201908152600183015480881660808401526101008104881660a0840152620100009004909616151560c082015294855291820180548451818402810184019095528085529293858301939092830182828015610f0a57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610eec575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610f6c57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610f4e575b5050505050815250509050919050565b6000610f8a8789018961536c565b6004805491925090600160c01b900460ff1661103457602082015151156110345760208201516040808401519051633854844f60e11b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016926370a9089e926110039230929190600401615594565b60006040518083038186803b15801561101b57600080fd5b505afa15801561102f573d6000803e3d6000fd5b505050505b8151515115158061104a57508151602001515115155b1561111557600b5460208b0135906001600160401b03808316911610156110ed57600b805467ffffffffffffffff19166001600160401b03831617905581548351604051633937306f60e01b81526001600160a01b0390921691633937306f916110b6916004016156a7565b600060405180830381600087803b1580156110d057600080fd5b505af11580156110e4573d6000803e3d6000fd5b50505050611113565b82602001515160000361111357604051632261116760e01b815260040160405180910390fd5b505b60005b8260200151518110156113cb5760008360200151828151811061113d5761113d614ef7565b60209081029190910101518051604051632cbc26bb60e01b815267ffffffffffffffff60801b608083901b166004820152919250906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632cbc26bb90602401602060405180830381865afa1580156111c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e791906156ba565b1561121057604051637edeb53960e11b81526001600160401b038216600482015260240161094d565b600061121b82611d55565b90508060010160405161122e91906156d7565b60405180910390208360200151805190602001201461126b5782602001518160010160405163b80d8fa960e01b815260040161094d9291906157ca565b60408301518154600160a81b90046001600160401b0390811691161415806112ac575082606001516001600160401b031683604001516001600160401b0316115b156112f157825160408085015160608601519151636af0786b60e11b81526001600160401b03938416600482015290831660248201529116604482015260640161094d565b6080830151806113145760405163504570e360e01b815260040160405180910390fd5b83516001600160401b03166000908152600a602090815260408083208484529091529020541561136c5783516040516332cf0cbf60e01b81526001600160401b0390911660048201526024810182905260440161094d565b606084015161137c9060016157ef565b825467ffffffffffffffff60a81b1916600160a81b6001600160401b0392831602179092559251166000908152600a602090815260408083209483529390529190912042905550600101611118565b50602082015182516040517f35c02761bcd3ef995c6a601a1981f4ed3934dcbe5041e24e286c89f5531d17e492611403929091615816565b60405180910390a1610d7d60008b8b8b8b8b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808f0282810182019093528e82529093508e92508d9182918501908490808284376000920191909152508c9250611da1915050565b60408051608080820183526000808352602080840182905283850182905260608085018190526001600160401b03878116845260088352928690208651948501875280546001600160a01b0381168652600160a01b810460ff16151593860193909352600160a81b90920490921694830194909452600184018054939492939184019161150b90614f0d565b80601f016020809104026020016040519081016040528092919081815260200182805461153790614f0d565b8015610f6c5780601f1061155957610100808354040283529160200191610f6c565b820191906000526020600020905b81548152906001019060200180831161156757505050919092525091949350505050565b611593611647565b6105688161209a565b6115dc6115ab8284018461583b565b60408051600080825260208201909252906115d6565b60608152602001906001900390816115c15790505b506119c0565b6040805160008082526020820190925290506115ff600185858585866000611da1565b50505050565b61160d611647565b60005b81518110156116435761163b82828151811061162e5761162e614ef7565b6020026020010151612113565b600101611610565b5050565b6001546001600160a01b03163314611672576040516315ae3a6f60e11b815260040160405180910390fd5b565b60005b815181101561164357600082828151811061169457611694614ef7565b60200260200101519050600081602001519050806001600160401b03166000036116d15760405163c656089560e01b815260040160405180910390fd5b81516001600160a01b03166116f9576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160401b0381166000908152600860205260409020606083015160018201805461172590614f0d565b905060000361178757815467ffffffffffffffff60a81b1916600160a81b1782556040516001600160401b03841681527ff4c1390c70e5c0f491ae1ccbc06f9117cbbadf2767b247b3bc203280f24c0fb99060200160405180910390a16117f0565b8154600160a81b90046001600160401b03166001148015906117c75750805160208201206040516117bc9060018501906156d7565b604051809103902014155b156117f057604051632105803760e11b81526001600160401b038416600482015260240161094d565b805115806118255750604080516000602082015201604051602081830303815290604052805190602001208180519060200120145b15611843576040516342bcdf7f60e11b815260040160405180910390fd5b6001820161185182826158bf565b506040840151825485516001600160a01b03166001600160a01b0319921515600160a01b029290921674ffffffffffffffffffffffffffffffffffffffffff19909116171782556118ac60066001600160401b03851661243d565b50826001600160401b03167f49f51971edd25182e97182d6ea372a0488ce2ab639f6a3a7ab4df0d2636fe56b836040516118e6919061597e565b60405180910390a250505050806001019050611677565b6000610815825490565b60006108128383612449565b6001600160401b0382166000908152600960205260408120816119376080856159cc565b6001600160401b031681526020810191909152604001600020549392505050565b467f00000000000000000000000000000000000000000000000000000000000000001461167257604051630f01ce8560e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015246602482015260440161094d565b81516000036119e25760405163c2e5347d60e01b815260040160405180910390fd5b80516040805160008082526020820190925291159181611a25565b6040805180820190915260008152606060208201528152602001906001900390816119fd5790505b50905060005b8451811015610d8357611a7b858281518110611a4957611a49614ef7565b602002602001015184611a7557858381518110611a6857611a68614ef7565b6020026020010151612473565b83612473565b600101611a2b565b606088516001600160401b03811115611a9e57611a9e613ccf565b604051908082528060200260200182016040528015611ae357816020015b6040805180820190915260008082526020820152815260200190600190039081611abc5790505b509050811560005b8a51811015611c265781611b8357848482818110611b0b57611b0b614ef7565b9050602002016020810190611b2091906159f2565b63ffffffff1615611b8357848482818110611b3d57611b3d614ef7565b9050602002016020810190611b5291906159f2565b8b8281518110611b6457611b64614ef7565b60200260200101516040019063ffffffff16908163ffffffff16815250505b611c018b8281518110611b9857611b98614ef7565b60200260200101518b8b8b8b8b87818110611bb557611bb5614ef7565b9050602002810190611bc79190615a0d565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612d0e92505050565b838281518110611c1357611c13614ef7565b6020908102919091010152600101611aeb565b505098975050505050505050565b6000611c3f8361300e565b801561081257506108128383613041565b80516001600160a01b0316611c78576040516342bcdf7f60e11b815260040160405180910390fd5b80516004805460208085018051604080880180516001600160a01b039889167fffffffffffffffff0000000000000000000000000000000000000000000000009097168717600160a01b63ffffffff958616021760ff60c01b1916600160c01b911515919091021790965560608089018051600580546001600160a01b031916918b169190911790558251968752935190921693850193909352935115159183019190915251909216908201527fcbb53bda7106a610de67df506ac86b65c44d5afac0fd2b11070dc2d61a6f2dee9060800160405180910390a150565b6001600160401b03811660009081526008602052604081208054600160a01b900460ff166108155760405163ed053c5960e01b81526001600160401b038416600482015260240161094d565b60ff87811660009081526002602090815260408083208151608081018352815481526001909101548086169382019390935261010083048516918101919091526201000090910490921615156060830152873590611e00876084615a53565b9050826060015115611e48578451611e19906020614fac565b8651611e26906020614fac565b611e319060a0615a53565b611e3b9190615a53565b611e459082615a53565b90505b368114611e7157604051638e1192e160e01b81526004810182905236602482015260440161094d565b5081518114611ea05781516040516324f7d61360e21b815260048101919091526024810182905260440161094d565b611ea8611958565b60ff808a1660009081526003602090815260408083203384528252808320815180830190925280548086168352939491939092840191610100909104166002811115611ef657611ef661414b565b6002811115611f0757611f0761414b565b9052509050600281602001516002811115611f2457611f2461414b565b148015611f785750600260008b60ff1660ff168152602001908152602001600020600301816000015160ff1681548110611f6057611f60614ef7565b6000918252602090912001546001600160a01b031633145b611f9557604051631b41e11d60e31b815260040160405180910390fd5b50816060015115612045576020820151611fb0906001615a66565b60ff16855114611fd3576040516371253a2560e01b815260040160405180910390fd5b8351855114611ff55760405163a75d88af60e01b815260040160405180910390fd5b60008787604051612007929190615a7f565b60405190819003812061201e918b90602001615a8f565b6040516020818303038152906040528051906020012090506120438a828888886130cb565b505b6040805182815260208a8101356001600160401b03169082015260ff8b16917f198d6990ef96613a9026203077e422916918b03ff47f0be6bee7b02d8e139ef0910160405180910390a2505050505050505050565b336001600160a01b038216036120c357604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b806040015160ff1660000361213e576000604051631b3fab5160e11b815260040161094d9190615aa3565b60208082015160ff8082166000908152600290935260408320600181015492939092839216900361218f576060840151600182018054911515620100000262ff0000199092169190911790556121cb565b6060840151600182015460ff62010000909104161515901515146121cb576040516321fd80df60e21b815260ff8416600482015260240161094d565b60a0840151805161010010156121f7576001604051631b3fab5160e11b815260040161094d9190615aa3565b805160000361221c576005604051631b3fab5160e11b815260040161094d9190615aa3565b612282848460030180548060200260200160405190810160405280929190818152602001828054801561227857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161225a575b505050505061327e565b8460600151156123b2576122f08484600201805480602002602001604051908101604052809291908181526020018280548015612278576020028201919060005260206000209081546001600160a01b0316815260019091019060200180831161225a57505050505061327e565b60808501518051610100101561231c576002604051631b3fab5160e11b815260040161094d9190615aa3565b604086015161232c906003615abd565b60ff16815111612352576003604051631b3fab5160e11b815260040161094d9190615aa3565b815181511015612378576001604051631b3fab5160e11b815260040161094d9190615aa3565b805160018401805461ff00191661010060ff8416021790556123a39060028601906020840190613c55565b506123b0858260016132e7565b505b6123be848260026132e7565b80516123d39060038501906020840190613c55565b5060408581015160018401805460ff191660ff8316179055865180855560a088015192517fab8b1b57514019638d7b5ce9c638fe71366fe8e2be1c40a7a80f1733d0e9f5479361242c9389939260028a01929190615ad9565b60405180910390a1610d8384613442565b600061081283836134c5565b600082600001828154811061246057612460614ef7565b9060005260206000200154905092915050565b81518151604051632cbc26bb60e01b8152608083901b67ffffffffffffffff60801b166004820152901515907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632cbc26bb90602401602060405180830381865afa1580156124f0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061251491906156ba565b1561258557801561254357604051637edeb53960e11b81526001600160401b038316600482015260240161094d565b6040516001600160401b03831681527faab522ed53d887e56ed53dd37398a01aeef6a58e0fa77c2173beb9512d8949339060200160405180910390a150505050565b60208401515160008190036125bb57845160405163676cf24b60e11b81526001600160401b03909116600482015260240161094d565b84604001515181146125e0576040516357e0e08360e01b815260040160405180910390fd5b6000816001600160401b038111156125fa576125fa613ccf565b604051908082528060200260200182016040528015612623578160200160208202803683370190505b50905060007f2425b0b9f9054c76ff151b0a175b18f37a4a4e82013a72e9f15c9caa095ed21f857f000000000000000000000000000000000000000000000000000000000000000061267488611d55565b60010160405161268491906156d7565b6040519081900381206126bc949392916020019384526001600160401b03928316602085015291166040830152606082015260800190565b60405160208183030381529060405280519060200120905060005b838110156127f2576000886020015182815181106126f7576126f7614ef7565b602002602001015190507f00000000000000000000000000000000000000000000000000000000000000006001600160401b03168160000151604001516001600160401b03161461276e5780516040908101519051631c21951160e11b81526001600160401b03909116600482015260240161094d565b866001600160401b03168160000151602001516001600160401b0316146127c257805160200151604051636c95f1eb60e01b81526001600160401b03808a166004830152909116602482015260440161094d565b6127cc8184613514565b8483815181106127de576127de614ef7565b6020908102919091010152506001016126d7565b5050600061280a858389606001518a6080015161361c565b90508060000361283857604051633ee8bd3f60e11b81526001600160401b038616600482015260240161094d565b60005b83811015612d045760005a905060008960200151838151811061286057612860614ef7565b60200260200101519050600061287e898360000151606001516107c6565b905060008160038111156128945761289461414b565b14806128b1575060038160038111156128af576128af61414b565b145b61290757815160600151604080516001600160401b03808d16825290921660208301527f3b575419319662b2a6f5e2467d84521517a3382b908eb3d557bb3fdb0c50e23c910160405180910390a1505050612cfc565b606088156129e6578a858151811061292157612921614ef7565b6020908102919091018101510151600454909150600090600160a01b900463ffffffff1661294f8842614f5d565b119050808061296f5750600383600381111561296d5761296d61414b565b145b612997576040516354e7e43160e11b81526001600160401b038c16600482015260240161094d565b8b86815181106129a9576129a9614ef7565b6020026020010151600001516000146129e0578b86815181106129ce576129ce614ef7565b60209081029190910101515160808501525b50612a52565b60008260038111156129fa576129fa61414b565b14612a5257825160600151604080516001600160401b03808e16825290921660208301527f3ef2a99c550a751d4b0b261268f05a803dfb049ab43616a1ffb388f61fe65120910160405180910390a150505050612cfc565b8251608001516001600160401b031615612b28576000826003811115612a7a57612a7a61414b565b03612b285782516080015160208401516040516370701e5760e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263e0e03cae92612ad8928f929190600401615b8b565b6020604051808303816000875af1158015612af7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b1b91906156ba565b612b285750505050612cfc565b60008c604001518681518110612b4057612b40614ef7565b6020026020010151905080518460a001515114612b8a57835160600151604051631cfe6d8b60e01b81526001600160401b03808e166004830152909116602482015260440161094d565b612b9e8b8560000151606001516001613659565b600080612bac8684866136fe565b91509150612bc38d87600001516060015184613659565b8b15612c1a576003826003811115612bdd57612bdd61414b565b03612c1a576000856003811115612bf657612bf661414b565b14612c1a57855151604051632b11b8d960e01b815261094d91908390600401615bb7565b6002826003811115612c2e57612c2e61414b565b14612c6f576003826003811115612c4757612c4761414b565b14612c6f578551606001516040516349362d1f60e11b815261094d918f918590600401615bd0565b8560000151600001518660000151606001516001600160401b03168e6001600160401b03167f05665fe9ad095383d018353f4cbcba77e84db27dd215081bbf7cdf9ae6fbe48b8d8c81518110612cc757612cc7614ef7565b602002602001015186865a612cdc908f614f5d565b604051612cec9493929190615bf5565b60405180910390a4505050505050505b60010161283b565b5050505050505050565b6040805180820190915260008082526020820152602086015160405163bbe4f6db60e01b81526001600160a01b0380831660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063bbe4f6db90602401602060405180830381865afa158015612d92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612db69190615c2c565b90506001600160a01b0381161580612de55750612de36001600160a01b03821663aff2afbf60e01b611c34565b155b15612e0e5760405163ae9b4ce960e01b81526001600160a01b038216600482015260240161094d565b600080612e2688858c6040015163ffffffff166137b2565b915091506000806000612ef76040518061010001604052808e81526020018c6001600160401b031681526020018d6001600160a01b031681526020018f608001518152602001896001600160a01b031681526020018f6000015181526020018f6060015181526020018b815250604051602401612ea39190615c49565b60408051601f198184030181529190526020810180516001600160e01b0316633907753760e01b17905287867f000000000000000000000000000000000000000000000000000000000000000060846138b5565b92509250925082612f1f578582604051634ff17cad60e11b815260040161094d929190615d15565b8151602014612f4e578151604051631e3be00960e21b815260206004820152602481019190915260440161094d565b600082806020019051810190612f649190615d37565b9050866001600160a01b03168c6001600160a01b031614612fe0576000612f958d8a612f90868a614f5d565b6137b2565b50905086811080612faf575081612fac8883614f5d565b14155b15612fde5760405163a966e21f60e01b815260048101839052602481018890526044810182905260640161094d565b505b604080518082019091526001600160a01b039098168852602088015250949550505050505095945050505050565b6000613021826301ffc9a760e01b613041565b8015610815575061303a826001600160e01b0319613041565b1592915050565b6040516001600160e01b031982166024820152600090819060440160408051601f19818403018152919052602080820180516001600160e01b03166301ffc9a760e01b178152825192935060009283928392909183918a617530fa92503d915060005190508280156130b4575060208210155b80156130c05750600081115b979650505050505050565b8251600090815b81811015612d045760006001888684602081106130f1576130f1614ef7565b6130fe91901a601b615a66565b89858151811061311057613110614ef7565b602002602001015189868151811061312a5761312a614ef7565b602002602001015160405160008152602001604052604051613168949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561318a573d6000803e3d6000fd5b505060408051601f1981015160ff808e166000908152600360209081528582206001600160a01b038516835281528582208587019096528554808416865293975090955092939284019161010090041660028111156131eb576131eb61414b565b60028111156131fc576131fc61414b565b90525090506001816020015160028111156132195761321961414b565b1461323757604051636518c33d60e11b815260040160405180910390fd5b8051600160ff9091161b85161561326157604051633d9ef1f160e21b815260040160405180910390fd5b806000015160ff166001901b8517945050508060010190506130d2565b60005b8151811015610aaa5760ff8316600090815260036020526040812083519091908490849081106132b3576132b3614ef7565b6020908102919091018101516001600160a01b03168252810191909152604001600020805461ffff19169055600101613281565b60005b82518110156115ff57600083828151811061330757613307614ef7565b60200260200101519050600060028111156133245761332461414b565b60ff80871660009081526003602090815260408083206001600160a01b038716845290915290205461010090041660028111156133635761336361414b565b14613384576004604051631b3fab5160e11b815260040161094d9190615aa3565b6001600160a01b0381166133ab5760405163d6c62c9b60e01b815260040160405180910390fd5b60405180604001604052808360ff1681526020018460028111156133d1576133d161414b565b905260ff80871660009081526003602090815260408083206001600160a01b0387168452825290912083518154931660ff198416811782559184015190929091839161ffff19161761010083600281111561342e5761342e61414b565b0217905550905050508060010190506132ea565b60ff8181166000818152600260205260409020600101546201000090049091169061349a5780613485576040516317bd8dd160e11b815260040160405180910390fd5b600b805467ffffffffffffffff191690555050565b60001960ff831601611643578015611643576040516307b8c74d60e51b815260040160405180910390fd5b600081815260018301602052604081205461350c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610815565b506000610815565b81518051606080850151908301516080808701519401516040516000958695889561357895919490939192916020019485526001600160a01b039390931660208501526001600160401b039182166040850152606084015216608082015260a00190565b604051602081830303815290604052805190602001208560200151805190602001208660400151805190602001208760a001516040516020016135bb9190615df1565b60408051601f198184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e0015b60405160208183030381529060405280519060200120905092915050565b60008061362a85858561398f565b6001600160401b0387166000908152600a6020908152604080832093835292905220549150505b949350505050565b60006002613668608085614f86565b6001600160401b031661367b9190614fac565b905060006136898585611913565b90508161369860016004614f5d565b901b1916818360038111156136af576136af61414b565b6001600160401b03871660009081526009602052604081209190921b929092179182916136dd6080886159cc565b6001600160401b031681526020810191909152604001600020555050505050565b604051630304c3e160e51b815260009060609030906360987c209061372b90889088908890600401615e88565b600060405180830381600087803b15801561374557600080fd5b505af1925050508015613756575060015b613795573d808015613784576040519150601f19603f3d011682016040523d82523d6000602084013e613789565b606091505b506003925090506137aa565b50506040805160208101909152600081526002905b935093915050565b6000806000806000613831886040516024016137dd91906001600160a01b0391909116815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166370a0823160e01b17905288887f000000000000000000000000000000000000000000000000000000000000000060846138b5565b92509250925082613859578682604051634ff17cad60e11b815260040161094d929190615d15565b6020825114613888578151604051631e3be00960e21b815260206004820152602481019190915260440161094d565b8180602001905181019061389c9190615d37565b6138a68288614f5d565b94509450505050935093915050565b6000606060008361ffff166001600160401b038111156138d7576138d7613ccf565b6040519080825280601f01601f191660200182016040528015613901576020820181803683370190505b509150863b61391b5763030ed58f60e21b60005260046000fd5b5a8581101561393557632be8ca8b60e21b60005260046000fd5b8590036040810481038710613955576337c3be2960e01b60005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d848111156139785750835b808352806000602085013e50955095509592505050565b82518251600091908183036139b757604051630469ac9960e21b815260040160405180910390fd5b61010182118015906139cb57506101018111155b6139e8576040516309bde33960e01b815260040160405180910390fd5b60001982820101610100811115613a12576040516309bde33960e01b815260040160405180910390fd5b80600003613a3f5786600081518110613a2d57613a2d614ef7565b60200260200101519350505050613c0d565b6000816001600160401b03811115613a5957613a59613ccf565b604051908082528060200260200182016040528015613a82578160200160208202803683370190505b50905060008080805b85811015613bac5760006001821b8b811603613ae65788851015613acf578c5160018601958e918110613ac057613ac0614ef7565b60200260200101519050613b08565b8551600185019487918110613ac057613ac0614ef7565b8b5160018401938d918110613afd57613afd614ef7565b602002602001015190505b600089861015613b38578d5160018701968f918110613b2957613b29614ef7565b60200260200101519050613b5a565b8651600186019588918110613b4f57613b4f614ef7565b602002602001015190505b82851115613b7b576040516309bde33960e01b815260040160405180910390fd5b613b858282613c14565b878481518110613b9757613b97614ef7565b60209081029190910101525050600101613a8b565b506001850382148015613bbe57508683145b8015613bc957508581145b613be6576040516309bde33960e01b815260040160405180910390fd5b836001860381518110613bfb57613bfb614ef7565b60200260200101519750505050505050505b9392505050565b6000818310613c2c57613c278284613c32565b610812565b61081283835b6040805160016020820152908101839052606081018290526000906080016135fe565b828054828255906000526020600020908101928215613caa579160200282015b82811115613caa57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613c75565b50613cb6929150613cba565b5090565b5b80821115613cb65760008155600101613cbb565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715613d0757613d07613ccf565b60405290565b60405160a081016001600160401b0381118282101715613d0757613d07613ccf565b60405160c081016001600160401b0381118282101715613d0757613d07613ccf565b604080519081016001600160401b0381118282101715613d0757613d07613ccf565b604051606081016001600160401b0381118282101715613d0757613d07613ccf565b604051601f8201601f191681016001600160401b0381118282101715613dbd57613dbd613ccf565b604052919050565b60006001600160401b03821115613dde57613dde613ccf565b5060051b60200190565b6001600160a01b038116811461056857600080fd5b80356001600160401b0381168114613e1457600080fd5b919050565b801515811461056857600080fd5b8035613e1481613e19565b60006001600160401b03821115613e4b57613e4b613ccf565b50601f01601f191660200190565b600082601f830112613e6a57600080fd5b8135613e7d613e7882613e32565b613d95565b818152846020838601011115613e9257600080fd5b816020850160208301376000918101602001919091529392505050565b60006020808385031215613ec257600080fd5b82356001600160401b0380821115613ed957600080fd5b818501915085601f830112613eed57600080fd5b8135613efb613e7882613dc5565b81815260059190911b83018401908481019088831115613f1a57600080fd5b8585015b83811015613fc057803585811115613f365760008081fd5b86016080818c03601f1901811315613f4e5760008081fd5b613f56613ce5565b89830135613f6381613de8565b81526040613f72848201613dfd565b8b830152606080850135613f8581613e19565b83830152928401359289841115613f9e57600091508182fd5b613fac8f8d86880101613e59565b908301525085525050918601918601613f1e565b5098975050505050505050565b60005b83811015613fe8578181015183820152602001613fd0565b50506000910152565b60008151808452614009816020860160208601613fcd565b601f01601f19169290920160200192915050565b6020815260006108126020830184613ff1565b6001600160a01b0381511682526020810151151560208301526001600160401b03604082015116604083015260006060820151608060608501526136516080850182613ff1565b604080825283519082018190526000906020906060840190828701845b828110156140b95781516001600160401b031684529284019290840190600101614094565b50505083810382850152845180825282820190600581901b8301840187850160005b8381101561410957601f198684030185526140f7838351614030565b948701949250908601906001016140db565b50909998505050505050505050565b6000806040838503121561412b57600080fd5b61413483613dfd565b915061414260208401613dfd565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b600481106141715761417161414b565b9052565b602081016108158284614161565b600060a0828403121561419557600080fd5b61419d613d0d565b9050813581526141af60208301613dfd565b60208201526141c060408301613dfd565b60408201526141d160608301613dfd565b60608201526141e260808301613dfd565b608082015292915050565b8035613e1481613de8565b803563ffffffff81168114613e1457600080fd5b600082601f83011261421d57600080fd5b8135602061422d613e7883613dc5565b82815260059290921b8401810191818101908684111561424c57600080fd5b8286015b8481101561431c5780356001600160401b03808211156142705760008081fd5b9088019060a0828b03601f190181131561428a5760008081fd5b614292613d0d565b87840135838111156142a45760008081fd5b6142b28d8a83880101613e59565b8252506040808501356142c481613de8565b828a015260606142d58682016141f8565b828401526080915081860135858111156142ef5760008081fd5b6142fd8f8c838a0101613e59565b9184019190915250919093013590830152508352918301918301614250565b509695505050505050565b6000610140828403121561433a57600080fd5b614342613d2f565b905061434e8383614183565b815260a08201356001600160401b038082111561436a57600080fd5b61437685838601613e59565b602084015260c084013591508082111561438f57600080fd5b61439b85838601613e59565b60408401526143ac60e085016141ed565b606084015261010084013560808401526101208401359150808211156143d157600080fd5b506143de8482850161420c565b60a08301525092915050565b600082601f8301126143fb57600080fd5b8135602061440b613e7883613dc5565b82815260059290921b8401810191818101908684111561442a57600080fd5b8286015b8481101561431c5780356001600160401b0381111561444d5760008081fd5b61445b8986838b0101614327565b84525091830191830161442e565b600082601f83011261447a57600080fd5b8135602061448a613e7883613dc5565b82815260059290921b840181019181810190868411156144a957600080fd5b8286015b8481101561431c5780356001600160401b03808211156144cc57600080fd5b818901915089603f8301126144e057600080fd5b858201356144f0613e7882613dc5565b81815260059190911b830160400190878101908c83111561451057600080fd5b604085015b838110156145495780358581111561452c57600080fd5b61453b8f6040838a0101613e59565b845250918901918901614515565b508752505050928401925083016144ad565b600082601f83011261456c57600080fd5b8135602061457c613e7883613dc5565b8083825260208201915060208460051b87010193508684111561459e57600080fd5b602086015b8481101561431c57803583529183019183016145a3565b600082601f8301126145cb57600080fd5b813560206145db613e7883613dc5565b82815260059290921b840181019181810190868411156145fa57600080fd5b8286015b8481101561431c5780356001600160401b038082111561461e5760008081fd5b9088019060a0828b03601f19018113156146385760008081fd5b614640613d0d565b61464b888501613dfd565b8152604080850135848111156146615760008081fd5b61466f8e8b838901016143ea565b8a84015250606080860135858111156146885760008081fd5b6146968f8c838a0101614469565b83850152506080915081860135858111156146b15760008081fd5b6146bf8f8c838a010161455b565b91840191909152509190930135908301525083529183019183016145fe565b600080604083850312156146f157600080fd5b6001600160401b038335111561470657600080fd5b61471384843585016145ba565b91506001600160401b036020840135111561472d57600080fd5b6020830135830184601f82011261474357600080fd5b614750613e788235613dc5565b81358082526020808301929160051b84010187101561476e57600080fd5b602083015b6020843560051b850101811015614914576001600160401b038135111561479957600080fd5b87603f8235860101126147ab57600080fd5b6147be613e786020833587010135613dc5565b81358501602081810135808452908301929160059190911b016040018a10156147e657600080fd5b604083358701015b83358701602081013560051b01604001811015614904576001600160401b038135111561481a57600080fd5b833587018135016040818d03603f1901121561483557600080fd5b61483d613d51565b604082013581526001600160401b036060830135111561485c57600080fd5b8c605f60608401358401011261487157600080fd5b6040606083013583010135614888613e7882613dc5565b808282526020820191508f60608460051b60608801358801010111156148ad57600080fd5b6060808601358601015b60608460051b6060880135880101018110156148e4576148d6816141f8565b8352602092830192016148b7565b5080602085015250505080855250506020830192506020810190506147ee565b5084525060209283019201614773565b508093505050509250929050565b60008083601f84011261493457600080fd5b5081356001600160401b0381111561494b57600080fd5b6020830191508360208260051b850101111561496657600080fd5b9250929050565b60008060008060006060868803121561498557600080fd5b85356001600160401b038082111561499c57600080fd5b6149a889838a01614327565b965060208801359150808211156149be57600080fd5b6149ca89838a01614922565b909650945060408801359150808211156149e357600080fd5b506149f088828901614922565b969995985093965092949392505050565b600060808284031215614a1357600080fd5b614a1b613ce5565b8235614a2681613de8565b8152614a34602084016141f8565b60208201526040830135614a4781613e19565b60408201526060830135614a5a81613de8565b60608201529392505050565b600060208284031215614a7857600080fd5b81356001600160401b03811115614a8e57600080fd5b820160a08185031215613c0d57600080fd5b803560ff81168114613e1457600080fd5b600060208284031215614ac357600080fd5b61081282614aa0565b60008151808452602080850194506020840160005b83811015614b065781516001600160a01b031687529582019590820190600101614ae1565b509495945050505050565b60208152600082518051602084015260ff602082015116604084015260ff604082015116606084015260608101511515608084015250602083015160c060a0840152614b6060e0840182614acc565b90506040840151601f198483030160c0850152614b7d8282614acc565b95945050505050565b60008060408385031215614b9957600080fd5b614ba283613dfd565b946020939093013593505050565b806040810183101561081557600080fd5b60008083601f840112614bd357600080fd5b5081356001600160401b03811115614bea57600080fd5b60208301915083602082850101111561496657600080fd5b60008060008060008060008060c0898b031215614c1e57600080fd5b614c288a8a614bb0565b975060408901356001600160401b0380821115614c4457600080fd5b614c508c838d01614bc1565b909950975060608b0135915080821115614c6957600080fd5b614c758c838d01614922565b909750955060808b0135915080821115614c8e57600080fd5b50614c9b8b828c01614922565b999c989b50969995989497949560a00135949350505050565b600060208284031215614cc657600080fd5b61081282613dfd565b6020815260006108126020830184614030565b600060208284031215614cf457600080fd5b8135613c0d81613de8565b600080600060608486031215614d1457600080fd5b614d1e8585614bb0565b925060408401356001600160401b03811115614d3957600080fd5b614d4586828701614bc1565b9497909650939450505050565b600082601f830112614d6357600080fd5b81356020614d73613e7883613dc5565b8083825260208201915060208460051b870101935086841115614d9557600080fd5b602086015b8481101561431c578035614dad81613de8565b8352918301918301614d9a565b60006020808385031215614dcd57600080fd5b82356001600160401b0380821115614de457600080fd5b818501915085601f830112614df857600080fd5b8135614e06613e7882613dc5565b81815260059190911b83018401908481019088831115614e2557600080fd5b8585015b83811015613fc057803585811115614e4057600080fd5b860160c0818c03601f19011215614e575760008081fd5b614e5f613d2f565b8882013581526040614e72818401614aa0565b8a8301526060614e83818501614aa0565b8284015260809150614e96828501613e27565b9083015260a08381013589811115614eae5760008081fd5b614ebc8f8d83880101614d52565b838501525060c0840135915088821115614ed65760008081fd5b614ee48e8c84870101614d52565b9083015250845250918601918601614e29565b634e487b7160e01b600052603260045260246000fd5b600181811c90821680614f2157607f821691505b602082108103614f4157634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561081557610815614f47565b634e487b7160e01b600052601260045260246000fd5b60006001600160401b0380841680614fa057614fa0614f70565b92169190910692915050565b808202811582820484141761081557610815614f47565b80518252600060206001600160401b0381840151168185015260408084015160a06040870152614ff660a0870182613ff1565b90506060850151868203606088015261500f8282613ff1565b608087810151898303918a01919091528051808352908601935060009250908501905b8083101561506457835180516001600160a01b0316835286015186830152928501926001929092019190840190615032565b50979650505050505050565b6020815260006108126020830184614fc3565b6080815260006150966080830187614fc3565b61ffff9590951660208301525060408101929092526001600160a01b0316606090910152919050565b6000806000606084860312156150d457600080fd5b83516150df81613e19565b60208501519093506001600160401b038111156150fb57600080fd5b8401601f8101861361510c57600080fd5b805161511a613e7882613e32565b81815287602083850101111561512f57600080fd5b615140826020830160208601613fcd565b809450505050604084015190509250925092565b80356001600160e01b0381168114613e1457600080fd5b600082601f83011261517c57600080fd5b8135602061518c613e7883613dc5565b82815260069290921b840181019181810190868411156151ab57600080fd5b8286015b8481101561431c57604081890312156151c85760008081fd5b6151d0613d51565b6151d982613dfd565b81526151e6858301615154565b818601528352918301916040016151af565b600082601f83011261520957600080fd5b81356020615219613e7883613dc5565b82815260059290921b8401810191818101908684111561523857600080fd5b8286015b8481101561431c5780356001600160401b038082111561525c5760008081fd5b9088019060a0828b03601f19018113156152765760008081fd5b61527e613d0d565b615289888501613dfd565b81526040808501358481111561529f5760008081fd5b6152ad8e8b83890101613e59565b8a84015250606093506152c1848601613dfd565b9082015260806152d2858201613dfd565b9382019390935292013590820152835291830191830161523c565b600082601f8301126152fe57600080fd5b8135602061530e613e7883613dc5565b82815260069290921b8401810191818101908684111561532d57600080fd5b8286015b8481101561431c576040818903121561534a5760008081fd5b615352613d51565b813581528482013585820152835291830191604001615331565b6000602080838503121561537f57600080fd5b82356001600160401b038082111561539657600080fd5b90840190606082870312156153aa57600080fd5b6153b2613d73565b8235828111156153c157600080fd5b830160408189038113156153d457600080fd5b6153dc613d51565b8235858111156153eb57600080fd5b8301601f81018b136153fc57600080fd5b803561540a613e7882613dc5565b81815260069190911b8201890190898101908d83111561542957600080fd5b928a01925b828410156154795785848f0312156154465760008081fd5b61544e613d51565b843561545981613de8565b8152615466858d01615154565b818d0152825292850192908a019061542e565b84525050508287013591508482111561549157600080fd5b61549d8a83850161516b565b818801528352505082840135828111156154b657600080fd5b6154c2888286016151f8565b858301525060408301359350818411156154db57600080fd5b6154e7878585016152ed565b60408201529695505050505050565b600082825180855260208086019550808260051b84010181860160005b8481101561558757601f19868403018952815160a06001600160401b0380835116865286830151828888015261554b83880182613ff1565b60408581015184169089015260608086015190931692880192909252506080928301519290950191909152509783019790830190600101615513565b5090979650505050505050565b6001600160a01b0384168152600060206060818401526155b760608401866154f6565b83810360408581019190915285518083528387019284019060005b81811015614109578451805184528601518684015293850193918301916001016155d2565b805160408084528151848201819052600092602091908201906060870190855b8181101561564e57835180516001600160a01b031684528501516001600160e01b0316858401529284019291850191600101615617565b50508583015187820388850152805180835290840192506000918401905b8083101561506457835180516001600160401b031683528501516001600160e01b03168583015292840192600192909201919085019061566c565b60208152600061081260208301846155f7565b6000602082840312156156cc57600080fd5b8151613c0d81613e19565b60008083546156e581614f0d565b600182811680156156fd576001811461571257615741565b60ff1984168752821515830287019450615741565b8760005260208060002060005b858110156157385781548a82015290840190820161571f565b50505082870194505b50929695505050505050565b6000815461575a81614f0d565b8085526020600183811680156157775760018114615791576157bf565b60ff1985168884015283151560051b8801830195506157bf565b866000528260002060005b858110156157b75781548a820186015290830190840161579c565b890184019650505b505050505092915050565b6040815260006157dd6040830185613ff1565b8281036020840152614b7d818561574d565b6001600160401b0381811683821601908082111561580f5761580f614f47565b5092915050565b60408152600061582960408301856154f6565b8281036020840152614b7d81856155f7565b60006020828403121561584d57600080fd5b81356001600160401b0381111561586357600080fd5b613651848285016145ba565b601f821115610aaa576000816000526020600020601f850160051c810160208610156158985750805b601f850160051c820191505b818110156158b7578281556001016158a4565b505050505050565b81516001600160401b038111156158d8576158d8613ccf565b6158ec816158e68454614f0d565b8461586f565b602080601f83116001811461592157600084156159095750858301515b600019600386901b1c1916600185901b1785556158b7565b600085815260208120601f198616915b8281101561595057888601518255948401946001909101908401615931565b508582101561596e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60208152600082546001600160a01b038116602084015260ff8160a01c16151560408401526001600160401b038160a81c1660608401525060808083015261081260a083016001850161574d565b60006001600160401b03808416806159e6576159e6614f70565b92169190910492915050565b600060208284031215615a0457600080fd5b610812826141f8565b6000808335601e19843603018112615a2457600080fd5b8301803591506001600160401b03821115615a3e57600080fd5b60200191503681900382131561496657600080fd5b8082018082111561081557610815614f47565b60ff818116838216019081111561081557610815614f47565b8183823760009101908152919050565b828152604082602083013760600192915050565b6020810160068310615ab757615ab761414b565b91905290565b60ff818116838216029081169081811461580f5761580f614f47565b600060a0820160ff881683526020878185015260a0604085015281875480845260c0860191508860005282600020935060005b81811015615b315784546001600160a01b031683526001948501949284019201615b0c565b50508481036060860152865180825290820192508187019060005b81811015615b715782516001600160a01b031685529383019391830191600101615b4c565b50505060ff851660808501525090505b9695505050505050565b60006001600160401b03808616835280851660208401525060606040830152614b7d6060830184613ff1565b8281526040602082015260006136516040830184613ff1565b6001600160401b03848116825283166020820152606081016136516040830184614161565b848152615c056020820185614161565b608060408201526000615c1b6080830185613ff1565b905082606083015295945050505050565b600060208284031215615c3e57600080fd5b8151613c0d81613de8565b6020815260008251610100806020850152615c68610120850183613ff1565b91506020850151615c8460408601826001600160401b03169052565b5060408501516001600160a01b038116606086015250606085015160808501526080850151615cbe60a08601826001600160a01b03169052565b5060a0850151601f19808685030160c0870152615cdb8483613ff1565b935060c08701519150808685030160e0870152615cf88483613ff1565b935060e0870151915080868503018387015250615b818382613ff1565b6001600160a01b03831681526040602082015260006136516040830184613ff1565b600060208284031215615d4957600080fd5b5051919050565b600082825180855260208086019550808260051b84010181860160005b8481101561558757601f19868403018952815160a08151818652615d9382870182613ff1565b9150506001600160a01b03868301511686860152604063ffffffff8184015116818701525060608083015186830382880152615dcf8382613ff1565b6080948501519790940196909652505098840198925090830190600101615d6d565b6020815260006108126020830184615d50565b60008282518085526020808601955060208260051b8401016020860160005b8481101561558757601f19868403018952615e3f838351613ff1565b98840198925090830190600101615e23565b60008151808452602080850194506020840160005b83811015614b0657815163ffffffff1687529582019590820190600101615e66565b60608152600084518051606084015260208101516001600160401b0380821660808601528060408401511660a08601528060608401511660c08601528060808401511660e0860152505050602085015161014080610100850152615ef06101a0850183613ff1565b91506040870151605f198086850301610120870152615f0f8483613ff1565b935060608901519150615f2c838701836001600160a01b03169052565b608089015161016087015260a0890151925080868503016101808701525050615f558282615d50565b9150508281036020840152615f6a8186615e04565b90508281036040840152615b818185615e5156fea164736f6c6343000818000a", } var OffRampABI = OffRampMetaData.ABI @@ -2467,7 +2468,7 @@ func (OffRampSourceChainSelectorAdded) Topic() common.Hash { } func (OffRampStaticConfigSet) Topic() common.Hash { - return common.HexToHash("0x683eb52ee924eb817377cfa8f41f238f4bb7a877da5267869dfffbad85f564d8") + return common.HexToHash("0xb0fa1fb01508c5097c502ad056fd77018870c9be9a86d9e56b6b471862d7c5b7") } func (OffRampTransmitted) Topic() common.Hash { diff --git a/core/gethwrappers/ccip/generated/token_pool/token_pool.go b/core/gethwrappers/ccip/generated/token_pool/token_pool.go index 5032b336e0a..c7c947d8636 100644 --- a/core/gethwrappers/ccip/generated/token_pool/token_pool.go +++ b/core/gethwrappers/ccip/generated/token_pool/token_pool.go @@ -81,7 +81,7 @@ type TokenPoolChainUpdate struct { } var TokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"lockOrBurnOut\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MismatchedArrayLengths\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"lockOrBurnOut\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectors\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config[]\",\"name\":\"outboundConfigs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config[]\",\"name\":\"inboundConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setChainRateLimiterConfigs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", } var TokenPoolABI = TokenPoolMetaData.ABI @@ -672,6 +672,18 @@ func (_TokenPool *TokenPoolTransactorSession) SetChainRateLimiterConfig(remoteCh return _TokenPool.Contract.SetChainRateLimiterConfig(&_TokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) } +func (_TokenPool *TokenPoolTransactor) SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "setChainRateLimiterConfigs", remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_TokenPool *TokenPoolSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _TokenPool.Contract.SetChainRateLimiterConfigs(&_TokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_TokenPool *TokenPoolTransactorSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _TokenPool.Contract.SetChainRateLimiterConfigs(&_TokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + func (_TokenPool *TokenPoolTransactor) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) { return _TokenPool.contract.Transact(opts, "setRateLimitAdmin", rateLimitAdmin) } @@ -2867,6 +2879,8 @@ type TokenPoolInterface interface { SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) + SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go b/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go index ca6c4a1977f..fb9493b24ac 100644 --- a/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go +++ b/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go @@ -94,8 +94,8 @@ type USDCTokenPoolDomainUpdate struct { } var USDCTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidDestinationDomain\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate\",\"name\":\"domain\",\"type\":\"tuple\"}],\"name\":\"InvalidDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidMessageVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"}],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"}],\"name\":\"InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidSourceDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidTokenMessengerVersion\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"domain\",\"type\":\"uint64\"}],\"name\":\"UnknownDomain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnlockingUSDCFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"DomainsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUPPORTED_USDC_VERSION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getDomain\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.Domain\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_localDomainIdentifier\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_messageTransmitter\",\"outputs\":[{\"internalType\":\"contractIMessageTransmitter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_tokenMessenger\",\"outputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"domains\",\"type\":\"tuple[]\"}],\"name\":\"setDomains\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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: "0x6101606040523480156200001257600080fd5b50604051620054b7380380620054b7833981016040819052620000359162000b93565b836006848484336000816200005d57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200009057620000908162000493565b50506001600160a01b0385161580620000b057506001600160a01b038116155b80620000c357506001600160a01b038216155b15620000e2576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808616608081905290831660c0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa92505050801562000152575060408051601f3d908101601f191682019092526200014f9181019062000cb9565b60015b1562000193578060ff168560ff161462000191576040516332ad3e0760e11b815260ff8087166004830152821660248201526044015b60405180910390fd5b505b60ff841660a052600480546001600160a01b0319166001600160a01b038316179055825115801560e052620001dd57604080516000815260208101909152620001dd90846200050d565b5050506001600160a01b03871691506200020c9050576040516306b7c75960e31b815260040160405180910390fd5b6000856001600160a01b0316632c1219216040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200024d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000273919062000ce5565b90506000816001600160a01b03166354fd4d506040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002b6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002dc919062000d05565b905063ffffffff8116156200030d576040516334697c6b60e11b815263ffffffff8216600482015260240162000188565b6000876001600160a01b0316639cdbb1816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200034e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000374919062000d05565b905063ffffffff811615620003a5576040516316ba39c560e31b815263ffffffff8216600482015260240162000188565b6001600160a01b038089166101005283166101208190526040805163234d8e3d60e21b81529051638d3638f4916004808201926020929091908290030181865afa158015620003f8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200041e919062000d05565b63ffffffff16610140526101005160805162000449916001600160a01b03909116906000196200066a565b6040516001600160a01b03891681527f2e902d38f15b233cbb63711add0fca4545334d3a169d60c0a616494d7eea95449060200160405180910390a1505050505050505062000e52565b336001600160a01b03821603620004bd57604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e0516200052e576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620005b957600083828151811062000552576200055262000d2d565b602090810291909101015190506200056c60028262000750565b15620005af576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000531565b5060005b815181101562000665576000828281518110620005de57620005de62000d2d565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200060a57506200065c565b6200061760028262000770565b156200065a576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620005bd565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620006bc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620006e2919062000d43565b620006ee919062000d73565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200074a918691906200078716565b50505050565b600062000767836001600160a01b03841662000858565b90505b92915050565b600062000767836001600160a01b0384166200095c565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490820152600090620007d6906001600160a01b038516908490620009ae565b805190915015620006655780806020019051810190620007f7919062000d89565b620006655760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000188565b60008181526001830160205260408120548015620009515760006200087f60018362000dad565b8554909150600090620008959060019062000dad565b905080821462000901576000866000018281548110620008b957620008b962000d2d565b9060005260206000200154905080876000018481548110620008df57620008df62000d2d565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000915576200091562000dc3565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200076a565b60009150506200076a565b6000818152600183016020526040812054620009a5575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200076a565b5060006200076a565b6060620009bf8484600085620009c7565b949350505050565b60608247101562000a2a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000188565b600080866001600160a01b0316858760405162000a48919062000dff565b60006040518083038185875af1925050503d806000811462000a87576040519150601f19603f3d011682016040523d82523d6000602084013e62000a8c565b606091505b50909250905062000aa08783838762000aab565b979650505050505050565b6060831562000b1f57825160000362000b17576001600160a01b0385163b62000b175760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000188565b5081620009bf565b620009bf838381511562000b365781518083602001fd5b8060405162461bcd60e51b815260040162000188919062000e1d565b6001600160a01b038116811462000b6857600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000b8e8162000b52565b919050565b600080600080600060a0868803121562000bac57600080fd5b855162000bb98162000b52565b8095505060208087015162000bce8162000b52565b60408801519095506001600160401b038082111562000bec57600080fd5b818901915089601f83011262000c0157600080fd5b81518181111562000c165762000c1662000b6b565b8060051b604051601f19603f8301168101818110858211171562000c3e5762000c3e62000b6b565b60405291825284820192508381018501918c83111562000c5d57600080fd5b938501935b8285101562000c865762000c768562000b81565b8452938501939285019262000c62565b80985050505050505062000c9d6060870162000b81565b915062000cad6080870162000b81565b90509295509295909350565b60006020828403121562000ccc57600080fd5b815160ff8116811462000cde57600080fd5b9392505050565b60006020828403121562000cf857600080fd5b815162000cde8162000b52565b60006020828403121562000d1857600080fd5b815163ffffffff8116811462000cde57600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000d5657600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156200076a576200076a62000d5d565b60006020828403121562000d9c57600080fd5b8151801515811462000cde57600080fd5b818103818111156200076a576200076a62000d5d565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000df657818101518382015260200162000ddc565b50506000910152565b6000825162000e1381846020870162000dd9565b9190910192915050565b602081526000825180602084015262000e3e81604085016020870162000dd9565b601f01601f19169190910160400192915050565b60805160a05160c05160e0516101005161012051610140516145af62000f08600039600081816104170152818161113c01528181612107015261216501526000818161072b0152610a750152600081816103dd01526110520152600081816106dc0152818161221d0152612bcc01526000818161061801528181611eb40152612509015260006103660152600081816102cd015281816103220152818161101c01528181612b620152612db701526145af6000f3fe608060405234801561001057600080fd5b50600436106102405760003560e01c80639a4575b911610145578063c4bffe2b116100bd578063dfadfa351161008c578063e8a1da1711610071578063e8a1da1714610700578063f2fde38b14610713578063fbf84dd71461072657600080fd5b8063dfadfa351461063c578063e0351e13146106da57600080fd5b8063c4bffe2b146105db578063c75eea9c146105f0578063cf7401f314610603578063dc0bd9711461061657600080fd5b8063acfecf9111610114578063b0f479a1116100f9578063b0f479a114610597578063b7946580146105b5578063c0d78655146105c857600080fd5b8063acfecf9114610515578063af58d59f1461052857600080fd5b80639a4575b9146104b85780639fdf13ff146104d8578063a42a7b8b146104e0578063a7cd63b71461050057600080fd5b806354c8a4f3116101d85780636d3d1a58116101a75780637d54534e1161018c5780637d54534e146104745780638926f54f146104875780638da5cb5b1461049a57600080fd5b80636d3d1a581461044e57806379ba50971461046c57600080fd5b806354c8a4f3146103c55780636155cda0146103d857806362ddd3c4146103ff5780636b716b0d1461041257600080fd5b8063240028e811610214578063240028e81461031257806324f65ee71461035f57806339077537146103905780634c5ef0ed146103b257600080fd5b806241d3c11461024557806301ffc9a71461025a578063181f5a771461028257806321df0da7146102cb575b600080fd5b610258610253366004613577565b61074d565b005b61026d6102683660046135ec565b6108ea565b60405190151581526020015b60405180910390f35b6102be6040518060400160405280601381526020017f55534443546f6b656e506f6f6c20312e352e310000000000000000000000000081525081565b6040516102799190613692565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610279565b61026d6103203660046136c7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610279565b6103a361039e3660046136e4565b6109cf565b60405190518152602001610279565b61026d6103c0366004613736565b610bb4565b6102586103d3366004613807565b610bfe565b6102ed7f000000000000000000000000000000000000000000000000000000000000000081565b61025861040d366004613736565b610c79565b6104397f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610279565b60095473ffffffffffffffffffffffffffffffffffffffff166102ed565b610258610d11565b6102586104823660046136c7565b610ddf565b61026d610495366004613873565b610e60565b60015473ffffffffffffffffffffffffffffffffffffffff166102ed565b6104cb6104c6366004613890565b610e77565b60405161027991906138cb565b610439600081565b6104f36104ee366004613873565b6111b7565b6040516102799190613922565b610508611322565b60405161027991906139a4565b610258610523366004613736565b611333565b61053b610536366004613873565b61144b565b604051610279919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102ed565b6102be6105c3366004613873565b611520565b6102586105d63660046136c7565b6115d0565b6105e36116a4565b60405161027991906139fe565b61053b6105fe366004613873565b61175c565b610258610611366004613b8b565b61182e565b7f00000000000000000000000000000000000000000000000000000000000000006102ed565b6106b061064a366004613873565b60408051606080820183526000808352602080840182905292840181905267ffffffffffffffff949094168452600a82529282902082519384018352805484526001015463ffffffff811691840191909152640100000000900460ff1615159082015290565b604080518251815260208084015163ffffffff169082015291810151151590820152606001610279565b7f000000000000000000000000000000000000000000000000000000000000000061026d565b61025861070e366004613807565b6118b2565b6102586107213660046136c7565b611dc4565b6102ed7f000000000000000000000000000000000000000000000000000000000000000081565b610755611dd8565b60005b818110156108ac57600083838381811061077457610774613bd2565b90506080020180360381019061078a9190613c15565b805190915015806107a75750604081015167ffffffffffffffff16155b1561081657604080517fa087bd2900000000000000000000000000000000000000000000000000000000815282516004820152602083015163ffffffff1660248201529082015167ffffffffffffffff1660448201526060820151151560648201526084015b60405180910390fd5b60408051606080820183528351825260208085015163ffffffff9081168285019081529286015115158486019081529585015167ffffffffffffffff166000908152600a90925293902091518255516001918201805494511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000909516919093161792909217905501610758565b507f1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee5682826040516108de929190613c8f565b60405180910390a15050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061097d57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806109c957507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b6040805160208101909152600081526109e782611e2b565b60006109f660c0840184613d16565b810190610a039190613d7b565b90506000610a1460e0850185613d16565b810190610a219190613e48565b9050610a3181600001518361204f565b805160208201516040517f57ecfd2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016926357ecfd2892610aa892600401613ed9565b6020604051808303816000875af1158015610ac7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aeb9190613efe565b610b21576040517fbf969f2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b3160608501604086016136c7565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08660600135604051610b9391815260200190565b60405180910390a35050604080516020810190915260609092013582525090565b6000610bf68383604051610bc9929190613f1b565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190612200565b949350505050565b610c06611dd8565b610c738484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061221b92505050565b50505050565b610c81611dd8565b610c8a83610e60565b610ccc576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161080d565b610d0c8383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506123d192505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d62576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610de7611dd8565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b60006109c9600567ffffffffffffffff8416612200565b6040805180820190915260608082526020820152610e94826124cb565b6000600a81610ea96040860160208701613873565b67ffffffffffffffff168152602080820192909252604090810160002081516060810183528154815260019091015463ffffffff81169382019390935264010000000090920460ff161515908201819052909150610f5057610f116040840160208501613873565b6040517fd201c48a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161080d565b610f5a8380613d16565b9050602014610fa157610f6d8380613d16565b6040517fa3c8cf0900000000000000000000000000000000000000000000000000000000815260040161080d929190613f74565b6000610fad8480613d16565b810190610fba9190613f88565b602083015183516040517ff856ddb60000000000000000000000000000000000000000000000000000000081526060880135600482015263ffffffff90921660248301526044820183905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116606484015260848301919091529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063f856ddb69060a4016020604051808303816000875af115801561109b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110bf9190613fa1565b6040516060870135815290915033907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a2604051806040016040528061111c8760200160208101906105c39190613873565b815260408051808201825267ffffffffffffffff851680825263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602093840190815284518085019390935251169281019290925290910190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905295945050505050565b67ffffffffffffffff81166000908152600760205260408120606091906111e090600501612657565b90506000815167ffffffffffffffff8111156111fe576111fe613a40565b60405190808252806020026020018201604052801561123157816020015b606081526020019060019003908161121c5790505b50905060005b825181101561131a576008600084838151811061125657611256613bd2565b60200260200101518152602001908152602001600020805461127790613fbe565b80601f01602080910402602001604051908101604052809291908181526020018280546112a390613fbe565b80156112f05780601f106112c5576101008083540402835291602001916112f0565b820191906000526020600020905b8154815290600101906020018083116112d357829003601f168201915b505050505082828151811061130757611307613bd2565b6020908102919091010152600101611237565b509392505050565b606061132e6002612657565b905090565b61133b611dd8565b61134483610e60565b611386576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161080d565b6113c68282604051611399929190613f1b565b604080519182900390912067ffffffffffffffff8616600090815260076020529190912060050190612664565b611402578282826040517f74f23c7c00000000000000000000000000000000000000000000000000000000815260040161080d93929190614011565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d76838360405161143e929190613f74565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526109c990612670565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061154b90613fbe565b80601f016020809104026020016040519081016040528092919081815260200182805461157790613fbe565b80156115c45780601f10611599576101008083540402835291602001916115c4565b820191906000526020600020905b8154815290600101906020018083116115a757829003601f168201915b50505050509050919050565b6115d8611dd8565b73ffffffffffffffffffffffffffffffffffffffff8116611625576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f168491016108de565b606060006116b26005612657565b90506000815167ffffffffffffffff8111156116d0576116d0613a40565b6040519080825280602002602001820160405280156116f9578160200160208202803683370190505b50905060005b82518110156117555782818151811061171a5761171a613bd2565b602002602001015182828151811061173457611734613bd2565b67ffffffffffffffff909216602092830291909101909101526001016116ff565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526109c990612670565b60095473ffffffffffffffffffffffffffffffffffffffff16331480159061186e575060015473ffffffffffffffffffffffffffffffffffffffff163314155b156118a7576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161080d565b610d0c838383612722565b6118ba611dd8565b60005b83811015611aa75760008585838181106118d9576118d9613bd2565b90506020020160208101906118ee9190613873565b9050611905600567ffffffffffffffff8316612664565b611947576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161080d565b67ffffffffffffffff8116600090815260076020526040812061196c90600501612657565b905060005b81518110156119d8576119cf82828151811061198f5761198f613bd2565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060050161266490919063ffffffff16565b50600101611971565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff00000000000000000000000000000000000000000090811682556001820183905560028201805490911690556003810182905590611a41600483018261350a565b6005820160008181611a538282613544565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d85991694506020019250611a95915050565b60405180910390a150506001016118bd565b5060005b81811015611dbd576000838383818110611ac757611ac7613bd2565b9050602002810190611ad99190614035565b611ae290614112565b9050611af38160600151600061280c565b611b028160800151600061280c565b806040015151600003611b41576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051611b599060059067ffffffffffffffff16612949565b611b9e5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161080d565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a909102999093161717909416959095179092559092029091176003820155908201516004820190611d21908261421a565b5060005b826020015151811015611d6557611d5d836000015184602001518381518110611d5057611d50613bd2565b60200260200101516123d1565b600101611d25565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c28260000151836040015184606001518560800151604051611dab9493929190614334565b60405180910390a15050600101611aab565b5050505050565b611dcc611dd8565b611dd581612955565b50565b60015473ffffffffffffffffffffffffffffffffffffffff163314611e29576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b611e3e61032060a08301608084016136c7565b611e9d57611e5260a08201608083016136c7565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161080d565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb611ee96040840160208501613873565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611f5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f7e9190613efe565b15611fb5576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611fcd611fc86040830160208401613873565b612a19565b611fed611fe06040830160208401613873565b6103c060a0840184613d16565b61203257611ffe60a0820182613d16565b6040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161080d929190613f74565b611dd56120456040830160208401613873565b8260600135612b3f565b600482015163ffffffff81161561209a576040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff8216600482015260240161080d565b6008830151600c8401516014850151602085015163ffffffff8085169116146121055760208501516040517fe366a11700000000000000000000000000000000000000000000000000000000815263ffffffff9182166004820152908416602482015260440161080d565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff161461219a576040517f77e4802600000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301528316602482015260440161080d565b845167ffffffffffffffff8281169116146121f85784516040517ff917ffea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9182166004820152908216602482015260440161080d565b505050505050565b600081815260018301602052604081205415155b9392505050565b7f0000000000000000000000000000000000000000000000000000000000000000612272576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561230857600083828151811061229257612292613bd2565b602002602001015190506122b0816002612b8690919063ffffffff16565b156122ff5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101612275565b5060005b8151811015610d0c57600082828151811061232957612329613bd2565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361236d57506123c9565b612378600282612ba8565b156123c75760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010161230c565b805160000361240c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff841660009081526007909252604090912061243e9060050182612949565b6124785782826040517f393b8ad200000000000000000000000000000000000000000000000000000000815260040161080d9291906143cd565b6000818152600860205260409020612490838261421a565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea8360405161143e9190613692565b6124de61032060a08301608084016136c7565b6124f257611e5260a08201608083016136c7565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb61253e6040840160208501613873565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa1580156125af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d39190613efe565b1561260a576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61262261261d60608301604084016136c7565b612bca565b61263a6126356040830160208401613873565b612c49565b611dd561264d6040830160208401613873565b8260600135612d97565b6060600061221483612ddb565b60006122148383612e36565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526126fe82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426126e2919061441f565b85608001516fffffffffffffffffffffffffffffffff16612f29565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61272b83610e60565b61276d576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161080d565b61277882600061280c565b67ffffffffffffffff8316600090815260076020526040902061279b9083612f51565b6127a681600061280c565b67ffffffffffffffff831660009081526007602052604090206127cc9060020182612f51565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516127ff93929190614432565b60405180910390a1505050565b8151156128d75781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612862575060408201516fffffffffffffffffffffffffffffffff16155b1561289b57816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161080d91906144b5565b80156128d3576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580612910575060208201516fffffffffffffffffffffffffffffffff1615155b156128d357816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161080d91906144b5565b600061221483836130f3565b3373ffffffffffffffffffffffffffffffffffffffff8216036129a4576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b612a2281610e60565b612a64576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161080d565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612ae3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b079190613efe565b611dd5576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161080d565b67ffffffffffffffff821660009081526007602052604090206128d390600201827f0000000000000000000000000000000000000000000000000000000000000000613142565b60006122148373ffffffffffffffffffffffffffffffffffffffff8416612e36565b60006122148373ffffffffffffffffffffffffffffffffffffffff84166130f3565b7f000000000000000000000000000000000000000000000000000000000000000015611dd557612bfb6002826134c5565b611dd5576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161080d565b612c5281610e60565b612c94576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161080d565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612d0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d3191906144f1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611dd5576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161080d565b67ffffffffffffffff821660009081526007602052604090206128d390827f0000000000000000000000000000000000000000000000000000000000000000613142565b6060816000018054806020026020016040519081016040528092919081815260200182805480156115c457602002820191906000526020600020905b815481526020019060010190808311612e175750505050509050919050565b60008181526001830160205260408120548015612f1f576000612e5a60018361441f565b8554909150600090612e6e9060019061441f565b9050808214612ed3576000866000018281548110612e8e57612e8e613bd2565b9060005260206000200154905080876000018481548110612eb157612eb1613bd2565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612ee457612ee461450e565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506109c9565b60009150506109c9565b6000612f4885612f39848661453d565b612f439087614554565b6134f4565b95945050505050565b8154600090612f7a90700100000000000000000000000000000000900463ffffffff164261441f565b9050801561301c5760018301548354612fc2916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612f29565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354613042916fffffffffffffffffffffffffffffffff90811691166134f4565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906127ff9084906144b5565b600081815260018301602052604081205461313a575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556109c9565b5060006109c9565b825474010000000000000000000000000000000000000000900460ff161580613169575081155b1561317357505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906131b990700100000000000000000000000000000000900463ffffffff164261441f565b9050801561327957818311156131fb576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546132359083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612f29565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156133305773ffffffffffffffffffffffffffffffffffffffff84166132d8576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161080d565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161080d565b848310156134435760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290613374908261441f565b61337e878a61441f565b6133889190614554565b6133929190614567565b905073ffffffffffffffffffffffffffffffffffffffff86166133eb576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161080d565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161080d565b61344d858461441f565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515612214565b60008183106135035781612214565b5090919050565b50805461351690613fbe565b6000825580601f10613526575050565b601f016020900490600052602060002090810190611dd5919061355e565b5080546000825590600052602060002090810190611dd591905b5b80821115613573576000815560010161355f565b5090565b6000806020838503121561358a57600080fd5b823567ffffffffffffffff808211156135a257600080fd5b818501915085601f8301126135b657600080fd5b8135818111156135c557600080fd5b8660208260071b85010111156135da57600080fd5b60209290920196919550909350505050565b6000602082840312156135fe57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461221457600080fd5b6000815180845260005b8181101561365457602081850181015186830182015201613638565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000612214602083018461362e565b73ffffffffffffffffffffffffffffffffffffffff81168114611dd557600080fd5b6000602082840312156136d957600080fd5b8135612214816136a5565b6000602082840312156136f657600080fd5b813567ffffffffffffffff81111561370d57600080fd5b8201610100818503121561221457600080fd5b67ffffffffffffffff81168114611dd557600080fd5b60008060006040848603121561374b57600080fd5b833561375681613720565b9250602084013567ffffffffffffffff8082111561377357600080fd5b818601915086601f83011261378757600080fd5b81358181111561379657600080fd5b8760208285010111156137a857600080fd5b6020830194508093505050509250925092565b60008083601f8401126137cd57600080fd5b50813567ffffffffffffffff8111156137e557600080fd5b6020830191508360208260051b850101111561380057600080fd5b9250929050565b6000806000806040858703121561381d57600080fd5b843567ffffffffffffffff8082111561383557600080fd5b613841888389016137bb565b9096509450602087013591508082111561385a57600080fd5b50613867878288016137bb565b95989497509550505050565b60006020828403121561388557600080fd5b813561221481613720565b6000602082840312156138a257600080fd5b813567ffffffffffffffff8111156138b957600080fd5b820160a0818503121561221457600080fd5b6020815260008251604060208401526138e7606084018261362e565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612f48828261362e565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015613997577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261398585835161362e565b9450928501929085019060010161394b565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b818110156139f257835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016139c0565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156139f257835167ffffffffffffffff1683529284019291840191600101613a1a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715613a9257613a92613a40565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613adf57613adf613a40565b604052919050565b8015158114611dd557600080fd5b80356fffffffffffffffffffffffffffffffff81168114613b1557600080fd5b919050565b600060608284031215613b2c57600080fd5b6040516060810181811067ffffffffffffffff82111715613b4f57613b4f613a40565b6040529050808235613b6081613ae7565b8152613b6e60208401613af5565b6020820152613b7f60408401613af5565b60408201525092915050565b600080600060e08486031215613ba057600080fd5b8335613bab81613720565b9250613bba8560208601613b1a565b9150613bc98560808601613b1a565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b803563ffffffff81168114613b1557600080fd5b600060808284031215613c2757600080fd5b6040516080810181811067ffffffffffffffff82111715613c4a57613c4a613a40565b60405282358152613c5d60208401613c01565b60208201526040830135613c7081613720565b60408201526060830135613c8381613ae7565b60608201529392505050565b6020808252818101839052600090604080840186845b87811015613d09578135835263ffffffff613cc1868401613c01565b168584015283820135613cd381613720565b67ffffffffffffffff1683850152606082810135613cf081613ae7565b1515908401526080928301929190910190600101613ca5565b5090979650505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613d4b57600080fd5b83018035915067ffffffffffffffff821115613d6657600080fd5b60200191503681900382131561380057600080fd5b600060408284031215613d8d57600080fd5b613d95613a6f565b8235613da081613720565b8152613dae60208401613c01565b60208201529392505050565b600082601f830112613dcb57600080fd5b813567ffffffffffffffff811115613de557613de5613a40565b613e1660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613a98565b818152846020838601011115613e2b57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215613e5a57600080fd5b813567ffffffffffffffff80821115613e7257600080fd5b9083019060408286031215613e8657600080fd5b613e8e613a6f565b823582811115613e9d57600080fd5b613ea987828601613dba565b825250602083013582811115613ebe57600080fd5b613eca87828601613dba565b60208301525095945050505050565b604081526000613eec604083018561362e565b8281036020840152612f48818561362e565b600060208284031215613f1057600080fd5b815161221481613ae7565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000610bf6602083018486613f2b565b600060208284031215613f9a57600080fd5b5035919050565b600060208284031215613fb357600080fd5b815161221481613720565b600181811c90821680613fd257607f821691505b60208210810361400b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b67ffffffffffffffff84168152604060208201526000612f48604083018486613f2b565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee183360301811261406957600080fd5b9190910192915050565b600082601f83011261408457600080fd5b8135602067ffffffffffffffff808311156140a1576140a1613a40565b8260051b6140b0838201613a98565b93845285810183019383810190888611156140ca57600080fd5b84880192505b85831015614106578235848111156140e85760008081fd5b6140f68a87838c0101613dba565b83525091840191908401906140d0565b98975050505050505050565b6000610120823603121561412557600080fd5b60405160a0810167ffffffffffffffff828210818311171561414957614149613a40565b816040528435915061415a82613720565b9082526020840135908082111561417057600080fd5b61417c36838701614073565b6020840152604085013591508082111561419557600080fd5b506141a236828601613dba565b6040830152506141b53660608501613b1a565b60608201526141c73660c08501613b1a565b608082015292915050565b601f821115610d0c576000816000526020600020601f850160051c810160208610156141fb5750805b601f850160051c820191505b818110156121f857828155600101614207565b815167ffffffffffffffff81111561423457614234613a40565b614248816142428454613fbe565b846141d2565b602080601f83116001811461429b57600084156142655750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556121f8565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156142e8578886015182559484019460019091019084016142c9565b508582101561432457878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526143588184018761362e565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506143969050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612f48565b67ffffffffffffffff83168152604060208201526000610bf6604083018461362e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109c9576109c96143f0565b67ffffffffffffffff8416815260e0810161447e60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152610bf6565b606081016109c982848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561450357600080fd5b8151612214816136a5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b80820281158282048414176109c9576109c96143f0565b808201808211156109c9576109c96143f0565b60008261459d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expected\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"actual\",\"type\":\"uint8\"}],\"name\":\"InvalidDecimalArgs\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidDestinationDomain\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate\",\"name\":\"domain\",\"type\":\"tuple\"}],\"name\":\"InvalidDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidMessageVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"}],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"}],\"name\":\"InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidSourceDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidTokenMessengerVersion\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MismatchedArrayLengths\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"remoteDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"localDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"remoteAmount\",\"type\":\"uint256\"}],\"name\":\"OverflowDetected\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"domain\",\"type\":\"uint64\"}],\"name\":\"UnknownDomain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnlockingUSDCFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"DomainsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"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\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUPPORTED_USDC_VERSION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getDomain\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.Domain\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_localDomainIdentifier\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_messageTransmitter\",\"outputs\":[{\"internalType\":\"contractIMessageTransmitter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_tokenMessenger\",\"outputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectors\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config[]\",\"name\":\"outboundConfigs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config[]\",\"name\":\"inboundConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setChainRateLimiterConfigs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"domains\",\"type\":\"tuple[]\"}],\"name\":\"setDomains\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"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: "0x6101606040523480156200001257600080fd5b506040516200573a3803806200573a833981016040819052620000359162000b93565b836006848484336000816200005d57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200009057620000908162000493565b50506001600160a01b0385161580620000b057506001600160a01b038116155b80620000c357506001600160a01b038216155b15620000e2576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808616608081905290831660c0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa92505050801562000152575060408051601f3d908101601f191682019092526200014f9181019062000cb9565b60015b1562000193578060ff168560ff161462000191576040516332ad3e0760e11b815260ff8087166004830152821660248201526044015b60405180910390fd5b505b60ff841660a052600480546001600160a01b0319166001600160a01b038316179055825115801560e052620001dd57604080516000815260208101909152620001dd90846200050d565b5050506001600160a01b03871691506200020c9050576040516306b7c75960e31b815260040160405180910390fd5b6000856001600160a01b0316632c1219216040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200024d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000273919062000ce5565b90506000816001600160a01b03166354fd4d506040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002b6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002dc919062000d05565b905063ffffffff8116156200030d576040516334697c6b60e11b815263ffffffff8216600482015260240162000188565b6000876001600160a01b0316639cdbb1816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200034e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000374919062000d05565b905063ffffffff811615620003a5576040516316ba39c560e31b815263ffffffff8216600482015260240162000188565b6001600160a01b038089166101005283166101208190526040805163234d8e3d60e21b81529051638d3638f4916004808201926020929091908290030181865afa158015620003f8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200041e919062000d05565b63ffffffff16610140526101005160805162000449916001600160a01b03909116906000196200066a565b6040516001600160a01b03891681527f2e902d38f15b233cbb63711add0fca4545334d3a169d60c0a616494d7eea95449060200160405180910390a1505050505050505062000e52565b336001600160a01b03821603620004bd57604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e0516200052e576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620005b957600083828151811062000552576200055262000d2d565b602090810291909101015190506200056c60028262000750565b15620005af576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000531565b5060005b815181101562000665576000828281518110620005de57620005de62000d2d565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200060a57506200065c565b6200061760028262000770565b156200065a576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101620005bd565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015620006bc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620006e2919062000d43565b620006ee919062000d73565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200074a918691906200078716565b50505050565b600062000767836001600160a01b03841662000858565b90505b92915050565b600062000767836001600160a01b0384166200095c565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490820152600090620007d6906001600160a01b038516908490620009ae565b805190915015620006655780806020019051810190620007f7919062000d89565b620006655760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000188565b60008181526001830160205260408120548015620009515760006200087f60018362000dad565b8554909150600090620008959060019062000dad565b905080821462000901576000866000018281548110620008b957620008b962000d2d565b9060005260206000200154905080876000018481548110620008df57620008df62000d2d565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000915576200091562000dc3565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200076a565b60009150506200076a565b6000818152600183016020526040812054620009a5575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200076a565b5060006200076a565b6060620009bf8484600085620009c7565b949350505050565b60608247101562000a2a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000188565b600080866001600160a01b0316858760405162000a48919062000dff565b60006040518083038185875af1925050503d806000811462000a87576040519150601f19603f3d011682016040523d82523d6000602084013e62000a8c565b606091505b50909250905062000aa08783838762000aab565b979650505050505050565b6060831562000b1f57825160000362000b17576001600160a01b0385163b62000b175760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000188565b5081620009bf565b620009bf838381511562000b365781518083602001fd5b8060405162461bcd60e51b815260040162000188919062000e1d565b6001600160a01b038116811462000b6857600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000b8e8162000b52565b919050565b600080600080600060a0868803121562000bac57600080fd5b855162000bb98162000b52565b8095505060208087015162000bce8162000b52565b60408801519095506001600160401b038082111562000bec57600080fd5b818901915089601f83011262000c0157600080fd5b81518181111562000c165762000c1662000b6b565b8060051b604051601f19603f8301168101818110858211171562000c3e5762000c3e62000b6b565b60405291825284820192508381018501918c83111562000c5d57600080fd5b938501935b8285101562000c865762000c768562000b81565b8452938501939285019262000c62565b80985050505050505062000c9d6060870162000b81565b915062000cad6080870162000b81565b90509295509295909350565b60006020828403121562000ccc57600080fd5b815160ff8116811462000cde57600080fd5b9392505050565b60006020828403121562000cf857600080fd5b815162000cde8162000b52565b60006020828403121562000d1857600080fd5b815163ffffffff8116811462000cde57600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000d5657600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156200076a576200076a62000d5d565b60006020828403121562000d9c57600080fd5b8151801515811462000cde57600080fd5b818103818111156200076a576200076a62000d5d565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000df657818101518382015260200162000ddc565b50506000910152565b6000825162000e1381846020870162000dd9565b9190910192915050565b602081526000825180602084015262000e3e81604085016020870162000dd9565b601f01601f19169190910160400192915050565b60805160a05160c05160e05161010051610120516101405161483262000f0860003960008181610432015281816112c40152818161228f01526122ed0152600081816107590152610aa30152600081816103f801526111da01526000818161070a015281816123a50152612ef60152600081816106460152818161203c015261277b015260006103810152600081816102e80152818161033d015281816111a401528181612cea01526130e101526148326000f3fe608060405234801561001057600080fd5b506004361061025b5760003560e01c80639a4575b911610145578063c4bffe2b116100bd578063dfadfa351161008c578063e8a1da1711610071578063e8a1da171461072e578063f2fde38b14610741578063fbf84dd71461075457600080fd5b8063dfadfa351461066a578063e0351e131461070857600080fd5b8063c4bffe2b14610609578063c75eea9c1461061e578063cf7401f314610631578063dc0bd9711461064457600080fd5b8063acfecf9111610114578063b0f479a1116100f9578063b0f479a1146105c5578063b7946580146105e3578063c0d78655146105f657600080fd5b8063acfecf9114610543578063af58d59f1461055657600080fd5b80639a4575b9146104e65780639fdf13ff14610506578063a42a7b8b1461050e578063a7cd63b71461052e57600080fd5b80636155cda0116101d857806379ba5097116101a75780638926f54f1161018c5780638926f54f146104a25780638da5cb5b146104b5578063962d4020146104d357600080fd5b806379ba5097146104875780637d54534e1461048f57600080fd5b80636155cda0146103f357806362ddd3c41461041a5780636b716b0d1461042d5780636d3d1a581461046957600080fd5b8063240028e81161022f578063390775371161021457806339077537146103ab5780634c5ef0ed146103cd57806354c8a4f3146103e057600080fd5b8063240028e81461032d57806324f65ee71461037a57600080fd5b806241d3c11461026057806301ffc9a714610275578063181f5a771461029d57806321df0da7146102e6575b600080fd5b61027361026e3660046136ff565b61077b565b005b610288610283366004613774565b610918565b60405190151581526020015b60405180910390f35b6102d96040518060400160405280601381526020017f55534443546f6b656e506f6f6c20312e352e310000000000000000000000000081525081565b604051610294919061381a565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610294565b61028861033b36600461384f565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610294565b6103be6103b936600461386c565b6109fd565b60405190518152602001610294565b6102886103db3660046138be565b610be2565b6102736103ee36600461398f565b610c2c565b6103087f000000000000000000000000000000000000000000000000000000000000000081565b6102736104283660046138be565b610ca7565b6104547f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610294565b60095473ffffffffffffffffffffffffffffffffffffffff16610308565b610273610d3f565b61027361049d36600461384f565b610e0d565b6102886104b03660046139fb565b610e8e565b60015473ffffffffffffffffffffffffffffffffffffffff16610308565b6102736104e1366004613a5d565b610ea5565b6104f96104f4366004613af7565b610fff565b6040516102949190613b32565b610454600081565b61052161051c3660046139fb565b61133f565b6040516102949190613b89565b6105366114aa565b6040516102949190613c0b565b6102736105513660046138be565b6114bb565b6105696105643660046139fb565b6115d3565b604051610294919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610308565b6102d96105f13660046139fb565b6116a8565b61027361060436600461384f565b611758565b61061161182c565b6040516102949190613c65565b61056961062c3660046139fb565b6118e4565b61027361063f366004613df2565b6119b6565b7f0000000000000000000000000000000000000000000000000000000000000000610308565b6106de6106783660046139fb565b60408051606080820183526000808352602080840182905292840181905267ffffffffffffffff949094168452600a82529282902082519384018352805484526001015463ffffffff811691840191909152640100000000900460ff1615159082015290565b604080518251815260208084015163ffffffff169082015291810151151590820152606001610294565b7f0000000000000000000000000000000000000000000000000000000000000000610288565b61027361073c36600461398f565b611a3a565b61027361074f36600461384f565b611f4c565b6103087f000000000000000000000000000000000000000000000000000000000000000081565b610783611f60565b60005b818110156108da5760008383838181106107a2576107a2613e39565b9050608002018036038101906107b89190613e7c565b805190915015806107d55750604081015167ffffffffffffffff16155b1561084457604080517fa087bd2900000000000000000000000000000000000000000000000000000000815282516004820152602083015163ffffffff1660248201529082015167ffffffffffffffff1660448201526060820151151560648201526084015b60405180910390fd5b60408051606080820183528351825260208085015163ffffffff9081168285019081529286015115158486019081529585015167ffffffffffffffff166000908152600a90925293902091518255516001918201805494511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000909516919093161792909217905501610786565b507f1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee56828260405161090c929190613ef6565b60405180910390a15050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806109ab57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806109f757507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b604080516020810190915260008152610a1582611fb3565b6000610a2460c0840184613f7d565b810190610a319190613fe2565b90506000610a4260e0850185613f7d565b810190610a4f91906140af565b9050610a5f8160000151836121d7565b805160208201516040517f57ecfd2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016926357ecfd2892610ad692600401614140565b6020604051808303816000875af1158015610af5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b199190614165565b610b4f576040517fbf969f2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b5f606085016040860161384f565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08660600135604051610bc191815260200190565b60405180910390a35050604080516020810190915260609092013582525090565b6000610c248383604051610bf7929190614182565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190612388565b949350505050565b610c34611f60565b610ca1848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040805160208088028281018201909352878252909350879250869182918501908490808284376000920191909152506123a392505050565b50505050565b610caf611f60565b610cb883610e8e565b610cfa576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161083b565b610d3a8383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061255992505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d90576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e15611f60565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b60006109f7600567ffffffffffffffff8416612388565b60095473ffffffffffffffffffffffffffffffffffffffff163314801590610ee5575060015473ffffffffffffffffffffffffffffffffffffffff163314155b15610f1e576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161083b565b8483141580610f2d5750848114155b15610f64576040517f568efce200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b85811015610ff657610fee878783818110610f8457610f84613e39565b9050602002016020810190610f9991906139fb565b868684818110610fab57610fab613e39565b905060600201803603810190610fc19190614192565b858585818110610fd357610fd3613e39565b905060600201803603810190610fe99190614192565b612653565b600101610f67565b50505050505050565b604080518082019091526060808252602082015261101c8261273d565b6000600a8161103160408601602087016139fb565b67ffffffffffffffff168152602080820192909252604090810160002081516060810183528154815260019091015463ffffffff81169382019390935264010000000090920460ff1615159082018190529091506110d85761109960408401602085016139fb565b6040517fd201c48a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161083b565b6110e28380613f7d565b9050602014611129576110f58380613f7d565b6040517fa3c8cf0900000000000000000000000000000000000000000000000000000000815260040161083b9291906141f7565b60006111358480613f7d565b810190611142919061420b565b602083015183516040517ff856ddb60000000000000000000000000000000000000000000000000000000081526060880135600482015263ffffffff90921660248301526044820183905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116606484015260848301919091529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063f856ddb69060a4016020604051808303816000875af1158015611223573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112479190614224565b6040516060870135815290915033907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a260405180604001604052806112a48760200160208101906105f191906139fb565b815260408051808201825267ffffffffffffffff851680825263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602093840190815284518085019390935251169281019290925290910190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905295945050505050565b67ffffffffffffffff8116600090815260076020526040812060609190611368906005016128c9565b90506000815167ffffffffffffffff81111561138657611386613ca7565b6040519080825280602002602001820160405280156113b957816020015b60608152602001906001900390816113a45790505b50905060005b82518110156114a257600860008483815181106113de576113de613e39565b6020026020010151815260200190815260200160002080546113ff90614241565b80601f016020809104026020016040519081016040528092919081815260200182805461142b90614241565b80156114785780601f1061144d57610100808354040283529160200191611478565b820191906000526020600020905b81548152906001019060200180831161145b57829003601f168201915b505050505082828151811061148f5761148f613e39565b60209081029190910101526001016113bf565b509392505050565b60606114b660026128c9565b905090565b6114c3611f60565b6114cc83610e8e565b61150e576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161083b565b61154e8282604051611521929190614182565b604080519182900390912067ffffffffffffffff86166000908152600760205291909120600501906128d6565b61158a578282826040517f74f23c7c00000000000000000000000000000000000000000000000000000000815260040161083b93929190614294565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d7683836040516115c69291906141f7565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526109f7906128e2565b67ffffffffffffffff811660009081526007602052604090206004018054606091906116d390614241565b80601f01602080910402602001604051908101604052809291908181526020018280546116ff90614241565b801561174c5780601f106117215761010080835404028352916020019161174c565b820191906000526020600020905b81548152906001019060200180831161172f57829003601f168201915b50505050509050919050565b611760611f60565b73ffffffffffffffffffffffffffffffffffffffff81166117ad576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910161090c565b6060600061183a60056128c9565b90506000815167ffffffffffffffff81111561185857611858613ca7565b604051908082528060200260200182016040528015611881578160200160208202803683370190505b50905060005b82518110156118dd578281815181106118a2576118a2613e39565b60200260200101518282815181106118bc576118bc613e39565b67ffffffffffffffff90921660209283029190910190910152600101611887565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526109f7906128e2565b60095473ffffffffffffffffffffffffffffffffffffffff1633148015906119f6575060015473ffffffffffffffffffffffffffffffffffffffff163314155b15611a2f576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161083b565b610d3a838383612653565b611a42611f60565b60005b83811015611c2f576000858583818110611a6157611a61613e39565b9050602002016020810190611a7691906139fb565b9050611a8d600567ffffffffffffffff83166128d6565b611acf576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161083b565b67ffffffffffffffff81166000908152600760205260408120611af4906005016128c9565b905060005b8151811015611b6057611b57828281518110611b1757611b17613e39565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206005016128d690919063ffffffff16565b50600101611af9565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff00000000000000000000000000000000000000000090811682556001820183905560028201805490911690556003810182905590611bc96004830182613692565b6005820160008181611bdb82826136cc565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d85991694506020019250611c1d915050565b60405180910390a15050600101611a45565b5060005b81811015611f45576000838383818110611c4f57611c4f613e39565b9050602002810190611c6191906142b8565b611c6a90614395565b9050611c7b81606001516000612994565b611c8a81608001516000612994565b806040015151600003611cc9576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051611ce19060059067ffffffffffffffff16612ad1565b611d265780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161083b565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a909102999093161717909416959095179092559092029091176003820155908201516004820190611ea9908261449d565b5060005b826020015151811015611eed57611ee5836000015184602001518381518110611ed857611ed8613e39565b6020026020010151612559565b600101611ead565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c28260000151836040015184606001518560800151604051611f3394939291906145b7565b60405180910390a15050600101611c33565b5050505050565b611f54611f60565b611f5d81612add565b50565b60015473ffffffffffffffffffffffffffffffffffffffff163314611fb1576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b611fc661033b60a083016080840161384f565b61202557611fda60a082016080830161384f565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161083b565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb61207160408401602085016139fb565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa1580156120e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121069190614165565b1561213d576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61215561215060408301602084016139fb565b612ba1565b61217561216860408301602084016139fb565b6103db60a0840184613f7d565b6121ba5761218660a0820182613f7d565b6040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161083b9291906141f7565b611f5d6121cd60408301602084016139fb565b8260600135612cc7565b600482015163ffffffff811615612222576040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff8216600482015260240161083b565b6008830151600c8401516014850151602085015163ffffffff80851691161461228d5760208501516040517fe366a11700000000000000000000000000000000000000000000000000000000815263ffffffff9182166004820152908416602482015260440161083b565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff1614612322576040517f77e4802600000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301528316602482015260440161083b565b845167ffffffffffffffff8281169116146123805784516040517ff917ffea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9182166004820152908216602482015260440161083b565b505050505050565b600081815260018301602052604081205415155b9392505050565b7f00000000000000000000000000000000000000000000000000000000000000006123fa576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561249057600083828151811061241a5761241a613e39565b60200260200101519050612438816002612d0e90919063ffffffff16565b156124875760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016123fd565b5060005b8151811015610d3a5760008282815181106124b1576124b1613e39565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036124f55750612551565b612500600282612d30565b1561254f5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101612494565b8051600003612594576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff84166000908152600790925260409091206125c69060050182612ad1565b6126005782826040517f393b8ad200000000000000000000000000000000000000000000000000000000815260040161083b929190614650565b6000818152600860205260409020612618838261449d565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea836040516115c6919061381a565b61265c83610e8e565b61269e576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161083b565b6126a9826000612994565b67ffffffffffffffff831660009081526007602052604090206126cc9083612d52565b6126d7816000612994565b67ffffffffffffffff831660009081526007602052604090206126fd9060020182612d52565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161273093929190614673565b60405180910390a1505050565b61275061033b60a083016080840161384f565b61276457611fda60a082016080830161384f565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6127b060408401602085016139fb565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015612821573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128459190614165565b1561287c576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61289461288f606083016040840161384f565b612ef4565b6128ac6128a760408301602084016139fb565b612f73565b611f5d6128bf60408301602084016139fb565b82606001356130c1565b6060600061239c83613105565b600061239c8383613160565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261297082606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426129549190614725565b85608001516fffffffffffffffffffffffffffffffff16613253565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b815115612a5f5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806129ea575060408201516fffffffffffffffffffffffffffffffff16155b15612a2357816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161083b9190614738565b8015612a5b576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580612a98575060208201516fffffffffffffffffffffffffffffffff1615155b15612a5b57816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161083b9190614738565b600061239c838361327b565b3373ffffffffffffffffffffffffffffffffffffffff821603612b2c576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b612baa81610e8e565b612bec576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161083b565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612c6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c8f9190614165565b611f5d576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161083b565b67ffffffffffffffff82166000908152600760205260409020612a5b90600201827f00000000000000000000000000000000000000000000000000000000000000006132ca565b600061239c8373ffffffffffffffffffffffffffffffffffffffff8416613160565b600061239c8373ffffffffffffffffffffffffffffffffffffffff841661327b565b8154600090612d7b90700100000000000000000000000000000000900463ffffffff1642614725565b90508015612e1d5760018301548354612dc3916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416613253565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612e43916fffffffffffffffffffffffffffffffff908116911661364d565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612730908490614738565b7f000000000000000000000000000000000000000000000000000000000000000015611f5d57612f25600282613663565b611f5d576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161083b565b612f7c81610e8e565b612fbe576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161083b565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015613037573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061305b9190614774565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f5d576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161083b565b67ffffffffffffffff82166000908152600760205260409020612a5b90827f00000000000000000000000000000000000000000000000000000000000000006132ca565b60608160000180548060200260200160405190810160405280929190818152602001828054801561174c57602002820191906000526020600020905b8154815260200190600101908083116131415750505050509050919050565b60008181526001830160205260408120548015613249576000613184600183614725565b855490915060009061319890600190614725565b90508082146131fd5760008660000182815481106131b8576131b8613e39565b90600052602060002001549050808760000184815481106131db576131db613e39565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061320e5761320e614791565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506109f7565b60009150506109f7565b60006132728561326384866147c0565b61326d90876147d7565b61364d565b95945050505050565b60008181526001830160205260408120546132c2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556109f7565b5060006109f7565b825474010000000000000000000000000000000000000000900460ff1615806132f1575081155b156132fb57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061334190700100000000000000000000000000000000900463ffffffff1642614725565b905080156134015781831115613383576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546133bd9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16613253565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156134b85773ffffffffffffffffffffffffffffffffffffffff8416613460576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161083b565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161083b565b848310156135cb5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906134fc9082614725565b613506878a614725565b61351091906147d7565b61351a91906147ea565b905073ffffffffffffffffffffffffffffffffffffffff8616613573576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161083b565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161083b565b6135d58584614725565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b600081831061365c578161239c565b5090919050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561239c565b50805461369e90614241565b6000825580601f106136ae575050565b601f016020900490600052602060002090810190611f5d91906136e6565b5080546000825590600052602060002090810190611f5d91905b5b808211156136fb57600081556001016136e7565b5090565b6000806020838503121561371257600080fd5b823567ffffffffffffffff8082111561372a57600080fd5b818501915085601f83011261373e57600080fd5b81358181111561374d57600080fd5b8660208260071b850101111561376257600080fd5b60209290920196919550909350505050565b60006020828403121561378657600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461239c57600080fd5b6000815180845260005b818110156137dc576020818501810151868301820152016137c0565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061239c60208301846137b6565b73ffffffffffffffffffffffffffffffffffffffff81168114611f5d57600080fd5b60006020828403121561386157600080fd5b813561239c8161382d565b60006020828403121561387e57600080fd5b813567ffffffffffffffff81111561389557600080fd5b8201610100818503121561239c57600080fd5b67ffffffffffffffff81168114611f5d57600080fd5b6000806000604084860312156138d357600080fd5b83356138de816138a8565b9250602084013567ffffffffffffffff808211156138fb57600080fd5b818601915086601f83011261390f57600080fd5b81358181111561391e57600080fd5b87602082850101111561393057600080fd5b6020830194508093505050509250925092565b60008083601f84011261395557600080fd5b50813567ffffffffffffffff81111561396d57600080fd5b6020830191508360208260051b850101111561398857600080fd5b9250929050565b600080600080604085870312156139a557600080fd5b843567ffffffffffffffff808211156139bd57600080fd5b6139c988838901613943565b909650945060208701359150808211156139e257600080fd5b506139ef87828801613943565b95989497509550505050565b600060208284031215613a0d57600080fd5b813561239c816138a8565b60008083601f840112613a2a57600080fd5b50813567ffffffffffffffff811115613a4257600080fd5b60208301915083602060608302850101111561398857600080fd5b60008060008060008060608789031215613a7657600080fd5b863567ffffffffffffffff80821115613a8e57600080fd5b613a9a8a838b01613943565b90985096506020890135915080821115613ab357600080fd5b613abf8a838b01613a18565b90965094506040890135915080821115613ad857600080fd5b50613ae589828a01613a18565b979a9699509497509295939492505050565b600060208284031215613b0957600080fd5b813567ffffffffffffffff811115613b2057600080fd5b820160a0818503121561239c57600080fd5b602081526000825160406020840152613b4e60608401826137b6565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301604085015261327282826137b6565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015613bfe577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452613bec8583516137b6565b94509285019290850190600101613bb2565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613c5957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613c27565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613c5957835167ffffffffffffffff1683529284019291840191600101613c81565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715613cf957613cf9613ca7565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613d4657613d46613ca7565b604052919050565b8015158114611f5d57600080fd5b80356fffffffffffffffffffffffffffffffff81168114613d7c57600080fd5b919050565b600060608284031215613d9357600080fd5b6040516060810181811067ffffffffffffffff82111715613db657613db6613ca7565b6040529050808235613dc781613d4e565b8152613dd560208401613d5c565b6020820152613de660408401613d5c565b60408201525092915050565b600080600060e08486031215613e0757600080fd5b8335613e12816138a8565b9250613e218560208601613d81565b9150613e308560808601613d81565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b803563ffffffff81168114613d7c57600080fd5b600060808284031215613e8e57600080fd5b6040516080810181811067ffffffffffffffff82111715613eb157613eb1613ca7565b60405282358152613ec460208401613e68565b60208201526040830135613ed7816138a8565b60408201526060830135613eea81613d4e565b60608201529392505050565b6020808252818101839052600090604080840186845b87811015613f70578135835263ffffffff613f28868401613e68565b168584015283820135613f3a816138a8565b67ffffffffffffffff1683850152606082810135613f5781613d4e565b1515908401526080928301929190910190600101613f0c565b5090979650505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613fb257600080fd5b83018035915067ffffffffffffffff821115613fcd57600080fd5b60200191503681900382131561398857600080fd5b600060408284031215613ff457600080fd5b613ffc613cd6565b8235614007816138a8565b815261401560208401613e68565b60208201529392505050565b600082601f83011261403257600080fd5b813567ffffffffffffffff81111561404c5761404c613ca7565b61407d60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613cff565b81815284602083860101111561409257600080fd5b816020850160208301376000918101602001919091529392505050565b6000602082840312156140c157600080fd5b813567ffffffffffffffff808211156140d957600080fd5b90830190604082860312156140ed57600080fd5b6140f5613cd6565b82358281111561410457600080fd5b61411087828601614021565b82525060208301358281111561412557600080fd5b61413187828601614021565b60208301525095945050505050565b60408152600061415360408301856137b6565b828103602084015261327281856137b6565b60006020828403121561417757600080fd5b815161239c81613d4e565b8183823760009101908152919050565b6000606082840312156141a457600080fd5b61239c8383613d81565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000610c246020830184866141ae565b60006020828403121561421d57600080fd5b5035919050565b60006020828403121561423657600080fd5b815161239c816138a8565b600181811c9082168061425557607f821691505b60208210810361428e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b67ffffffffffffffff841681526040602082015260006132726040830184866141ae565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee18336030181126142ec57600080fd5b9190910192915050565b600082601f83011261430757600080fd5b8135602067ffffffffffffffff8083111561432457614324613ca7565b8260051b614333838201613cff565b938452858101830193838101908886111561434d57600080fd5b84880192505b858310156143895782358481111561436b5760008081fd5b6143798a87838c0101614021565b8352509184019190840190614353565b98975050505050505050565b600061012082360312156143a857600080fd5b60405160a0810167ffffffffffffffff82821081831117156143cc576143cc613ca7565b81604052843591506143dd826138a8565b908252602084013590808211156143f357600080fd5b6143ff368387016142f6565b6020840152604085013591508082111561441857600080fd5b5061442536828601614021565b6040830152506144383660608501613d81565b606082015261444a3660c08501613d81565b608082015292915050565b601f821115610d3a576000816000526020600020601f850160051c8101602086101561447e5750805b601f850160051c820191505b818110156123805782815560010161448a565b815167ffffffffffffffff8111156144b7576144b7613ca7565b6144cb816144c58454614241565b84614455565b602080601f83116001811461451e57600084156144e85750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555612380565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561456b5788860151825594840194600190910190840161454c565b50858210156145a757878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526145db818401876137b6565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506146199050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613272565b67ffffffffffffffff83168152604060208201526000610c2460408301846137b6565b67ffffffffffffffff8416815260e081016146bf60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152610c24565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109f7576109f76146f6565b606081016109f782848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561478657600080fd5b815161239c8161382d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b80820281158282048414176109f7576109f76146f6565b808201808211156109f7576109f76146f6565b600082614820577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", } var USDCTokenPoolABI = USDCTokenPoolMetaData.ABI @@ -836,6 +836,18 @@ func (_USDCTokenPool *USDCTokenPoolTransactorSession) SetChainRateLimiterConfig( return _USDCTokenPool.Contract.SetChainRateLimiterConfig(&_USDCTokenPool.TransactOpts, remoteChainSelector, outboundConfig, inboundConfig) } +func (_USDCTokenPool *USDCTokenPoolTransactor) SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "setChainRateLimiterConfigs", remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_USDCTokenPool *USDCTokenPoolSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _USDCTokenPool.Contract.SetChainRateLimiterConfigs(&_USDCTokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) SetChainRateLimiterConfigs(remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) { + return _USDCTokenPool.Contract.SetChainRateLimiterConfigs(&_USDCTokenPool.TransactOpts, remoteChainSelectors, outboundConfigs, inboundConfigs) +} + func (_USDCTokenPool *USDCTokenPoolTransactor) SetDomains(opts *bind.TransactOpts, domains []USDCTokenPoolDomainUpdate) (*types.Transaction, error) { return _USDCTokenPool.contract.Transact(opts, "setDomains", domains) } @@ -3424,6 +3436,8 @@ type USDCTokenPoolInterface interface { SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) + SetChainRateLimiterConfigs(opts *bind.TransactOpts, remoteChainSelectors []uint64, outboundConfigs []RateLimiterConfig, inboundConfigs []RateLimiterConfig) (*types.Transaction, error) + SetDomains(opts *bind.TransactOpts, domains []USDCTokenPoolDomainUpdate) (*types.Transaction, error) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 7ace8c949a8..95a62aad83b 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,13 +1,13 @@ GETH_VERSION: 1.14.11 -burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin 642919607d5642aa98713b88f737c918487adba682535cf630b7c7d5fd80dc43 -burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 054d95f302a142f7b64eea27237e0889bee6c9eb8a487579c7279c09646dc42b -burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin c3f723e7f6394297c095a9d9696f1bceec4a2e85b5be2159f7a21d257eb6b480 +burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin 76c31f52fe1df85528c08b2e772e37dcf99ca1ec492d83a221abc1d5ec833694 +burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 1c78cd3118b3c9ca82f8cb77ffc1137619ea4e8e503c460f2dafb659d0dd766b +burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin eab9c19ef27b245e5ef0216ab1080c9dd89c96013b7dc978bf610288d5e82b00 ccip_encoding_utils: ../../../contracts/solc/v0.8.24/ICCIPEncodingUtils/ICCIPEncodingUtils.abi ../../../contracts/solc/v0.8.24/ICCIPEncodingUtils/ICCIPEncodingUtils.bin 9971fc93c34442a0989570d3dab90a125de31e6e60754ad972807ce6ad4dfba0 -ccip_home: ../../../contracts/solc/v0.8.24/CCIPHome/CCIPHome.abi ../../../contracts/solc/v0.8.24/CCIPHome/CCIPHome.bin 02cb75b4274a5be7f4006cf2b72cc09e77eb6dba4c1a9c720af86668ff8ea1df +ccip_home: ../../../contracts/solc/v0.8.24/CCIPHome/CCIPHome.abi ../../../contracts/solc/v0.8.24/CCIPHome/CCIPHome.bin 865bc25c54cf346e5f519dc3fb625260a12c80983b5ba2dcea63519a7befc660 ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin b368699ae7dbee7c21d049a641642837f18ce2cc8d4ece69509f205de673108e ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de fee_quoter: ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.abi ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.bin aee49c9246d5903e68b175516b3cdfdec5df23e25d53d604cd382b6bc0bf34f7 -lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin 1067f557abeb5570f1da7f050ea982ffad0f35dc064e668a8a0e6af128df490c +lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin 04b40584830294fb603cc2a250af7d831d05a04650a8c2fc9e3af5a78c471be6 maybe_revert_message_receiver: ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin d73956c26232ebcc4a5444429fa99cbefed960e323be9b5a24925885c2e477d5 message_hasher: ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.abi ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.bin ec2d3a92348d8e7b8f0d359b62a45157b9d2c750c01fbcf991826c4392f6e218 mock_usdc_token_messenger: ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.bin d976651d36b33ac2196b32b9d2f4fa6690c6a18d41b621365659fce1c1d1e737 @@ -16,7 +16,7 @@ mock_v3_aggregator_contract: ../../../contracts/solc/v0.8.24/MockV3Aggregator/Mo multi_aggregate_rate_limiter: ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.abi ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.bin c3cac2010c2815b484055bf981363a2bd04e7fbe7bb502dc8fd29a16165d221c multi_ocr3_helper: ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.abi ../../../contracts/solc/v0.8.24/MultiOCR3Helper/MultiOCR3Helper.bin a523e11ea4c069d7d61b309c156951cc6834aff0f352bd1ac37c3a838ff2588f nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin e6008490d916826cefd1903612db39621d51617300fc9bb42b68c6c117958198 -offramp: ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.abi ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.bin 7c65e586181c5099a6ecb5353f60043bb6add9ebad941ddf7ef9998c7ee008ea +offramp: ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.abi ../../../contracts/solc/v0.8.24/OffRamp/OffRamp.bin 067fdfbf7cae1557fc03ca16d9c38737ee4595655792a1b8bc4846c45caa0c74 onramp: ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.abi ../../../contracts/solc/v0.8.24/OnRamp/OnRamp.bin 2bf74188a997218502031f177cb2df505b272d66b25fd341a741289e77380c59 ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin 24b4415a883a470d65c484be0fa20714a46b1c9262db205f1c958017820307b2 registry_module_owner_custom: ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.abi ../../../contracts/solc/v0.8.24/RegistryModuleOwnerCustom/RegistryModuleOwnerCustom.bin 0fc277a0b512db4e20b5a32a775b94ed2c0d342d8237511de78c94f7dacad428 @@ -26,7 +26,7 @@ rmn_proxy_contract: ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../ rmn_remote: ../../../contracts/solc/v0.8.24/RMNRemote/RMNRemote.abi ../../../contracts/solc/v0.8.24/RMNRemote/RMNRemote.bin 2bf58225d1ceec21f3dd9e65b8088945c643ec527ae54b9983ec46316f5bca1f router: ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin 2e4f0a7826c8abb49d882bb49fc5ff20a186dbd3137624b9097ffed903ae4888 token_admin_registry: ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin 397bc7be08c2848c0f4715f90b16206d6367f78ffb7cd48e2b1dfc0ccc5aea26 -token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin da86a1407f31134e7246bde63c80ce8c78ce7d7b44e267f3c1f6030441ff4252 +token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin 793d65f336929becdcf8bc3f2208a5b6de93774215fe2e863bef64df419cfdb0 usdc_reader_tester: ../../../contracts/solc/v0.8.24/USDCReaderTester/USDCReaderTester.abi ../../../contracts/solc/v0.8.24/USDCReaderTester/USDCReaderTester.bin 672a07c9218fd6ad7c04dde583088b0f5ffc8d55a46f4be1714008dd3409438b -usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin b688126b13353f7aab7481f3f6b8f79cd2cace96be71eace70237d402823493a +usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin a9fef4db2c901302c0293b139eb77017b18da8543b7623e17f2932efbb8e3011 weth9: ../../../contracts/solc/v0.8.24/WETH9/WETH9.abi ../../../contracts/solc/v0.8.24/WETH9/WETH9.bin 2970d79a0ca6dd6279cde130de45e56c8790ed695eae477fb5ba4c1bb75b720d diff --git a/core/gethwrappers/workflow/generated/workflow_registry_wrapper/workflow_registry_wrapper.go b/core/gethwrappers/workflow/generated/workflow_registry_wrapper/workflow_registry_wrapper.go index c87f59c0e7b..a81d69c343e 100644 --- a/core/gethwrappers/workflow/generated/workflow_registry_wrapper/workflow_registry_wrapper.go +++ b/core/gethwrappers/workflow/generated/workflow_registry_wrapper/workflow_registry_wrapper.go @@ -43,7 +43,7 @@ type WorkflowRegistryWorkflowMetadata struct { var WorkflowRegistryMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AddressNotAuthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotWorkflowOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"}],\"name\":\"DONNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWorkflowID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryLocked\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"providedLength\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"maxAllowedLength\",\"type\":\"uint8\"}],\"name\":\"URLTooLong\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WorkflowAlreadyInDesiredStatus\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WorkflowAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WorkflowContentNotUpdated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WorkflowDoesNotExist\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WorkflowIDAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WorkflowIDNotUpdated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"providedLength\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"maxAllowedLength\",\"type\":\"uint8\"}],\"name\":\"WorkflowNameTooLong\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32[]\",\"name\":\"donIDs\",\"type\":\"uint32[]\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"AllowedDONsUpdatedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"AuthorizedAddressesUpdatedV1\",\"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\":\"lockedBy\",\"type\":\"address\"}],\"name\":\"RegistryLockedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"unlockedBy\",\"type\":\"address\"}],\"name\":\"RegistryUnlockedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"}],\"name\":\"WorkflowActivatedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"}],\"name\":\"WorkflowDeletedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"secretsURLHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"}],\"name\":\"WorkflowForceUpdateSecretsRequestedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"}],\"name\":\"WorkflowPausedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"enumWorkflowRegistry.WorkflowStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"name\":\"WorkflowRegisteredV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"oldWorkflowID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"newWorkflowID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"name\":\"WorkflowUpdatedV1\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"workflowKey\",\"type\":\"bytes32\"}],\"name\":\"activateWorkflow\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"field\",\"type\":\"string\"}],\"name\":\"computeHashKey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"workflowKey\",\"type\":\"bytes32\"}],\"name\":\"deleteWorkflow\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAllowedDONs\",\"outputs\":[{\"internalType\":\"uint32[]\",\"name\":\"allowedDONs\",\"type\":\"uint32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"authorizedAddresses\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"}],\"name\":\"getWorkflowMetadata\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"internalType\":\"enumWorkflowRegistry.WorkflowStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"internalType\":\"structWorkflowRegistry.WorkflowMetadata\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"start\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"getWorkflowMetadataListByDON\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"internalType\":\"enumWorkflowRegistry.WorkflowStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"internalType\":\"structWorkflowRegistry.WorkflowMetadata[]\",\"name\":\"workflowMetadataList\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"start\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"getWorkflowMetadataListByOwner\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"internalType\":\"enumWorkflowRegistry.WorkflowStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"internalType\":\"structWorkflowRegistry.WorkflowMetadata[]\",\"name\":\"workflowMetadataList\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isRegistryLocked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lockRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"workflowKey\",\"type\":\"bytes32\"}],\"name\":\"pauseWorkflow\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"},{\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"internalType\":\"enumWorkflowRegistry.WorkflowStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"name\":\"registerWorkflow\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"name\":\"requestForceUpdateSecrets\",\"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\"},{\"inputs\":[],\"name\":\"unlockRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"donIDs\",\"type\":\"uint32[]\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"updateAllowedDONs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"updateAuthorizedAddresses\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"workflowKey\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"newWorkflowID\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"name\":\"updateWorkflow\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6080806040523461004a57331561003b57600180546001600160a01b03191633179055600a805460ff191690556040516133f390816100508239f35b639b15e16f60e01b8152600490fd5b600080fdfe6080604052600436101561001257600080fd5b60003560e01c806308e7f63a14612096578063181f5a77146120075780632303348a14611eca5780632b596f6d14611e3c5780633ccd14ff14611502578063695e13401461135a5780636f35177114611281578063724c13dd1461118a5780637497066b1461106f57806379ba509714610f995780637ec0846d14610f0e5780638da5cb5b14610ebc5780639f4cb53414610e9b578063b87a019414610e45578063d4b89c7414610698578063db800092146105fd578063e3dce080146104d6578063e690f33214610362578063f2fde38b14610284578063f794bdeb146101495763f99ecb6b1461010357600080fd5b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457602060ff600a54166040519015158152f35b600080fd5b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610144576006805461018581612410565b6101926040519182612297565b81815261019e82612410565b916020937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe060208401940136853760005b82811061023257505050906040519283926020840190602085525180915260408401929160005b82811061020557505050500390f35b835173ffffffffffffffffffffffffffffffffffffffff16855286955093810193928101926001016101f6565b6001908260005273ffffffffffffffffffffffffffffffffffffffff817ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01541661027d8287612542565b52016101cf565b346101445760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610144576102bb61237e565b6102c3612bdb565b73ffffffffffffffffffffffffffffffffffffffff8091169033821461033857817fffffffffffffffffffffffff00000000000000000000000000000000000000006000541617600055600154167fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278600080a3005b60046040517fdad89dca000000000000000000000000000000000000000000000000000000008152fd5b346101445760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760ff600a54166104ac576103a760043533612dc1565b600181019081549160ff8360c01c16600281101561047d576001146104535778010000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff841617905580547f6a0ed88e9cf3cb493ab4028fcb1dc7d18f0130fcdfba096edde0aadbfbf5e99f63ffffffff604051946020865260a01c16938061044e339560026020840191016125e4565b0390a4005b60046040517f6f861db1000000000000000000000000000000000000000000000000000000008152fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60046040517f78a4e7d9000000000000000000000000000000000000000000000000000000008152fd5b34610144576104e436612306565b916104ed612bdb565b60ff600a54166104ac5760005b828110610589575060405191806040840160408552526060830191906000905b8082106105515785151560208601527f509460cccbb176edde6cac28895a4415a24961b8f3a0bd2617b9bb7b4e166c9b85850386a1005b90919283359073ffffffffffffffffffffffffffffffffffffffff82168092036101445760019181526020809101940192019061051a565b60019084156105cb576105c373ffffffffffffffffffffffffffffffffffffffff6105bd6105b8848888612a7b565b612bba565b16612f9c565b505b016104fa565b6105f773ffffffffffffffffffffffffffffffffffffffff6105f16105b8848888612a7b565b166131cd565b506105c5565b346101445761061d61060e366123a1565b91610617612428565b50612a9c565b6000526004602052604060002073ffffffffffffffffffffffffffffffffffffffff6001820154161561066e5761065661066a91612698565b604051918291602083526020830190612154565b0390f35b60046040517f871e01b2000000000000000000000000000000000000000000000000000000008152fd5b346101445760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760443567ffffffffffffffff8111610144576106e79036906004016122d8565b9060643567ffffffffffffffff8111610144576107089036906004016122d8565b9160843567ffffffffffffffff8111610144576107299036906004016122d8565b60ff600a94929454166104ac57610744818688602435612cd0565b61075060043533612dc1565b9163ffffffff600184015460a01c169561076a3388612c26565b8354946024358614610e1b576107a56040516107948161078d8160038b016125e4565b0382612297565b61079f368c8561284c565b90612e30565b6107c76040516107bc8161078d8160048c016125e4565b61079f36868861284c565b6107e96040516107de8161078d8160058d016125e4565b61079f36898d61284c565b918080610e14575b80610e0d575b610de357602435885515610c8e575b15610b3d575b15610890575b926108807f41161473ce2ed633d9f902aab9702d16a5531da27ec84e1939abeffe54ad7353959361044e93610872610864978d604051998a996024358b5260a060208c0152600260a08c0191016125e4565b9189830360408b015261290f565b91868303606088015261290f565b908382036080850152339761290f565b61089d6005860154612591565b610ad6575b67ffffffffffffffff8411610aa7576108cb846108c26005880154612591565b600588016128c8565b6000601f85116001146109a757928492610872610880938a9b9c61094f876108649b9a61044e9a7f41161473ce2ed633d9f902aab9702d16a5531da27ec84e1939abeffe54ad73539e9f60009261099c575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b60058a01555b8c8780610972575b50509c9b9a9950935050929495509250610812565b61097c9133612a9c565b60005260056020526109946004356040600020612fee565b508c8761095d565b013590508f8061091d565b9860058601600052602060002060005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe087168110610a8f5750926108726108809361044e969388968c7f41161473ce2ed633d9f902aab9702d16a5531da27ec84e1939abeffe54ad73539c9d9e9f897fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06108649e9d1610610a57575b505050600187811b0160058a0155610955565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88b60031b161c199101351690558e8d81610a44565b898c0135825560209b8c019b600190920191016109b7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516020810190610b1c81610af060058a01338661294e565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282612297565b5190206000526005602052610b376004356040600020613294565b506108a2565b67ffffffffffffffff8311610aa757610b6683610b5d6004890154612591565b600489016128c8565b600083601f8111600114610bc75780610bb292600091610bbc575b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b600487015561080c565b90508601358d610b81565b506004870160005260206000209060005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086168110610c765750847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0811610610c3e575b5050600183811b01600487015561080c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88660031b161c19908601351690558a80610c2c565b9091602060018192858a013581550193019101610bd8565b67ffffffffffffffff8b11610aa757610cb78b610cae60038a0154612591565b60038a016128c8565b60008b601f8111600114610d175780610d0292600091610d0c57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b6003880155610806565b90508501358e610b81565b506003880160005260206000209060005b8d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081168210610dca578091507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0811610610d91575b905060018092501b016003880155610806565b60f87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9160031b161c19908501351690558b808c610d7e565b5085820135835560019092019160209182019101610d28565b60046040517f6b4a810d000000000000000000000000000000000000000000000000000000008152fd5b50826107f7565b50816107f1565b60046040517f95406722000000000000000000000000000000000000000000000000000000008152fd5b346101445760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445761066a610e8f610e8261237e565b6044359060243590612af7565b604051918291826121f8565b34610144576020610eb4610eae366123a1565b91612a9c565b604051908152f35b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457602073ffffffffffffffffffffffffffffffffffffffff60015416604051908152f35b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457610f45612bdb565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00600a5416600a557f11a03e25ee25bf1459f9e1cb293ea03707d84917f54a65e32c9a7be2f2edd68a6020604051338152a1005b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760005473ffffffffffffffffffffffffffffffffffffffff808216330361104557600154917fffffffffffffffffffffffff0000000000000000000000000000000000000000903382851617600155166000553391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b60046040517f02b543c6000000000000000000000000000000000000000000000000000000008152fd5b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457600880546110ab81612410565b6110b86040519182612297565b8181526110c482612410565b916020937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe060208401940136853760005b82811061114857505050906040519283926020840190602085525180915260408401929160005b82811061112b57505050500390f35b835163ffffffff168552869550938101939281019260010161111c565b6001908260005263ffffffff817ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30154166111838287612542565b52016110f5565b346101445761119836612306565b916111a1612bdb565b60ff600a54166104ac5760005b82811061122d575060405191806040840160408552526060830191906000905b8082106112055785151560208601527fcab63bf31d1e656baa23cebef64e12033ea0ffbd44b1278c3747beec2d2f618c85850386a1005b90919283359063ffffffff8216809203610144576001918152602080910194019201906111ce565b600190841561125f5761125763ffffffff61125161124c848888612a7b565b612a8b565b16612ee3565b505b016111ae565b61127b63ffffffff61127561124c848888612a7b565b1661307a565b50611259565b346101445760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760ff600a54166104ac576112c660043533612dc1565b600181019081549163ffffffff8360a01c169260ff8160c01c16600281101561047d5715610453577fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff9061131a3386612c26565b16905580547f17b2d730bb5e064df3fbc6165c8aceb3b0d62c524c196c0bc1012209280bc9a6604051602081528061044e339560026020840191016125e4565b34610144576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610144576004359060ff600a54166104ac576113a28233612dc1565b916113ba336000526007602052604060002054151590565b156114d25760049233600052600283526113d8826040600020613294565b50600181019063ffffffff80835460a01c16600052600385526113ff846040600020613294565b506005820161140e8154612591565b61149e575b508154925460a01c16917f76ee2dfcae10cb8522e62e713e62660e09ecfaab08db15d9404de1914132257160405186815280611456339560028a840191016125e4565b0390a46000525261149c60056040600020600081556000600182015561147e60028201612a32565b61148a60038201612a32565b61149660048201612a32565b01612a32565b005b6040516114b381610af089820194338661294e565b519020600052600585526114cb846040600020613294565b5086611413565b60246040517f85982a00000000000000000000000000000000000000000000000000000000008152336004820152fd5b346101445760e07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760043567ffffffffffffffff8111610144576115519036906004016122d8565b6044359163ffffffff8316830361014457600260643510156101445760843567ffffffffffffffff81116101445761158d9036906004016122d8565b91909260a43567ffffffffffffffff8111610144576115b09036906004016122d8565b60c43567ffffffffffffffff8111610144576115d09036906004016122d8565b96909560ff600a54166104ac576115e7338a612c26565b60408511611e04576115fd888483602435612cd0565b611608858733612a9c565b80600052600460205273ffffffffffffffffffffffffffffffffffffffff60016040600020015416611dda57604051906116418261227a565b602435825233602083015263ffffffff8b16604083015261166760643560608401612585565b61167236888a61284c565b608083015261168236848661284c565b60a083015261169236868861284c565b60c08301526116a2368b8b61284c565b60e0830152806000526004602052604060002091805183556001830173ffffffffffffffffffffffffffffffffffffffff60208301511681549077ffffffff0000000000000000000000000000000000000000604085015160a01b16906060850151600281101561047d5778ff0000000000000000000000000000000000000000000000007fffffffffffffff000000000000000000000000000000000000000000000000009160c01b1693161717179055608081015180519067ffffffffffffffff8211610aa7576117858261177c6002880154612591565b600288016128c8565b602090601f8311600114611d0e576117d2929160009183611c375750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b60028401555b60a081015180519067ffffffffffffffff8211610aa757611809826118006003880154612591565b600388016128c8565b602090601f8311600114611c4257611856929160009183611c375750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b60038401555b60c081015180519067ffffffffffffffff8211610aa75761188d826118846004880154612591565b600488016128c8565b602090601f8311600114611b6a5791806118de9260e09594600092611a455750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b60048501555b015180519267ffffffffffffffff8411610aa757838d926119168e9661190d6005860154612591565b600586016128c8565b602090601f8311600114611a50579463ffffffff61087295819a957fc4399022965bad9b2b468bbd8c758a7e80cdde36ff3088ddbb7f93bdfb5623cb9f9e9d99946119a28761044e9f9b98600593611a069f9a600092611a455750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b9101555b3360005260026020526119bd836040600020612fee565b501660005260036020526119d5816040600020612fee565b508d82611a1c575b5050506108646040519a8b9a6119f58c6064356120e9565b60a060208d015260a08c019161290f565b978389036080850152169633966024359661290f565b611a3c92611a2a9133612a9c565b60005260056020526040600020612fee565b508c8f8d6119dd565b01519050388061091d565b906005840160005260206000209160005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe085168110611b4057506108729563ffffffff9a957fc4399022965bad9b2b468bbd8c758a7e80cdde36ff3088ddbb7f93bdfb5623cb9f9e9d999460018761044e9f9b96928f9693611a069f9a94837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06005971610611b09575b505050811b019101556119a6565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c19169055388080611afb565b939550918194969750600160209291839285015181550194019201918f9492918f97969492611a61565b906004860160005260206000209160005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe085168110611c1f5750918391600193837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe060e098971610611be8575b505050811b0160048501556118e4565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690558f8080611bd8565b91926020600181928685015181550194019201611b7b565b015190508f8061091d565b9190600386016000526020600020906000935b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084168510611cf35760019450837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0811610611cbc575b505050811b01600384015561185c565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690558e8080611cac565b81810151835560209485019460019093019290910190611c55565b9190600286016000526020600020906000935b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084168510611dbf5760019450837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0811610611d88575b505050811b0160028401556117d8565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690558e8080611d78565b81810151835560209485019460019093019290910190611d21565b60046040517fa0677dd0000000000000000000000000000000000000000000000000000000008152fd5b604485604051907f36a7c503000000000000000000000000000000000000000000000000000000008252600482015260406024820152fd5b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457611e73612bdb565b60017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00600a541617600a557f2789711f6fd67d131ad68378617b5d1d21a2c92b34d7c3745d70b3957c08096c6020604051338152a1005b34610144576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760043567ffffffffffffffff811161014457611f1a9036906004016122d8565b60ff600a54166104ac57611f2e9133612a9c565b90816000526005602052604060002091825491821561066e5760005b838110611f5357005b80611f6060019287612ecb565b90549060031b1c60005260048352604060002063ffffffff8382015460a01c1660005260098452604060002054151580611fea575b611fa1575b5001611f4a565b7f95d94f817db4971aa99ba35d0fe019bd8cc39866fbe02b6d47b5f0f3727fb67360405186815260408682015280611fe1339460026040840191016125e4565b0390a286611f9a565b50612002336000526007602052604060002054151590565b611f95565b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457604051604081019080821067ffffffffffffffff831117610aa75761066a91604052601a81527f576f726b666c6f77526567697374727920312e302e302d64657600000000000060208201526040519182916020835260208301906120f6565b346101445760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760043563ffffffff8116810361014457610e8f61066a916044359060243590612757565b90600282101561047d5752565b919082519283825260005b8481106121405750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8460006020809697860101520116010190565b602081830181015184830182015201612101565b6121f59160e06121e46121d26121c06101008651865273ffffffffffffffffffffffffffffffffffffffff602088015116602087015263ffffffff60408801511660408701526121ac606088015160608801906120e9565b6080870151908060808801528601906120f6565b60a086015185820360a08701526120f6565b60c085015184820360c08601526120f6565b9201519060e08184039101526120f6565b90565b6020808201906020835283518092526040830192602060408460051b8301019501936000915b84831061222e5750505050505090565b909192939495848061226a837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc086600196030187528a51612154565b980193019301919493929061221e565b610100810190811067ffffffffffffffff821117610aa757604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117610aa757604052565b9181601f840112156101445782359167ffffffffffffffff8311610144576020838186019501011161014457565b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126101445760043567ffffffffffffffff9283821161014457806023830112156101445781600401359384116101445760248460051b8301011161014457602401919060243580151581036101445790565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361014457565b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126101445760043573ffffffffffffffffffffffffffffffffffffffff8116810361014457916024359067ffffffffffffffff82116101445761240c916004016122d8565b9091565b67ffffffffffffffff8111610aa75760051b60200190565b604051906124358261227a565b606060e0836000815260006020820152600060408201526000838201528260808201528260a08201528260c08201520152565b6040516020810181811067ffffffffffffffff821117610aa7576040526000815290565b9061249682612410565b6124a36040519182612297565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06124d18294612410565b019060005b8281106124e257505050565b6020906124ed612428565b828285010152016124d6565b9190820180921161250657565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9190820391821161250657565b80518210156125565760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600282101561047d5752565b90600182811c921680156125da575b60208310146125ab57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b91607f16916125a0565b8054600093926125f382612591565b9182825260209360019160018116908160001461265b575060011461261a575b5050505050565b90939495506000929192528360002092846000945b83861061264757505050500101903880808080612613565b80548587018301529401938590820161262f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168685015250505090151560051b010191503880808080612613565b90600560e06040936127538551916126af8361227a565b61274c8397825485526126f960ff600185015473ffffffffffffffffffffffffffffffffffffffff8116602089015263ffffffff8160a01c168489015260c01c1660608701612585565b805161270c8161078d81600288016125e4565b608086015280516127248161078d81600388016125e4565b60a0860152805161273c8161078d81600488016125e4565b60c08601525180968193016125e4565b0384612297565b0152565b63ffffffff16916000838152600360209060036020526040936040842054908187101561283c576127ab918160648993118015612834575b61282c575b8161279f82856124f9565b111561281c5750612535565b946127b58661248c565b96845b8781106127ca57505050505050505090565b6001908287528486526127e98888206127e383876124f9565b90612ecb565b905490861b1c875260048652612800888820612698565b61280a828c612542565b52612815818b612542565b50016127b8565b6128279150826124f9565b612535565b506064612794565b50801561278f565b50505050505050506121f5612468565b92919267ffffffffffffffff8211610aa7576040519161289460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160184612297565b829481845281830111610144578281602093846000960137010152565b8181106128bc575050565b600081556001016128b1565b9190601f81116128d757505050565b612903926000526020600020906020601f840160051c83019310612905575b601f0160051c01906128b1565b565b90915081906128f6565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b91907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009060601b16825260149060009281549261298a84612591565b926001946001811690816000146129f157506001146129ac575b505050505090565b9091929395945060005260209460206000206000905b8582106129de57505050506014929350010138808080806129a4565b80548583018501529087019082016129c2565b92505050601494507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00919350168383015280151502010138808080806129a4565b612a3c8154612591565b9081612a46575050565b81601f60009311600114612a58575055565b908083918252612a77601f60208420940160051c8401600185016128b1565b5555565b91908110156125565760051b0190565b3563ffffffff811681036101445790565b91906034612af191836040519485927fffffffffffffffffffffffffffffffffffffffff000000000000000000000000602085019860601b168852848401378101600083820152036014810184520182612297565b51902090565b73ffffffffffffffffffffffffffffffffffffffff1691600083815260029260209060026020526040936040842054908183101561283c57612b4e9181606485931180156128345761282c578161279f82856124f9565b94612b588661248c565b96845b878110612b6d57505050505050505090565b600190828752838652612b868888206127e383886124f9565b90549060031b1c875260048652612b9e888820612698565b612ba8828c612542565b52612bb3818b612542565b5001612b5b565b3573ffffffffffffffffffffffffffffffffffffffff811681036101445790565b73ffffffffffffffffffffffffffffffffffffffff600154163303612bfc57565b60046040517f2b5c74de000000000000000000000000000000000000000000000000000000008152fd5b63ffffffff1680600052600960205260406000205415612c9f575073ffffffffffffffffffffffffffffffffffffffff1680600052600760205260406000205415612c6e5750565b602490604051907f85982a000000000000000000000000000000000000000000000000000000000082526004820152fd5b602490604051907f8fe6d7e10000000000000000000000000000000000000000000000000000000082526004820152fd5b91909115612d975760c891828111612d615750818111612d2c5750808211612cf6575050565b60449250604051917ecd56a800000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b604491604051917ecd56a800000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b60449083604051917ecd56a800000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b60046040517f7dc2f4e1000000000000000000000000000000000000000000000000000000008152fd5b90600052600460205260406000209073ffffffffffffffffffffffffffffffffffffffff8060018401541691821561066e5716809103612dff575090565b602490604051907f31ee6dc70000000000000000000000000000000000000000000000000000000082526004820152fd5b9081518151908181149384612e47575b5050505090565b6020929394508201209201201438808080612e40565b6008548110156125565760086000527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30190600090565b6006548110156125565760066000527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0190600090565b80548210156125565760005260206000200190600090565b600081815260096020526040812054612f975760085468010000000000000000811015612f6a579082612f56612f2184600160409601600855612e5d565b81939154907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9060031b92831b921b19161790565b905560085492815260096020522055600190565b6024827f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b905090565b600081815260076020526040812054612f975760065468010000000000000000811015612f6a579082612fda612f2184600160409601600655612e94565b905560065492815260076020522055600190565b9190600183016000908282528060205260408220541560001461307457845494680100000000000000008610156130475783613037612f21886001604098999a01855584612ecb565b9055549382526020522055600190565b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b50925050565b60008181526009602052604081205490919080156131c8577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9081810181811161319b576008549083820191821161316e5781810361313a575b505050600854801561310d578101906130ec82612e5d565b909182549160031b1b19169055600855815260096020526040812055600190565b6024847f4e487b710000000000000000000000000000000000000000000000000000000081526031600452fd5b613158613149612f2193612e5d565b90549060031b1c928392612e5d565b90558452600960205260408420553880806130d4565b6024867f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b505090565b60008181526007602052604081205490919080156131c8577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9081810181811161319b576006549083820191821161316e57818103613260575b505050600654801561310d5781019061323f82612e94565b909182549160031b1b19169055600655815260076020526040812055600190565b61327e61326f612f2193612e94565b90549060031b1c928392612e94565b9055845260076020526040842055388080613227565b90600182019060009281845282602052604084205490811515600014612e40577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff918281018181116133b95782549084820191821161338c57818103613357575b5050508054801561332a5782019161330d8383612ecb565b909182549160031b1b191690555582526020526040812055600190565b6024867f4e487b710000000000000000000000000000000000000000000000000000000081526031600452fd5b613377613367612f219386612ecb565b90549060031b1c92839286612ecb565b905586528460205260408620553880806132f5565b6024887f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6024877f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fdfea164736f6c6343000818000a", + Bin: "0x6080806040523461004a57331561003b57600180546001600160a01b03191633179055600b805460ff191690556040516134e290816100508239f35b639b15e16f60e01b8152600490fd5b600080fdfe6080604052600436101561001257600080fd5b60003560e01c806308e7f63a1461210e578063181f5a771461207f5780632303348a14611f425780632b596f6d14611eb45780633ccd14ff14611572578063695e1340146113965780636f351771146112bd578063724c13dd146111c65780637497066b146110ab57806379ba509714610fd55780637ec0846d14610f4a5780638da5cb5b14610ef85780639f4cb53414610ed7578063b87a019414610e81578063d4b89c7414610698578063db800092146105fd578063e3dce080146104d6578063e690f33214610362578063f2fde38b14610284578063f794bdeb146101495763f99ecb6b1461010357600080fd5b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457602060ff600b54166040519015158152f35b600080fd5b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610144576007805461018581612488565b610192604051918261230f565b81815261019e82612488565b916020937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe060208401940136853760005b82811061023257505050906040519283926020840190602085525180915260408401929160005b82811061020557505050500390f35b835173ffffffffffffffffffffffffffffffffffffffff16855286955093810193928101926001016101f6565b6001908260005273ffffffffffffffffffffffffffffffffffffffff817fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68801541661027d82876125ba565b52016101cf565b346101445760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610144576102bb6123f6565b6102c3612c53565b73ffffffffffffffffffffffffffffffffffffffff8091169033821461033857817fffffffffffffffffffffffff00000000000000000000000000000000000000006000541617600055600154167fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278600080a3005b60046040517fdad89dca000000000000000000000000000000000000000000000000000000008152fd5b346101445760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760ff600b54166104ac576103a760043533612eb0565b600181019081549160ff8360c01c16600281101561047d576001146104535778010000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff841617905580547f6a0ed88e9cf3cb493ab4028fcb1dc7d18f0130fcdfba096edde0aadbfbf5e99f63ffffffff604051946020865260a01c16938061044e3395600260208401910161265c565b0390a4005b60046040517f6f861db1000000000000000000000000000000000000000000000000000000008152fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60046040517f78a4e7d9000000000000000000000000000000000000000000000000000000008152fd5b34610144576104e43661237e565b916104ed612c53565b60ff600b54166104ac5760005b828110610589575060405191806040840160408552526060830191906000905b8082106105515785151560208601527f509460cccbb176edde6cac28895a4415a24961b8f3a0bd2617b9bb7b4e166c9b85850386a1005b90919283359073ffffffffffffffffffffffffffffffffffffffff82168092036101445760019181526020809101940192019061051a565b60019084156105cb576105c373ffffffffffffffffffffffffffffffffffffffff6105bd6105b8848888612af3565b612c32565b1661308b565b505b016104fa565b6105f773ffffffffffffffffffffffffffffffffffffffff6105f16105b8848888612af3565b166132bc565b506105c5565b346101445761061d61060e36612419565b916106176124a0565b50612b14565b6000526004602052604060002073ffffffffffffffffffffffffffffffffffffffff6001820154161561066e5761065661066a91612710565b6040519182916020835260208301906121cc565b0390f35b60046040517f871e01b2000000000000000000000000000000000000000000000000000000008152fd5b346101445760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760443567ffffffffffffffff8111610144576106e7903690600401612350565b9060643567ffffffffffffffff811161014457610708903690600401612350565b9160843567ffffffffffffffff811161014457610729903690600401612350565b60ff600b94929454166104ac57610741818688612d48565b61074d60043533612eb0565b9163ffffffff600184015460a01c16956107673388612c9e565b8354946024358614610e57576107a26040516107918161078a8160038b0161265c565b038261230f565b61079c368c856128c4565b90612f1f565b6107c46040516107b98161078a8160048c0161265c565b61079c3686886128c4565b6107e66040516107db8161078a8160058d0161265c565b61079c36898d6128c4565b918080610e50575b80610e49575b610e1f57610803602435612e08565b88600052600660205260406000207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008154169055602435885515610cca575b15610b79575b156108cc575b926108bc7f41161473ce2ed633d9f902aab9702d16a5531da27ec84e1939abeffe54ad7353959361044e936108ae6108a0978d604051998a996024358b5260a060208c0152600260a08c01910161265c565b9189830360408b0152612987565b918683036060880152612987565b9083820360808501523397612987565b6108d96005860154612609565b610b12575b67ffffffffffffffff8411610ae357610907846108fe6005880154612609565b60058801612940565b6000601f85116001146109e3579284926108ae6108bc938a9b9c61098b876108a09b9a61044e9a7f41161473ce2ed633d9f902aab9702d16a5531da27ec84e1939abeffe54ad73539e9f6000926109d8575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b60058a01555b8c87806109ae575b50509c9b9a995093505092949550925061084e565b6109b89133612b14565b60005260056020526109d060043560406000206130dd565b508c87610999565b013590508f80610959565b9860058601600052602060002060005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe087168110610acb5750926108ae6108bc9361044e969388968c7f41161473ce2ed633d9f902aab9702d16a5531da27ec84e1939abeffe54ad73539c9d9e9f897fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06108a09e9d1610610a93575b505050600187811b0160058a0155610991565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88b60031b161c199101351690558e8d81610a80565b898c0135825560209b8c019b600190920191016109f3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516020810190610b5881610b2c60058a0133866129c6565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0810183528261230f565b5190206000526005602052610b736004356040600020613383565b506108de565b67ffffffffffffffff8311610ae357610ba283610b996004890154612609565b60048901612940565b600083601f8111600114610c035780610bee92600091610bf8575b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b6004870155610848565b90508601358d610bbd565b506004870160005260206000209060005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086168110610cb25750847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0811610610c7a575b5050600183811b016004870155610848565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88660031b161c19908601351690558a80610c68565b9091602060018192858a013581550193019101610c14565b67ffffffffffffffff8b11610ae357610cf38b610cea60038a0154612609565b60038a01612940565b60008b601f8111600114610d535780610d3e92600091610d4857507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b6003880155610842565b90508501358e610bbd565b506003880160005260206000209060005b8d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081168210610e06578091507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0811610610dcd575b905060018092501b016003880155610842565b60f87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9160031b161c19908501351690558b808c610dba565b5085820135835560019092019160209182019101610d64565b60046040517f6b4a810d000000000000000000000000000000000000000000000000000000008152fd5b50826107f4565b50816107ee565b60046040517f95406722000000000000000000000000000000000000000000000000000000008152fd5b346101445760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445761066a610ecb610ebe6123f6565b6044359060243590612b6f565b60405191829182612270565b34610144576020610ef0610eea36612419565b91612b14565b604051908152f35b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457602073ffffffffffffffffffffffffffffffffffffffff60015416604051908152f35b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457610f81612c53565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00600b5416600b557f11a03e25ee25bf1459f9e1cb293ea03707d84917f54a65e32c9a7be2f2edd68a6020604051338152a1005b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760005473ffffffffffffffffffffffffffffffffffffffff808216330361108157600154917fffffffffffffffffffffffff0000000000000000000000000000000000000000903382851617600155166000553391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b60046040517f02b543c6000000000000000000000000000000000000000000000000000000008152fd5b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457600980546110e781612488565b6110f4604051918261230f565b81815261110082612488565b916020937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe060208401940136853760005b82811061118457505050906040519283926020840190602085525180915260408401929160005b82811061116757505050500390f35b835163ffffffff1685528695509381019392810192600101611158565b6001908260005263ffffffff817f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0154166111bf82876125ba565b5201611131565b34610144576111d43661237e565b916111dd612c53565b60ff600b54166104ac5760005b828110611269575060405191806040840160408552526060830191906000905b8082106112415785151560208601527fcab63bf31d1e656baa23cebef64e12033ea0ffbd44b1278c3747beec2d2f618c85850386a1005b90919283359063ffffffff82168092036101445760019181526020809101940192019061120a565b600190841561129b5761129363ffffffff61128d611288848888612af3565b612b03565b16612fd2565b505b016111ea565b6112b763ffffffff6112b1611288848888612af3565b16613169565b50611295565b346101445760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760ff600b54166104ac5761130260043533612eb0565b600181019081549163ffffffff8360a01c169260ff8160c01c16600281101561047d5715610453577fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff906113563386612c9e565b16905580547f17b2d730bb5e064df3fbc6165c8aceb3b0d62c524c196c0bc1012209280bc9a6604051602081528061044e3395600260208401910161265c565b34610144576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610144576004359060ff600b54166104ac576113de8233612eb0565b916113f6336000526008602052604060002054151590565b156115425782600493546000526006835260406000207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0081541690553360005260028352611448826040600020613383565b50600181019063ffffffff80835460a01c166000526003855261146f846040600020613383565b506005820161147e8154612609565b61150e575b508154925460a01c16917f76ee2dfcae10cb8522e62e713e62660e09ecfaab08db15d9404de19141322571604051868152806114c6339560028a8401910161265c565b0390a46000525261150c6005604060002060008155600060018201556114ee60028201612aaa565b6114fa60038201612aaa565b61150660048201612aaa565b01612aaa565b005b60405161152381610b2c8982019433866129c6565b5190206000526005855261153b846040600020613383565b5086611483565b60246040517f85982a00000000000000000000000000000000000000000000000000000000008152336004820152fd5b346101445760e07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760043567ffffffffffffffff8111610144576115c1903690600401612350565b6044359163ffffffff8316830361014457600260643510156101445760843567ffffffffffffffff8111610144576115fd903690600401612350565b91909260a43567ffffffffffffffff811161014457611620903690600401612350565b60c43567ffffffffffffffff811161014457611640903690600401612350565b96909560ff600b54166104ac57611657338a612c9e565b60408511611e7c5761166a888483612d48565b611675858733612b14565b80600052600460205273ffffffffffffffffffffffffffffffffffffffff60016040600020015416611e52576116ac602435612e08565b604051906116b9826122f2565b602435825233602083015263ffffffff8b1660408301526116df606435606084016125fd565b6116ea36888a6128c4565b60808301526116fa3684866128c4565b60a083015261170a3686886128c4565b60c083015261171a368b8b6128c4565b60e0830152806000526004602052604060002091805183556001830173ffffffffffffffffffffffffffffffffffffffff60208301511681549077ffffffff0000000000000000000000000000000000000000604085015160a01b16906060850151600281101561047d5778ff0000000000000000000000000000000000000000000000007fffffffffffffff000000000000000000000000000000000000000000000000009160c01b1693161717179055608081015180519067ffffffffffffffff8211610ae3576117fd826117f46002880154612609565b60028801612940565b602090601f8311600114611d865761184a929160009183611caf5750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b60028401555b60a081015180519067ffffffffffffffff8211610ae357611881826118786003880154612609565b60038801612940565b602090601f8311600114611cba576118ce929160009183611caf5750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b60038401555b60c081015180519067ffffffffffffffff8211610ae357611905826118fc6004880154612609565b60048801612940565b602090601f8311600114611be25791806119569260e09594600092611abd5750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b60048501555b015180519267ffffffffffffffff8411610ae357838d9261198e8e966119856005860154612609565b60058601612940565b602090601f8311600114611ac8579463ffffffff6108ae95819a957fc4399022965bad9b2b468bbd8c758a7e80cdde36ff3088ddbb7f93bdfb5623cb9f9e9d9994611a1a8761044e9f9b98600593611a7e9f9a600092611abd5750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b9101555b336000526002602052611a358360406000206130dd565b50166000526003602052611a4d8160406000206130dd565b508d82611a94575b5050506108a06040519a8b9a611a6d8c606435612161565b60a060208d015260a08c0191612987565b9783890360808501521696339660243596612987565b611ab492611aa29133612b14565b600052600560205260406000206130dd565b508c8f8d611a55565b015190503880610959565b906005840160005260206000209160005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe085168110611bb857506108ae9563ffffffff9a957fc4399022965bad9b2b468bbd8c758a7e80cdde36ff3088ddbb7f93bdfb5623cb9f9e9d999460018761044e9f9b96928f9693611a7e9f9a94837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06005971610611b81575b505050811b01910155611a1e565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c19169055388080611b73565b939550918194969750600160209291839285015181550194019201918f9492918f97969492611ad9565b906004860160005260206000209160005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe085168110611c975750918391600193837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe060e098971610611c60575b505050811b01600485015561195c565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690558f8080611c50565b91926020600181928685015181550194019201611bf3565b015190508f80610959565b9190600386016000526020600020906000935b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084168510611d6b5760019450837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0811610611d34575b505050811b0160038401556118d4565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690558e8080611d24565b81810151835560209485019460019093019290910190611ccd565b9190600286016000526020600020906000935b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084168510611e375760019450837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0811610611e00575b505050811b016002840155611850565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690558e8080611df0565b81810151835560209485019460019093019290910190611d99565b60046040517fa0677dd0000000000000000000000000000000000000000000000000000000008152fd5b604485604051907f36a7c503000000000000000000000000000000000000000000000000000000008252600482015260406024820152fd5b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457611eeb612c53565b60017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00600b541617600b557f2789711f6fd67d131ad68378617b5d1d21a2c92b34d7c3745d70b3957c08096c6020604051338152a1005b34610144576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760043567ffffffffffffffff811161014457611f92903690600401612350565b60ff600b54166104ac57611fa69133612b14565b90816000526005602052604060002091825491821561066e5760005b838110611fcb57005b80611fd860019287612fba565b90549060031b1c60005260048352604060002063ffffffff8382015460a01c16600052600a8452604060002054151580612062575b612019575b5001611fc2565b7f95d94f817db4971aa99ba35d0fe019bd8cc39866fbe02b6d47b5f0f3727fb673604051868152604086820152806120593394600260408401910161265c565b0390a286612012565b5061207a336000526008602052604060002054151590565b61200d565b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457604051604081019080821067ffffffffffffffff831117610ae35761066a91604052601a81527f576f726b666c6f77526567697374727920312e302e302d646576000000000000602082015260405191829160208352602083019061216e565b346101445760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760043563ffffffff8116810361014457610ecb61066a9160443590602435906127cf565b90600282101561047d5752565b919082519283825260005b8481106121b85750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8460006020809697860101520116010190565b602081830181015184830182015201612179565b61226d9160e061225c61224a6122386101008651865273ffffffffffffffffffffffffffffffffffffffff602088015116602087015263ffffffff604088015116604087015261222460608801516060880190612161565b60808701519080608088015286019061216e565b60a086015185820360a087015261216e565b60c085015184820360c086015261216e565b9201519060e081840391015261216e565b90565b6020808201906020835283518092526040830192602060408460051b8301019501936000915b8483106122a65750505050505090565b90919293949584806122e2837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc086600196030187528a516121cc565b9801930193019194939290612296565b610100810190811067ffffffffffffffff821117610ae357604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117610ae357604052565b9181601f840112156101445782359167ffffffffffffffff8311610144576020838186019501011161014457565b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126101445760043567ffffffffffffffff9283821161014457806023830112156101445781600401359384116101445760248460051b8301011161014457602401919060243580151581036101445790565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361014457565b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126101445760043573ffffffffffffffffffffffffffffffffffffffff8116810361014457916024359067ffffffffffffffff82116101445761248491600401612350565b9091565b67ffffffffffffffff8111610ae35760051b60200190565b604051906124ad826122f2565b606060e0836000815260006020820152600060408201526000838201528260808201528260a08201528260c08201520152565b6040516020810181811067ffffffffffffffff821117610ae3576040526000815290565b9061250e82612488565b61251b604051918261230f565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06125498294612488565b019060005b82811061255a57505050565b6020906125656124a0565b8282850101520161254e565b9190820180921161257e57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9190820391821161257e57565b80518210156125ce5760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600282101561047d5752565b90600182811c92168015612652575b602083101461262357565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b91607f1691612618565b80546000939261266b82612609565b918282526020936001916001811690816000146126d35750600114612692575b5050505050565b90939495506000929192528360002092846000945b8386106126bf5750505050010190388080808061268b565b8054858701830152940193859082016126a7565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168685015250505090151560051b01019150388080808061268b565b90600560e06040936127cb855191612727836122f2565b6127c483978254855261277160ff600185015473ffffffffffffffffffffffffffffffffffffffff8116602089015263ffffffff8160a01c168489015260c01c16606087016125fd565b80516127848161078a816002880161265c565b6080860152805161279c8161078a816003880161265c565b60a086015280516127b48161078a816004880161265c565b60c086015251809681930161265c565b038461230f565b0152565b63ffffffff1691600083815260036020906003602052604093604084205490818710156128b4576128239181606489931180156128ac575b6128a4575b816128178285612571565b111561289457506125ad565b9461282d86612504565b96845b87811061284257505050505050505090565b60019082875284865261286188882061285b8387612571565b90612fba565b905490861b1c875260048652612878888820612710565b612882828c6125ba565b5261288d818b6125ba565b5001612830565b61289f915082612571565b6125ad565b50606461280c565b508015612807565b505050505050505061226d6124e0565b92919267ffffffffffffffff8211610ae3576040519161290c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116018461230f565b829481845281830111610144578281602093846000960137010152565b818110612934575050565b60008155600101612929565b9190601f811161294f57505050565b61297b926000526020600020906020601f840160051c8301931061297d575b601f0160051c0190612929565b565b909150819061296e565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b91907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009060601b168252601490600092815492612a0284612609565b92600194600181169081600014612a695750600114612a24575b505050505090565b9091929395945060005260209460206000206000905b858210612a565750505050601492935001013880808080612a1c565b8054858301850152908701908201612a3a565b92505050601494507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0091935016838301528015150201013880808080612a1c565b612ab48154612609565b9081612abe575050565b81601f60009311600114612ad0575055565b908083918252612aef601f60208420940160051c840160018501612929565b5555565b91908110156125ce5760051b0190565b3563ffffffff811681036101445790565b91906034612b6991836040519485927fffffffffffffffffffffffffffffffffffffffff000000000000000000000000602085019860601b16885284840137810160008382015203601481018452018261230f565b51902090565b73ffffffffffffffffffffffffffffffffffffffff169160008381526002926020906002602052604093604084205490818310156128b457612bc69181606485931180156128ac576128a457816128178285612571565b94612bd086612504565b96845b878110612be557505050505050505090565b600190828752838652612bfe88882061285b8388612571565b90549060031b1c875260048652612c16888820612710565b612c20828c6125ba565b52612c2b818b6125ba565b5001612bd3565b3573ffffffffffffffffffffffffffffffffffffffff811681036101445790565b73ffffffffffffffffffffffffffffffffffffffff600154163303612c7457565b60046040517f2b5c74de000000000000000000000000000000000000000000000000000000008152fd5b63ffffffff1680600052600a60205260406000205415612d17575073ffffffffffffffffffffffffffffffffffffffff1680600052600860205260406000205415612ce65750565b602490604051907f85982a000000000000000000000000000000000000000000000000000000000082526004820152fd5b602490604051907f8fe6d7e10000000000000000000000000000000000000000000000000000000082526004820152fd5b9060c891828111612dd25750818111612d9d5750808211612d67575050565b60449250604051917ecd56a800000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b604491604051917ecd56a800000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b60449083604051917ecd56a800000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b8015612e865780600052600660205260ff60406000205416612e5c576000526006602052604060002060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00825416179055565b60046040517f4cb050e4000000000000000000000000000000000000000000000000000000008152fd5b60046040517f7dc2f4e1000000000000000000000000000000000000000000000000000000008152fd5b90600052600460205260406000209073ffffffffffffffffffffffffffffffffffffffff8060018401541691821561066e5716809103612eee575090565b602490604051907f31ee6dc70000000000000000000000000000000000000000000000000000000082526004820152fd5b9081518151908181149384612f36575b5050505090565b6020929394508201209201201438808080612f2f565b6009548110156125ce5760096000527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0190600090565b6007548110156125ce5760076000527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880190600090565b80548210156125ce5760005260206000200190600090565b6000818152600a6020526040812054613086576009546801000000000000000081101561305957908261304561301084600160409601600955612f4c565b81939154907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9060031b92831b921b19161790565b9055600954928152600a6020522055600190565b6024827f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b905090565b60008181526008602052604081205461308657600754680100000000000000008110156130595790826130c961301084600160409601600755612f83565b905560075492815260086020522055600190565b9190600183016000908282528060205260408220541560001461316357845494680100000000000000008610156131365783613126613010886001604098999a01855584612fba565b9055549382526020522055600190565b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b50925050565b6000818152600a602052604081205490919080156132b7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9081810181811161328a576009549083820191821161325d57818103613229575b50505060095480156131fc578101906131db82612f4c565b909182549160031b1b191690556009558152600a6020526040812055600190565b6024847f4e487b710000000000000000000000000000000000000000000000000000000081526031600452fd5b61324761323861301093612f4c565b90549060031b1c928392612f4c565b90558452600a60205260408420553880806131c3565b6024867f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b505090565b60008181526008602052604081205490919080156132b7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9081810181811161328a576007549083820191821161325d5781810361334f575b50505060075480156131fc5781019061332e82612f83565b909182549160031b1b19169055600755815260086020526040812055600190565b61336d61335e61301093612f83565b90549060031b1c928392612f83565b9055845260086020526040842055388080613316565b90600182019060009281845282602052604084205490811515600014612f2f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff918281018181116134a85782549084820191821161347b57818103613446575b50505080548015613419578201916133fc8383612fba565b909182549160031b1b191690555582526020526040812055600190565b6024867f4e487b710000000000000000000000000000000000000000000000000000000081526031600452fd5b6134666134566130109386612fba565b90549060031b1c92839286612fba565b905586528460205260408620553880806133e4565b6024887f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6024877f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fdfea164736f6c6343000818000a", } var WorkflowRegistryABI = WorkflowRegistryMetaData.ABI diff --git a/core/gethwrappers/workflow/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/workflow/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 7552f72d164..a908ff2e724 100644 --- a/core/gethwrappers/workflow/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/workflow/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,2 +1,2 @@ GETH_VERSION: 1.14.11 -workflow_registry_wrapper: ../../../contracts/solc/v0.8.24/WorkflowRegistry/WorkflowRegistry.abi ../../../contracts/solc/v0.8.24/WorkflowRegistry/WorkflowRegistry.bin 910925e0786fbe9efb686646ede620e7fc0536c74acdaeef49e96ac67580ea14 +workflow_registry_wrapper: ../../../contracts/solc/v0.8.24/WorkflowRegistry/WorkflowRegistry.abi ../../../contracts/solc/v0.8.24/WorkflowRegistry/WorkflowRegistry.bin bad48df0196c8a170a8e5486d0334183defd60e74bd89d3885989e00d6f13d23 diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 8f9e458b8e2..d29df20e3fa 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -9,6 +9,13 @@ replace github.com/smartcontractkit/chainlink/v2 => ../../ replace github.com/smartcontractkit/chainlink/deployment => ../../deployment +// Using a separate `require` here to avoid surrounding line changes +// creating potential merge conflicts. +require ( + github.com/smartcontractkit/chainlink/deployment v0.0.0-20241206210521-125d98cdaf66 + github.com/smartcontractkit/chainlink/v2 v2.0.0-20241206210521-125d98cdaf66 +) + require ( github.com/docker/docker v27.3.1+incompatible github.com/docker/go-connections v0.5.0 @@ -26,9 +33,7 @@ require ( github.com/prometheus/client_golang v1.20.5 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v0.8.1 - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f - github.com/smartcontractkit/chainlink/deployment v0.0.0-00010101000000-000000000000 - github.com/smartcontractkit/chainlink/v2 v2.14.0-mercury-20240807.0.20241106193309-5560cd76211a + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 github.com/smartcontractkit/libocr v0.0.0-20241007185508-adbe57025f12 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 @@ -298,13 +303,13 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 // indirect github.com/smartcontractkit/chain-selectors v1.0.34 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0 // indirect github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e // indirect github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db // indirect github.com/smartcontractkit/chainlink-feeds v0.1.1 // indirect github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 // indirect github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2 // indirect - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241204153209-c3a71b0eef99 // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8 // indirect github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.13 // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 3b8c5987c00..c14563ea569 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1140,10 +1140,10 @@ github.com/smartcontractkit/chain-selectors v1.0.34 h1:MJ17OGu8+jjl426pcKrJkCf3f github.com/smartcontractkit/chain-selectors v1.0.34/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e h1:GnM6ZWV6vlk2+n6c6o+v/R1LtXzBGVVx7r37nt/h6Uc= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e/go.mod h1:80vGBbOfertJig0xFKsRfm+i17FkjdKkk1dAaGE45Os= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f h1:hH+cAG2zt+WK4I2m572LXAnAJg3wtGEAwzBKR8FiXo8= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0 h1:/1L+v4SxUD2K5RMRbfByyLfePMAgQKeD0onSetPnGmA= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 h1:ZA92CTX9JtEArrxgZw7PNctVxFS+/DmSXumkwf1WiMY= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e/go.mod h1:mUh5/woemsVaHgTorA080hrYmO3syBCmPdnWc/5dOqk= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db h1:N1RH1hSr2ACzOFc9hkCcjE8pRBTdcU3p8nsTJByaLes= @@ -1154,8 +1154,8 @@ github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 h1:0ewLMbAz3 github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0/go.mod h1:/dVVLXrsp+V0AbcYGJo3XMzKg3CkELsweA/TTopCsKE= github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2 h1:onBe3DqNrbtOAzKS4PrPIiJX65BGo1aYiYZxFVEW+jc= github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2/go.mod h1:m/A3lqD7ms/RsQ9BT5P2uceYY0QX5mIt4KQxT2G6qEo= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241204153209-c3a71b0eef99 h1:lvn9Yxah+QD1/PcgijLO0dNRa28HuQWZl8Kkxh46KJc= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241204153209-c3a71b0eef99/go.mod h1:p8aUDfJeley6oer7y+Ucd3edOtRlMTnWg3mN6rhaLWo= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc h1:dssRwJhmzJkUN/OajaDj2GsxBn+Tupk3bI1BkPEoJg0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc/go.mod h1:p8aUDfJeley6oer7y+Ucd3edOtRlMTnWg3mN6rhaLWo= github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8 h1:tNS7U9lrxkFvEuyxQv11HHOiV9LPDGC9wYEy+yM/Jv4= github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8/go.mod h1:EBrEgcdIbwepqguClkv8Ohy7CbyWSJaE4EC9aBJlQK0= github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.13 h1:T0kbw07Vb6xUyA9MIJZfErMgWseWi1zf7cYvRpoq7ug= diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 29473c4d932..d8b9777cb5a 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -312,12 +312,19 @@ func NewApplication(opts ApplicationOpts) (Application, error) { }, eventHandler) globalLogger.Debugw("Creating WorkflowRegistrySyncer") - wfSyncer := syncer.NewWorkflowRegistry(lggr, func(ctx context.Context, bytes []byte) (syncer.ContractReader, error) { - return relayer.NewContractReader(ctx, bytes) - }, cfg.Capabilities().WorkflowRegistry().Address(), + wfSyncer := syncer.NewWorkflowRegistry( + lggr, + func(ctx context.Context, bytes []byte) (syncer.ContractReader, error) { + return relayer.NewContractReader(ctx, bytes) + }, + cfg.Capabilities().WorkflowRegistry().Address(), syncer.WorkflowEventPollerConfig{ QueryCount: 100, - }, eventHandler, loader, workflowDonNotifier) + }, + eventHandler, + loader, + workflowDonNotifier, + ) srvcs = append(srvcs, fetcher, wfSyncer) } diff --git a/core/services/ocr2/plugins/ccip/integration_legacy_test.go b/core/services/ocr2/plugins/ccip/integration_legacy_test.go deleted file mode 100644 index 12a117d47c4..00000000000 --- a/core/services/ocr2/plugins/ccip/integration_legacy_test.go +++ /dev/null @@ -1,594 +0,0 @@ -package ccip_test - -import ( - "context" - "encoding/json" - "fmt" - "math/big" - "sync" - "testing" - "time" - - "github.com/ethereum/go-ethereum/common" - gethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - evm_2_evm_onramp "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_v3_aggregator_contract" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" - testhelpers_new "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" - testhelpers "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0" -) - -func TestIntegration_legacy_CCIP(t *testing.T) { - // Run the batches of tests for both pipeline and dynamic price getter setups. - // We will remove the pipeline batch once the feature is deleted from the code. - tests := []struct { - name string - withPipeline bool - }{ - { - name: "with pipeline", - withPipeline: true, - }, - { - name: "with dynamic price getter", - withPipeline: false, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - ccipTH := testhelpers.SetupCCIPIntegrationTH(t, testhelpers.SourceChainID, testhelpers.SourceChainSelector, testhelpers.DestChainID, testhelpers.DestChainSelector) - - tokenPricesUSDPipeline := "" - priceGetterConfigJson := "" - - if test.withPipeline { - // Set up a test pipeline. - testPricePipeline, linkUSD, ethUSD := ccipTH.CreatePricesPipeline(t) - defer linkUSD.Close() - defer ethUSD.Close() - tokenPricesUSDPipeline = testPricePipeline - } else { - // Set up a test price getter. - // Set up the aggregators here to avoid modifying ccipTH. - aggSrcNatAddr, _, aggSrcNat, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(ccipTH.Source.User, ccipTH.Source.Chain.Client(), 18, big.NewInt(2e18)) - require.NoError(t, err) - _, err = aggSrcNat.UpdateRoundData(ccipTH.Source.User, big.NewInt(50), big.NewInt(17000000), big.NewInt(1000), big.NewInt(1000)) - require.NoError(t, err) - ccipTH.Source.Chain.Commit() - - aggDstLnkAddr, _, aggDstLnk, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(ccipTH.Dest.User, ccipTH.Dest.Chain.Client(), 18, big.NewInt(3e18)) - require.NoError(t, err) - ccipTH.Dest.Chain.Commit() - _, err = aggDstLnk.UpdateRoundData(ccipTH.Dest.User, big.NewInt(50), big.NewInt(8000000), big.NewInt(1000), big.NewInt(1000)) - require.NoError(t, err) - ccipTH.Dest.Chain.Commit() - - priceGetterConfig := config.DynamicPriceGetterConfig{ - AggregatorPrices: map[common.Address]config.AggregatorPriceConfig{ - ccipTH.Source.WrappedNative.Address(): { - ChainID: ccipTH.Source.ChainID, - AggregatorContractAddress: aggSrcNatAddr, - }, - ccipTH.Dest.LinkToken.Address(): { - ChainID: ccipTH.Dest.ChainID, - AggregatorContractAddress: aggDstLnkAddr, - }, - ccipTH.Dest.WrappedNative.Address(): { - ChainID: ccipTH.Dest.ChainID, - AggregatorContractAddress: aggDstLnkAddr, - }, - }, - StaticPrices: map[common.Address]config.StaticPriceConfig{}, - } - priceGetterConfigBytes, err := json.MarshalIndent(priceGetterConfig, "", " ") - require.NoError(t, err) - priceGetterConfigJson = string(priceGetterConfigBytes) - } - - jobParams := ccipTH.SetUpNodesAndJobs(t, tokenPricesUSDPipeline, priceGetterConfigJson, "") - - currentSeqNum := 1 - - t.Run("single", func(t *testing.T) { - tokenAmount := big.NewInt(500000003) // prime number - gasLimit := big.NewInt(200_003) // prime number - - extraArgs, err2 := testhelpers.GetEVMExtraArgsV1(gasLimit, false) - require.NoError(t, err2) - - sourceBalances, err2 := testhelpers.GetBalances(t, []testhelpers.BalanceReq{ - {Name: testhelpers.SourcePool, Addr: ccipTH.Source.LinkTokenPool.Address(), Getter: ccipTH.GetSourceLinkBalance}, - {Name: testhelpers.OnRamp, Addr: ccipTH.Source.OnRamp.Address(), Getter: ccipTH.GetSourceLinkBalance}, - {Name: testhelpers.SourceRouter, Addr: ccipTH.Source.Router.Address(), Getter: ccipTH.GetSourceLinkBalance}, - {Name: testhelpers.SourcePriceRegistry, Addr: ccipTH.Source.PriceRegistry.Address(), Getter: ccipTH.GetSourceLinkBalance}, - }) - require.NoError(t, err2) - destBalances, err2 := testhelpers.GetBalances(t, []testhelpers.BalanceReq{ - {Name: testhelpers.Receiver, Addr: ccipTH.Dest.Receivers[0].Receiver.Address(), Getter: ccipTH.GetDestLinkBalance}, - {Name: testhelpers.DestPool, Addr: ccipTH.Dest.LinkTokenPool.Address(), Getter: ccipTH.GetDestLinkBalance}, - {Name: testhelpers.OffRamp, Addr: ccipTH.Dest.OffRamp.Address(), Getter: ccipTH.GetDestLinkBalance}, - }) - require.NoError(t, err2) - - ccipTH.Source.User.Value = tokenAmount - _, err2 = ccipTH.Source.WrappedNative.Deposit(ccipTH.Source.User) - require.NoError(t, err2) - ccipTH.Source.Chain.Commit() - ccipTH.Source.User.Value = nil - - msg := router.ClientEVM2AnyMessage{ - Receiver: testhelpers.MustEncodeAddress(t, ccipTH.Dest.Receivers[0].Receiver.Address()), - Data: []byte("hello"), - TokenAmounts: []router.ClientEVMTokenAmount{ - { - Token: ccipTH.Source.LinkToken.Address(), - Amount: tokenAmount, - }, - { - Token: ccipTH.Source.WrappedNative.Address(), - Amount: tokenAmount, - }, - }, - FeeToken: ccipTH.Source.LinkToken.Address(), - ExtraArgs: extraArgs, - } - fee, err2 := ccipTH.Source.Router.GetFee(nil, testhelpers.DestChainSelector, msg) - require.NoError(t, err2) - // Currently no overhead and 10gwei dest gas price. So fee is simply (gasLimit * gasPrice)* link/native - // require.Equal(t, new(big.Int).Mul(gasLimit, gasPrice).String(), fee.String()) - // Approve the fee amount + the token amount - _, err2 = ccipTH.Source.LinkToken.Approve(ccipTH.Source.User, ccipTH.Source.Router.Address(), new(big.Int).Add(fee, tokenAmount)) - require.NoError(t, err2) - ccipTH.Source.Chain.Commit() - _, err2 = ccipTH.Source.WrappedNative.Approve(ccipTH.Source.User, ccipTH.Source.Router.Address(), tokenAmount) - require.NoError(t, err2) - ccipTH.Source.Chain.Commit() - - ccipTH.SendRequest(t, msg) - // Should eventually see this executed. - ccipTH.AllNodesHaveReqSeqNum(t, currentSeqNum) - ccipTH.EventuallyReportCommitted(t, currentSeqNum) - - executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum) - assert.Len(t, executionLogs, 1) - ccipTH.AssertExecState(t, executionLogs[0], testhelpers.ExecutionStateSuccess) - - // Asserts - // 1) The total pool input == total pool output - // 2) Pool flow equals tokens sent - // 3) Sent tokens arrive at the receiver - ccipTH.AssertBalances(t, []testhelpers.BalanceAssertion{ - { - Name: testhelpers.SourcePool, - Address: ccipTH.Source.LinkTokenPool.Address(), - Expected: testhelpers.MustAddBigInt(sourceBalances[testhelpers.SourcePool], tokenAmount.String()).String(), - Getter: ccipTH.GetSourceLinkBalance, - }, - { - Name: testhelpers.SourcePriceRegistry, - Address: ccipTH.Source.PriceRegistry.Address(), - Expected: sourceBalances[testhelpers.SourcePriceRegistry].String(), - Getter: ccipTH.GetSourceLinkBalance, - }, - { - // Fees end up in the onramp. - Name: testhelpers.OnRamp, - Address: ccipTH.Source.OnRamp.Address(), - Expected: testhelpers.MustAddBigInt(sourceBalances[testhelpers.SourcePriceRegistry], fee.String()).String(), - Getter: ccipTH.GetSourceLinkBalance, - }, - { - Name: testhelpers.SourceRouter, - Address: ccipTH.Source.Router.Address(), - Expected: sourceBalances[testhelpers.SourceRouter].String(), - Getter: ccipTH.GetSourceLinkBalance, - }, - { - Name: testhelpers.Receiver, - Address: ccipTH.Dest.Receivers[0].Receiver.Address(), - Expected: testhelpers.MustAddBigInt(destBalances[testhelpers.Receiver], tokenAmount.String()).String(), - Getter: ccipTH.GetDestLinkBalance, - }, - { - Name: testhelpers.DestPool, - Address: ccipTH.Dest.LinkTokenPool.Address(), - Expected: testhelpers.MustSubBigInt(destBalances[testhelpers.DestPool], tokenAmount.String()).String(), - Getter: ccipTH.GetDestLinkBalance, - }, - { - Name: testhelpers.OffRamp, - Address: ccipTH.Dest.OffRamp.Address(), - Expected: destBalances[testhelpers.OffRamp].String(), - Getter: ccipTH.GetDestLinkBalance, - }, - }) - currentSeqNum++ - }) - - t.Run("multiple batches", func(t *testing.T) { - tokenAmount := big.NewInt(500000003) - gasLimit := big.NewInt(250_000) - - var txs []*gethtypes.Transaction - // Enough to require batched executions as gasLimit per tx is 250k -> 500k -> 750k .... - // The actual gas usage of executing 15 messages is higher than the gas limit for - // a single tx. This means that when batching is turned off, and we simply include - // all txs without checking gas, this also fails. - n := 15 - for i := 0; i < n; i++ { - txGasLimit := new(big.Int).Mul(gasLimit, big.NewInt(int64(i+1))) - extraArgs, err2 := testhelpers.GetEVMExtraArgsV1(txGasLimit, false) - require.NoError(t, err2) - msg := router.ClientEVM2AnyMessage{ - Receiver: testhelpers.MustEncodeAddress(t, ccipTH.Dest.Receivers[0].Receiver.Address()), - Data: []byte("hello"), - TokenAmounts: []router.ClientEVMTokenAmount{ - { - Token: ccipTH.Source.LinkToken.Address(), - Amount: tokenAmount, - }, - }, - FeeToken: ccipTH.Source.LinkToken.Address(), - ExtraArgs: extraArgs, - } - fee, err2 := ccipTH.Source.Router.GetFee(nil, testhelpers.DestChainSelector, msg) - require.NoError(t, err2) - // Currently no overhead and 1gwei dest gas price. So fee is simply gasLimit * gasPrice. - // require.Equal(t, new(big.Int).Mul(txGasLimit, gasPrice).String(), fee.String()) - // Approve the fee amount + the token amount - _, err2 = ccipTH.Source.LinkToken.Approve(ccipTH.Source.User, ccipTH.Source.Router.Address(), new(big.Int).Add(fee, tokenAmount)) - require.NoError(t, err2) - ccipTH.Source.Chain.Commit() - tx, err2 := ccipTH.Source.Router.CcipSend(ccipTH.Source.User, ccipTH.Dest.ChainSelector, msg) - require.NoError(t, err2) - ccipTH.Source.Chain.Commit() - txs = append(txs, tx) - } - - // Send a batch of requests in a single block - testhelpers_new.ConfirmTxs(t, txs, ccipTH.Source.Chain) - for i := 0; i < n; i++ { - ccipTH.AllNodesHaveReqSeqNum(t, currentSeqNum+i) - } - // Should see a report with the full range - ccipTH.EventuallyReportCommitted(t, currentSeqNum+n-1) - // Should all be executed - executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum+n-1) - for _, execLog := range executionLogs { - ccipTH.AssertExecState(t, execLog, testhelpers.ExecutionStateSuccess) - } - - currentSeqNum += n - }) - - // Deploy new on ramp,Commit store,off ramp - // Delete v1 jobs - // Send a number of requests - // Upgrade the router with new contracts - // create new jobs - // Verify all pending requests are sent after the contracts are upgraded - t.Run("upgrade contracts and verify requests can be sent with upgraded contract", func(t *testing.T) { - ctx := testutils.Context(t) - gasLimit := big.NewInt(200_003) // prime number - tokenAmount := big.NewInt(100) - commitStoreV1 := ccipTH.Dest.CommitStore - offRampV1 := ccipTH.Dest.OffRamp - onRampV1 := ccipTH.Source.OnRamp - // deploy v2 contracts - ccipTH.DeployNewOnRamp(t) - ccipTH.DeployNewCommitStore(t) - ccipTH.DeployNewOffRamp(t) - - // send a request as the v2 contracts are not enabled in router it should route through the v1 contracts - t.Logf("sending request for seqnum %d", currentSeqNum) - ccipTH.SendMessage(t, gasLimit, tokenAmount, ccipTH.Dest.Receivers[0].Receiver.Address()) - ccipTH.Source.Chain.Commit() - ccipTH.Dest.Chain.Commit() - t.Logf("verifying seqnum %d on previous onRamp %s", currentSeqNum, onRampV1.Address().Hex()) - ccipTH.AllNodesHaveReqSeqNum(t, currentSeqNum, onRampV1.Address()) - ccipTH.EventuallyReportCommitted(t, currentSeqNum, commitStoreV1.Address()) - executionLog := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum, offRampV1.Address()) - ccipTH.AssertExecState(t, executionLog[0], testhelpers.ExecutionStateSuccess, offRampV1.Address()) - - nonceAtOnRampV1, err := onRampV1.GetSenderNonce(nil, ccipTH.Source.User.From) - require.NoError(t, err, "getting nonce from onRamp") - require.Equal(t, currentSeqNum, int(nonceAtOnRampV1)) - nonceAtOffRampV1, err := offRampV1.GetSenderNonce(nil, ccipTH.Source.User.From) - require.NoError(t, err, "getting nonce from offRamp") - require.Equal(t, currentSeqNum, int(nonceAtOffRampV1)) - - // enable the newly deployed contracts - newConfigBlock, err := ccipTH.Dest.Chain.Client().BlockNumber(ctx) - require.NoError(t, err) - ccipTH.EnableOnRamp(t) - ccipTH.EnableCommitStore(t) - ccipTH.EnableOffRamp(t) - srcStartBlock, err := ccipTH.Source.Chain.Client().BlockNumber(ctx) - require.NoError(t, err) - - // send a number of requests, the requests should not be delivered yet as the previous contracts are not configured - // with the router anymore - startSeq := 1 - noOfRequests := 5 - endSeqNum := startSeq + noOfRequests - for i := startSeq; i <= endSeqNum; i++ { - t.Logf("sending request for seqnum %d", i) - ccipTH.SendMessage(t, gasLimit, tokenAmount, ccipTH.Dest.Receivers[0].Receiver.Address()) - ccipTH.Source.Chain.Commit() - ccipTH.Dest.Chain.Commit() - ccipTH.EventuallySendRequested(t, uint64(i)) - } - - // delete v1 jobs - for _, node := range ccipTH.Nodes { - id := node.FindJobIDForContract(t, commitStoreV1.Address()) - require.Greater(t, id, int32(0)) - t.Logf("deleting job %d", id) - err = node.App.DeleteJob(context.Background(), id) - require.NoError(t, err) - id = node.FindJobIDForContract(t, offRampV1.Address()) - require.Greater(t, id, int32(0)) - t.Logf("deleting job %d", id) - err = node.App.DeleteJob(context.Background(), id) - require.NoError(t, err) - } - - // Commit on both chains to reach Finality - ccipTH.Source.Chain.Commit() - ccipTH.Dest.Chain.Commit() - - // create new jobs - jobParams = ccipTH.NewCCIPJobSpecParams(tokenPricesUSDPipeline, priceGetterConfigJson, newConfigBlock, "") - jobParams.Version = "v2" - jobParams.SourceStartBlock = srcStartBlock - ccipTH.AddAllJobs(t, jobParams) - committedSeqNum := uint64(0) - // Now the requests should be delivered - for i := startSeq; i <= endSeqNum; i++ { - t.Logf("verifying seqnum %d", i) - ccipTH.AllNodesHaveReqSeqNum(t, i) - if committedSeqNum < uint64(i+1) { - committedSeqNum = ccipTH.EventuallyReportCommitted(t, i) - } - ccipTH.EventuallyExecutionStateChangedToSuccess(t, []uint64{uint64(i)}, uint64(newConfigBlock)) - } - - // nonces should be correctly synced from v1 contracts for the sender - nonceAtOnRampV2, err := ccipTH.Source.OnRamp.GetSenderNonce(nil, ccipTH.Source.User.From) - require.NoError(t, err, "getting nonce from onRamp") - nonceAtOffRampV2, err := ccipTH.Dest.OffRamp.GetSenderNonce(nil, ccipTH.Source.User.From) - require.NoError(t, err, "getting nonce from offRamp") - require.Equal(t, nonceAtOnRampV1+uint64(noOfRequests)+1, nonceAtOnRampV2, "nonce should be synced from v1 onRamps") - require.Equal(t, nonceAtOffRampV1+uint64(noOfRequests)+1, nonceAtOffRampV2, "nonce should be synced from v1 offRamps") - currentSeqNum = endSeqNum + 1 - }) - - t.Run("pay nops", func(t *testing.T) { - linkToTransferToOnRamp := big.NewInt(1e18) - - // transfer some link to onramp to pay the nops - _, err := ccipTH.Source.LinkToken.Transfer(ccipTH.Source.User, ccipTH.Source.OnRamp.Address(), linkToTransferToOnRamp) - require.NoError(t, err) - ccipTH.Source.Chain.Commit() - - srcBalReq := []testhelpers.BalanceReq{ - { - Name: testhelpers.Sender, - Addr: ccipTH.Source.User.From, - Getter: ccipTH.GetSourceWrappedTokenBalance, - }, - { - Name: testhelpers.OnRampNative, - Addr: ccipTH.Source.OnRamp.Address(), - Getter: ccipTH.GetSourceWrappedTokenBalance, - }, - { - Name: testhelpers.OnRamp, - Addr: ccipTH.Source.OnRamp.Address(), - Getter: ccipTH.GetSourceLinkBalance, - }, - { - Name: testhelpers.SourceRouter, - Addr: ccipTH.Source.Router.Address(), - Getter: ccipTH.GetSourceWrappedTokenBalance, - }, - } - - var nopsAndWeights []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight - var totalWeight uint16 - nodes := ccipTH.Nodes - for i := range nodes { - // For now set the transmitter addresses to be the same as the payee addresses - nodes[i].PaymentReceiver = nodes[i].Transmitter - nopsAndWeights = append(nopsAndWeights, evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight{ - Nop: nodes[i].PaymentReceiver, - Weight: 5, - }) - totalWeight += 5 - srcBalReq = append(srcBalReq, testhelpers.BalanceReq{ - Name: fmt.Sprintf("node %d", i), - Addr: nodes[i].PaymentReceiver, - Getter: ccipTH.GetSourceLinkBalance, - }) - } - srcBalances, err := testhelpers.GetBalances(t, srcBalReq) - require.NoError(t, err) - - // set nops on the onramp - ccipTH.SetNopsOnRamp(t, nopsAndWeights) - - // send a message - extraArgs, err := testhelpers.GetEVMExtraArgsV1(big.NewInt(200_000), true) - require.NoError(t, err) - - // FeeToken is empty, indicating it should use native token - msg := router.ClientEVM2AnyMessage{ - Receiver: testhelpers.MustEncodeAddress(t, ccipTH.Dest.Receivers[1].Receiver.Address()), - Data: []byte("hello"), - TokenAmounts: []router.ClientEVMTokenAmount{}, - ExtraArgs: extraArgs, - FeeToken: common.Address{}, - } - fee, err := ccipTH.Source.Router.GetFee(nil, testhelpers.DestChainSelector, msg) - require.NoError(t, err) - - // verify message is sent - ccipTH.Source.User.Value = fee - ccipTH.SendRequest(t, msg) - ccipTH.Source.User.Value = nil - ccipTH.AllNodesHaveReqSeqNum(t, currentSeqNum) - ccipTH.EventuallyReportCommitted(t, currentSeqNum) - - executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum) - assert.Len(t, executionLogs, 1) - ccipTH.AssertExecState(t, executionLogs[0], testhelpers.ExecutionStateSuccess) - currentSeqNum++ - - // get the nop fee - nopFee, err := ccipTH.Source.OnRamp.GetNopFeesJuels(nil) - require.NoError(t, err) - t.Log("nopFee", nopFee) - - // withdraw fees and verify there is still fund left for nop payment - _, err = ccipTH.Source.OnRamp.WithdrawNonLinkFees( - ccipTH.Source.User, - ccipTH.Source.WrappedNative.Address(), - ccipTH.Source.User.From, - ) - require.NoError(t, err) - ccipTH.Source.Chain.Commit() - - // pay nops - _, err = ccipTH.Source.OnRamp.PayNops(ccipTH.Source.User) - require.NoError(t, err) - ccipTH.Source.Chain.Commit() - - srcBalanceAssertions := []testhelpers.BalanceAssertion{ - { - // Onramp should not have any balance left in wrapped native - Name: testhelpers.OnRampNative, - Address: ccipTH.Source.OnRamp.Address(), - Expected: big.NewInt(0).String(), - Getter: ccipTH.GetSourceWrappedTokenBalance, - }, - { - // Onramp should have the remaining link after paying nops - Name: testhelpers.OnRamp, - Address: ccipTH.Source.OnRamp.Address(), - Expected: new(big.Int).Sub(srcBalances[testhelpers.OnRamp], nopFee).String(), - Getter: ccipTH.GetSourceLinkBalance, - }, - { - Name: testhelpers.SourceRouter, - Address: ccipTH.Source.Router.Address(), - Expected: srcBalances[testhelpers.SourceRouter].String(), - Getter: ccipTH.GetSourceWrappedTokenBalance, - }, - // onRamp's balance (of previously sent fee during message sending) should have been transferred to - // the owner as a result of WithdrawNonLinkFees - { - Name: testhelpers.Sender, - Address: ccipTH.Source.User.From, - Expected: fee.String(), - Getter: ccipTH.GetSourceWrappedTokenBalance, - }, - } - - // the nodes should be paid according to the weights assigned - for i, node := range nodes { - paymentWeight := float64(nopsAndWeights[i].Weight) / float64(totalWeight) - paidInFloat := paymentWeight * float64(nopFee.Int64()) - paid, _ := new(big.Float).SetFloat64(paidInFloat).Int64() - bal := new(big.Int).Add( - new(big.Int).SetInt64(paid), - srcBalances[fmt.Sprintf("node %d", i)]).String() - srcBalanceAssertions = append(srcBalanceAssertions, testhelpers.BalanceAssertion{ - Name: fmt.Sprintf("node %d", i), - Address: node.PaymentReceiver, - Expected: bal, - Getter: ccipTH.GetSourceLinkBalance, - }) - } - ccipTH.AssertBalances(t, srcBalanceAssertions) - }) - - // Keep on sending a bunch of messages - // In the meantime update onchainConfig with new price registry address - // Verify if the jobs can pick up updated config - // Verify if all the messages are sent - t.Run("config change or price registry update while requests are inflight", func(t *testing.T) { - gasLimit := big.NewInt(200_003) // prime number - tokenAmount := big.NewInt(100) - msgWg := &sync.WaitGroup{} - msgWg.Add(1) - ticker := time.NewTicker(100 * time.Millisecond) - defer ticker.Stop() - startSeq := currentSeqNum - endSeq := currentSeqNum + 20 - - // send message with the old configs - ccipTH.SendMessage(t, gasLimit, tokenAmount, ccipTH.Dest.Receivers[0].Receiver.Address()) - ccipTH.Source.Chain.Commit() - - go func(ccipContracts testhelpers.CCIPContracts, currentSeqNum int) { - seqNumber := currentSeqNum + 1 - defer msgWg.Done() - for { - <-ticker.C // wait for ticker - t.Logf("sending request for seqnum %d", seqNumber) - ccipContracts.SendMessage(t, gasLimit, tokenAmount, ccipTH.Dest.Receivers[0].Receiver.Address()) - ccipContracts.Source.Chain.Commit() - seqNumber++ - if seqNumber == endSeq { - return - } - } - }(ccipTH.CCIPContracts, currentSeqNum) - - ccipTH.DeployNewPriceRegistry(t) - commitOnchainConfig := ccipTH.CreateDefaultCommitOnchainConfig(t) - commitOffchainConfig := ccipTH.CreateDefaultCommitOffchainConfig(t) - execOnchainConfig := ccipTH.CreateDefaultExecOnchainConfig(t) - execOffchainConfig := ccipTH.CreateDefaultExecOffchainConfig(t) - - ccipTH.SetupOnchainConfig(t, commitOnchainConfig, commitOffchainConfig, execOnchainConfig, execOffchainConfig) - - // wait for all requests to be complete - msgWg.Wait() - for i := startSeq; i < endSeq; i++ { - ccipTH.AllNodesHaveReqSeqNum(t, i) - ccipTH.EventuallyReportCommitted(t, i) - - executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, i, i) - assert.Len(t, executionLogs, 1) - ccipTH.AssertExecState(t, executionLogs[0], testhelpers.ExecutionStateSuccess) - } - - for i, node := range ccipTH.Nodes { - t.Logf("verifying node %d", i) - node.EventuallyNodeUsesNewCommitConfig(t, ccipTH, ccipdata.CommitOnchainConfig{ - PriceRegistry: ccipTH.Dest.PriceRegistry.Address(), - }) - node.EventuallyNodeUsesNewExecConfig(t, ccipTH, v1_2_0.ExecOnchainConfig{ - PermissionLessExecutionThresholdSeconds: testhelpers.PermissionLessExecutionThresholdSeconds, - Router: ccipTH.Dest.Router.Address(), - PriceRegistry: ccipTH.Dest.PriceRegistry.Address(), - MaxDataBytes: 1e5, - MaxNumberOfTokensPerMsg: 5, - MaxPoolReleaseOrMintGas: 200_000, - }) - node.EventuallyNodeUsesUpdatedPriceRegistry(t, ccipTH) - } - currentSeqNum = endSeq - }) - }) - } -} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go index 6a220ececf7..c2fec2903e8 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go @@ -5,6 +5,7 @@ import ( "fmt" "math" "math/big" + "sync" "testing" "time" @@ -168,11 +169,32 @@ type MaybeRevertReceiver struct { Strict bool } +// Backend wraps a simulated backend with a mutex to make it safe for concurrent use +// Commit() in particular has caused races. +type Backend struct { + mu sync.Mutex + *simulated.Backend +} + +func NewBackend(sim *simulated.Backend) *Backend { + return &Backend{ + mu: sync.Mutex{}, + Backend: sim, + } +} + +func (b *Backend) Commit() common.Hash { + b.mu.Lock() + defer b.mu.Unlock() + + return b.Backend.Commit() +} + type Common struct { ChainID uint64 ChainSelector uint64 User *bind.TransactOpts - Chain *simulated.Backend + Chain *Backend LinkToken *link_token_interface.LinkToken LinkTokenPool *lock_release_token_pool.LockReleaseTokenPool CustomToken *link_token_interface.LinkToken @@ -1194,7 +1216,7 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh ChainID: sourceChainID, ChainSelector: sourceChainSelector, User: sourceUser, - Chain: sourceChain, + Chain: NewBackend(sourceChain), LinkToken: sourceLinkToken, LinkTokenPool: sourceLinkPool, CustomToken: sourceCustomToken, @@ -1214,7 +1236,7 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh ChainID: destChainID, ChainSelector: destChainSelector, User: destUser, - Chain: destChain, + Chain: NewBackend(destChain), LinkToken: destLinkToken, LinkTokenPool: destLinkPool, CustomToken: destCustomToken, diff --git a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go index ddae5241883..d21c5b12513 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go @@ -17,7 +17,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" types3 "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethclient/simulated" "github.com/google/uuid" "github.com/hashicorp/consul/sdk/freeport" "github.com/jmoiron/sqlx" @@ -369,7 +368,7 @@ func setupNodeCCIP( owner *bind.TransactOpts, port int64, dbName string, - sourceChain *simulated.Backend, destChain *simulated.Backend, + sourceChain *testhelpers.Backend, destChain *testhelpers.Backend, sourceChainID *big.Int, destChainID *big.Int, bootstrapPeerID string, bootstrapPort int64, diff --git a/core/services/ocr2/plugins/ccip/testhelpers/simulated_backend.go b/core/services/ocr2/plugins/ccip/testhelpers/simulated_backend.go index 58206d37427..699af7e14dc 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/simulated_backend.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/simulated_backend.go @@ -56,7 +56,7 @@ func (ks EthKeyStoreSim) Eth() keystore.Eth { var _ keystore.Eth = EthKeyStoreSim{}.ETHKS -func ConfirmTxs(t *testing.T, txs []*ethtypes.Transaction, chain *simulated.Backend) { +func ConfirmTxs(t *testing.T, txs []*ethtypes.Transaction, chain *Backend) { chain.Commit() ctx := tests.Context(t) for _, tx := range txs { diff --git a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go deleted file mode 100644 index 5ed20875498..00000000000 --- a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/ccip_contracts_1_4_0.go +++ /dev/null @@ -1,1620 +0,0 @@ -package testhelpers_1_4_0 - -import ( - "context" - "fmt" - "math" - "math/big" - "testing" - "time" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethclient/simulated" - "github.com/pkg/errors" - "github.com/rs/zerolog/log" - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" - ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - - "github.com/smartcontractkit/chainlink-common/pkg/config" - "github.com/smartcontractkit/chainlink-common/pkg/hashutil" - "github.com/smartcontractkit/chainlink-common/pkg/merklemulti" - cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" - - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - burn_mint_token_pool "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/burn_mint_token_pool_1_4_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_2_0" - evm_2_evm_offramp "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" - evm_2_evm_onramp "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool_1_0_0" - lock_release_token_pool "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/lock_release_token_pool_1_4_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" - "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" - ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" -) - -var ( - // Source - SourcePool = "source Link pool" - SourcePriceRegistry = "source PriceRegistry" - OnRamp = "onramp" - OnRampNative = "onramp-native" - SourceRouter = "source router" - - // Dest - OffRamp = "offramp" - DestPool = "dest Link pool" - - Receiver = "receiver" - Sender = "sender" - Link = func(amount int64) *big.Int { return new(big.Int).Mul(big.NewInt(1e18), big.NewInt(amount)) } - HundredLink = Link(100) - LinkUSDValue = func(amount int64) *big.Int { return new(big.Int).Mul(big.NewInt(1e18), big.NewInt(amount)) } - SourceChainID = uint64(1000) - SourceChainSelector = uint64(11787463284727550157) - DestChainID = uint64(1337) - DestChainSelector = uint64(3379446385462418246) -) - -// Backwards compat, in principle these statuses are version dependent -// TODO: Adjust integration tests to be version agnostic using readers -var ( - ExecutionStateSuccess = MessageExecutionState(cciptypes.ExecutionStateSuccess) - ExecutionStateFailure = MessageExecutionState(cciptypes.ExecutionStateFailure) -) - -type MessageExecutionState cciptypes.MessageExecutionState -type CommitOffchainConfig struct { - v1_2_0.JSONCommitOffchainConfig -} - -func (c CommitOffchainConfig) Encode() ([]byte, error) { - return ccipconfig.EncodeOffchainConfig(c.JSONCommitOffchainConfig) -} - -func NewCommitOffchainConfig( - GasPriceHeartBeat config.Duration, - DAGasPriceDeviationPPB uint32, - ExecGasPriceDeviationPPB uint32, - TokenPriceHeartBeat config.Duration, - TokenPriceDeviationPPB uint32, - InflightCacheExpiry config.Duration, - priceReportingDisabled bool) CommitOffchainConfig { - return CommitOffchainConfig{v1_2_0.JSONCommitOffchainConfig{ - GasPriceHeartBeat: GasPriceHeartBeat, - DAGasPriceDeviationPPB: DAGasPriceDeviationPPB, - ExecGasPriceDeviationPPB: ExecGasPriceDeviationPPB, - TokenPriceHeartBeat: TokenPriceHeartBeat, - TokenPriceDeviationPPB: TokenPriceDeviationPPB, - InflightCacheExpiry: InflightCacheExpiry, - PriceReportingDisabled: priceReportingDisabled, - }} -} - -type CommitOnchainConfig struct { - ccipdata.CommitOnchainConfig -} - -func NewCommitOnchainConfig( - PriceRegistry common.Address, -) CommitOnchainConfig { - return CommitOnchainConfig{ccipdata.CommitOnchainConfig{ - PriceRegistry: PriceRegistry, - }} -} - -type ExecOnchainConfig struct { - v1_2_0.ExecOnchainConfig -} - -func NewExecOnchainConfig( - PermissionLessExecutionThresholdSeconds uint32, - Router common.Address, - PriceRegistry common.Address, - MaxNumberOfTokensPerMsg uint16, - MaxDataBytes uint32, - MaxPoolReleaseOrMintGas uint32, -) ExecOnchainConfig { - return ExecOnchainConfig{v1_2_0.ExecOnchainConfig{ - PermissionLessExecutionThresholdSeconds: PermissionLessExecutionThresholdSeconds, - Router: Router, - PriceRegistry: PriceRegistry, - MaxNumberOfTokensPerMsg: MaxNumberOfTokensPerMsg, - MaxDataBytes: MaxDataBytes, - MaxPoolReleaseOrMintGas: MaxPoolReleaseOrMintGas, - }} -} - -type ExecOffchainConfig struct { - v1_2_0.JSONExecOffchainConfig -} - -func (c ExecOffchainConfig) Encode() ([]byte, error) { - return ccipconfig.EncodeOffchainConfig(c.JSONExecOffchainConfig) -} - -func NewExecOffchainConfig( - DestOptimisticConfirmations uint32, - BatchGasLimit uint32, - RelativeBoostPerWaitHour float64, - InflightCacheExpiry config.Duration, - RootSnoozeTime config.Duration, - BatchingStrategyID uint32, -) ExecOffchainConfig { - return ExecOffchainConfig{v1_2_0.JSONExecOffchainConfig{ - DestOptimisticConfirmations: DestOptimisticConfirmations, - BatchGasLimit: BatchGasLimit, - RelativeBoostPerWaitHour: RelativeBoostPerWaitHour, - InflightCacheExpiry: InflightCacheExpiry, - RootSnoozeTime: RootSnoozeTime, - BatchingStrategyID: BatchingStrategyID, - }} -} - -type MaybeRevertReceiver struct { - Receiver *maybe_revert_message_receiver.MaybeRevertMessageReceiver - Strict bool -} - -type Common struct { - ChainID uint64 - ChainSelector uint64 - User *bind.TransactOpts - Chain *simulated.Backend - LinkToken *link_token_interface.LinkToken - LinkTokenPool *lock_release_token_pool.LockReleaseTokenPool - CustomToken *link_token_interface.LinkToken - WrappedNative *weth9.WETH9 - WrappedNativePool *lock_release_token_pool_1_0_0.LockReleaseTokenPool - ARM *mock_rmn_contract.MockRMNContract - ARMProxy *rmn_proxy_contract.RMNProxyContract - PriceRegistry *price_registry_1_2_0.PriceRegistry -} - -type SourceChain struct { - Common - Router *router.Router - OnRamp *evm_2_evm_onramp.EVM2EVMOnRamp -} - -type DestinationChain struct { - Common - - CommitStore *commit_store_1_2_0.CommitStore - Router *router.Router - OffRamp *evm_2_evm_offramp.EVM2EVMOffRamp - Receivers []MaybeRevertReceiver -} - -type OCR2Config struct { - Signers []common.Address - Transmitters []common.Address - F uint8 - OnchainConfig []byte - OffchainConfigVersion uint64 - OffchainConfig []byte -} - -type BalanceAssertion struct { - Name string - Address common.Address - Expected string - Getter func(t *testing.T, addr common.Address) *big.Int - Within string -} - -type BalanceReq struct { - Name string - Addr common.Address - Getter func(t *testing.T, addr common.Address) *big.Int -} - -type CCIPContracts struct { - Source SourceChain - Dest DestinationChain - Oracles []confighelper.OracleIdentityExtra - - commitOCRConfig, execOCRConfig *OCR2Config -} - -func (c *CCIPContracts) DeployNewOffRamp(t *testing.T) { - prevOffRamp := common.HexToAddress("") - if c.Dest.OffRamp != nil { - prevOffRamp = c.Dest.OffRamp.Address() - } - offRampAddress, _, _, err := evm_2_evm_offramp.DeployEVM2EVMOffRamp( - c.Dest.User, - c.Dest.Chain.Client(), - evm_2_evm_offramp.EVM2EVMOffRampStaticConfig{ - CommitStore: c.Dest.CommitStore.Address(), - ChainSelector: c.Dest.ChainSelector, - SourceChainSelector: c.Source.ChainSelector, - OnRamp: c.Source.OnRamp.Address(), - PrevOffRamp: prevOffRamp, - ArmProxy: c.Dest.ARMProxy.Address(), - }, - []common.Address{c.Source.LinkToken.Address()}, // source tokens - []common.Address{c.Dest.LinkTokenPool.Address()}, // pools - evm_2_evm_offramp.RateLimiterConfig{ - IsEnabled: true, - Capacity: LinkUSDValue(100), - Rate: LinkUSDValue(1), - }, - ) - require.NoError(t, err) - c.Dest.Chain.Commit() - - c.Dest.OffRamp, err = evm_2_evm_offramp.NewEVM2EVMOffRamp(offRampAddress, c.Dest.Chain.Client()) - require.NoError(t, err) - - c.Dest.Chain.Commit() - c.Source.Chain.Commit() -} - -func (c *CCIPContracts) EnableOffRamp(t *testing.T) { - _, err := c.Dest.Router.ApplyRampUpdates(c.Dest.User, nil, nil, []router.RouterOffRamp{{SourceChainSelector: SourceChainSelector, OffRamp: c.Dest.OffRamp.Address()}}) - require.NoError(t, err) - c.Dest.Chain.Commit() - - onChainConfig := c.CreateDefaultExecOnchainConfig(t) - offChainConfig := c.CreateDefaultExecOffchainConfig(t) - - c.SetupExecOCR2Config(t, onChainConfig, offChainConfig) -} - -func (c *CCIPContracts) EnableCommitStore(t *testing.T) { - onChainConfig := c.CreateDefaultCommitOnchainConfig(t) - offChainConfig := c.CreateDefaultCommitOffchainConfig(t) - - c.SetupCommitOCR2Config(t, onChainConfig, offChainConfig) - - _, err := c.Dest.PriceRegistry.ApplyPriceUpdatersUpdates(c.Dest.User, []common.Address{c.Dest.CommitStore.Address()}, []common.Address{}) - require.NoError(t, err) - c.Dest.Chain.Commit() -} - -func (c *CCIPContracts) DeployNewOnRamp(t *testing.T) { - t.Log("Deploying new onRamp") - // find the last onRamp - prevOnRamp := common.HexToAddress("") - if c.Source.OnRamp != nil { - prevOnRamp = c.Source.OnRamp.Address() - } - onRampAddress, _, _, err := evm_2_evm_onramp.DeployEVM2EVMOnRamp( - c.Source.User, // user - c.Source.Chain.Client(), // client - evm_2_evm_onramp.EVM2EVMOnRampStaticConfig{ - LinkToken: c.Source.LinkToken.Address(), - ChainSelector: c.Source.ChainSelector, - DestChainSelector: c.Dest.ChainSelector, - DefaultTxGasLimit: 200_000, - MaxNopFeesJuels: big.NewInt(0).Mul(big.NewInt(100_000_000), big.NewInt(1e18)), - PrevOnRamp: prevOnRamp, - ArmProxy: c.Source.ARM.Address(), // ARM - }, - evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{ - Router: c.Source.Router.Address(), - MaxNumberOfTokensPerMsg: 5, - DestGasOverhead: 350_000, - DestGasPerPayloadByte: 16, - DestDataAvailabilityOverheadGas: 33_596, - DestGasPerDataAvailabilityByte: 16, - DestDataAvailabilityMultiplierBps: 6840, // 0.684 - PriceRegistry: c.Source.PriceRegistry.Address(), - MaxDataBytes: 1e5, - MaxPerMsgGasLimit: 4_000_000, - }, - []evm_2_evm_onramp.InternalPoolUpdate{ - { - Token: c.Source.LinkToken.Address(), - Pool: c.Source.LinkTokenPool.Address(), - }, - }, - evm_2_evm_onramp.RateLimiterConfig{ - IsEnabled: true, - Capacity: LinkUSDValue(100), - Rate: LinkUSDValue(1), - }, - []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs{ - { - Token: c.Source.LinkToken.Address(), - NetworkFeeUSDCents: 1_00, - GasMultiplierWeiPerEth: 1e18, - PremiumMultiplierWeiPerEth: 9e17, - Enabled: true, - }, - { - Token: c.Source.WrappedNative.Address(), - NetworkFeeUSDCents: 1_00, - GasMultiplierWeiPerEth: 1e18, - PremiumMultiplierWeiPerEth: 1e18, - Enabled: true, - }, - }, - []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs{ - { - Token: c.Source.LinkToken.Address(), - MinFeeUSDCents: 50, // $0.5 - MaxFeeUSDCents: 1_000_000_00, // $ 1 million - DeciBps: 5_0, // 5 bps - DestGasOverhead: 34_000, - DestBytesOverhead: 32, - }, - }, - []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight{}, - ) - - require.NoError(t, err) - c.Source.Chain.Commit() - c.Dest.Chain.Commit() - c.Source.OnRamp, err = evm_2_evm_onramp.NewEVM2EVMOnRamp(onRampAddress, c.Source.Chain.Client()) - require.NoError(t, err) - c.Source.Chain.Commit() - c.Dest.Chain.Commit() -} - -func (c *CCIPContracts) EnableOnRamp(t *testing.T) { - t.Log("Setting onRamp on source router") - _, err := c.Source.Router.ApplyRampUpdates(c.Source.User, []router.RouterOnRamp{{DestChainSelector: c.Dest.ChainSelector, OnRamp: c.Source.OnRamp.Address()}}, nil, nil) - require.NoError(t, err) - c.Source.Chain.Commit() - c.Dest.Chain.Commit() -} - -func (c *CCIPContracts) DeployNewCommitStore(t *testing.T) { - commitStoreAddress, _, _, err := commit_store_1_2_0.DeployCommitStore( - c.Dest.User, // user - c.Dest.Chain.Client(), // client - commit_store_1_2_0.CommitStoreStaticConfig{ - ChainSelector: c.Dest.ChainSelector, - SourceChainSelector: c.Source.ChainSelector, - OnRamp: c.Source.OnRamp.Address(), - ArmProxy: c.Dest.ARMProxy.Address(), - }, - ) - require.NoError(t, err) - c.Dest.Chain.Commit() - // since CommitStoreHelper derives from CommitStore, it's safe to instantiate both on same address - c.Dest.CommitStore, err = commit_store_1_2_0.NewCommitStore(commitStoreAddress, c.Dest.Chain.Client()) - require.NoError(t, err) -} - -func (c *CCIPContracts) DeployNewPriceRegistry(t *testing.T) { - t.Log("Deploying new Price Registry") - destPricesAddress, _, _, err := price_registry_1_2_0.DeployPriceRegistry( - c.Dest.User, - c.Dest.Chain.Client(), - []common.Address{c.Dest.CommitStore.Address()}, - []common.Address{c.Dest.LinkToken.Address()}, - 60*60*24*14, // two weeks - ) - require.NoError(t, err) - c.Source.Chain.Commit() - c.Dest.Chain.Commit() - c.Dest.PriceRegistry, err = price_registry_1_2_0.NewPriceRegistry(destPricesAddress, c.Dest.Chain.Client()) - require.NoError(t, err) - - priceUpdates := price_registry_1_2_0.InternalPriceUpdates{ - TokenPriceUpdates: []price_registry_1_2_0.InternalTokenPriceUpdate{ - { - SourceToken: c.Dest.LinkToken.Address(), - UsdPerToken: big.NewInt(8e18), // 8usd - }, - { - SourceToken: c.Dest.WrappedNative.Address(), - UsdPerToken: big.NewInt(1e18), // 1usd - }, - }, - GasPriceUpdates: []price_registry_1_2_0.InternalGasPriceUpdate{ - { - DestChainSelector: c.Source.ChainSelector, - UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 - }, - }, - } - _, err = c.Dest.PriceRegistry.UpdatePrices(c.Dest.User, priceUpdates) - require.NoError(t, err) - - c.Source.Chain.Commit() - c.Dest.Chain.Commit() - - t.Logf("New Price Registry deployed at %s", destPricesAddress.String()) -} - -func (c *CCIPContracts) SetNopsOnRamp(t *testing.T, nopsAndWeights []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight) { - tx, err := c.Source.OnRamp.SetNops(c.Source.User, nopsAndWeights) - require.NoError(t, err) - c.Source.Chain.Commit() - _, err = bind.WaitMined(tests.Context(t), c.Source.Chain.Client(), tx) - require.NoError(t, err) -} - -func (c *CCIPContracts) GetSourceLinkBalance(t *testing.T, addr common.Address) *big.Int { - return GetBalance(t, c.Source.Chain.Client(), c.Source.LinkToken.Address(), addr) -} - -func (c *CCIPContracts) GetDestLinkBalance(t *testing.T, addr common.Address) *big.Int { - return GetBalance(t, c.Dest.Chain.Client(), c.Dest.LinkToken.Address(), addr) -} - -func (c *CCIPContracts) GetSourceWrappedTokenBalance(t *testing.T, addr common.Address) *big.Int { - return GetBalance(t, c.Source.Chain.Client(), c.Source.WrappedNative.Address(), addr) -} - -func (c *CCIPContracts) GetDestWrappedTokenBalance(t *testing.T, addr common.Address) *big.Int { - return GetBalance(t, c.Dest.Chain.Client(), c.Dest.WrappedNative.Address(), addr) -} - -func (c *CCIPContracts) AssertBalances(t *testing.T, bas []BalanceAssertion) { - for _, b := range bas { - actual := b.Getter(t, b.Address) - t.Log("Checking balance for", b.Name, "at", b.Address.Hex(), "got", actual) - require.NotNil(t, actual, "%v getter return nil", b.Name) - if b.Within == "" { - require.Equal(t, b.Expected, actual.String(), "wrong balance for %s got %s want %s", b.Name, actual, b.Expected) - } else { - bi, _ := big.NewInt(0).SetString(b.Expected, 10) - withinI, _ := big.NewInt(0).SetString(b.Within, 10) - high := big.NewInt(0).Add(bi, withinI) - low := big.NewInt(0).Sub(bi, withinI) - require.Equal(t, -1, actual.Cmp(high), "wrong balance for %s got %s outside expected range [%s, %s]", b.Name, actual, low, high) - require.Equal(t, 1, actual.Cmp(low), "wrong balance for %s got %s outside expected range [%s, %s]", b.Name, actual, low, high) - } - } -} - -func AccountToAddress(accounts []ocr2types.Account) (addresses []common.Address, err error) { - for _, signer := range accounts { - bytes, err := hexutil.Decode(string(signer)) - if err != nil { - return []common.Address{}, errors.Wrap(err, fmt.Sprintf("given address is not valid %s", signer)) - } - if len(bytes) != 20 { - return []common.Address{}, errors.Errorf("address is not 20 bytes %s", signer) - } - addresses = append(addresses, common.BytesToAddress(bytes)) - } - return addresses, nil -} - -func OnchainPublicKeyToAddress(publicKeys []ocrtypes.OnchainPublicKey) (addresses []common.Address, err error) { - for _, signer := range publicKeys { - if len(signer) != 20 { - return []common.Address{}, errors.Errorf("address is not 20 bytes %s", signer) - } - addresses = append(addresses, common.BytesToAddress(signer)) - } - return addresses, nil -} - -func (c *CCIPContracts) DeriveOCR2Config(t *testing.T, oracles []confighelper.OracleIdentityExtra, rawOnchainConfig []byte, rawOffchainConfig []byte) *OCR2Config { - signers, transmitters, threshold, onchainConfig, offchainConfigVersion, offchainConfig, err := confighelper.ContractSetConfigArgsForTests( - 2*time.Second, // deltaProgress - 1*time.Second, // deltaResend - 1*time.Second, // deltaRound - 500*time.Millisecond, // deltaGrace - 2*time.Second, // deltaStage - 3, - []int{1, 1, 1, 1}, - oracles, - rawOffchainConfig, - nil, - 50*time.Millisecond, // Max duration query - 1*time.Second, // Max duration observation - 100*time.Millisecond, - 100*time.Millisecond, - 100*time.Millisecond, - 1, // faults - rawOnchainConfig, - ) - require.NoError(t, err) - lggr := logger.TestLogger(t) - lggr.Infow("Setting Config on Oracle Contract", - "signers", signers, - "transmitters", transmitters, - "threshold", threshold, - "onchainConfig", onchainConfig, - "encodedConfigVersion", offchainConfigVersion, - ) - signerAddresses, err := OnchainPublicKeyToAddress(signers) - require.NoError(t, err) - transmitterAddresses, err := AccountToAddress(transmitters) - require.NoError(t, err) - - return &OCR2Config{ - Signers: signerAddresses, - Transmitters: transmitterAddresses, - F: threshold, - OnchainConfig: onchainConfig, - OffchainConfigVersion: offchainConfigVersion, - OffchainConfig: offchainConfig, - } -} - -func (c *CCIPContracts) SetupCommitOCR2Config(t *testing.T, commitOnchainConfig, commitOffchainConfig []byte) { - c.commitOCRConfig = c.DeriveOCR2Config(t, c.Oracles, commitOnchainConfig, commitOffchainConfig) - // Set the DON on the commit store - _, err := c.Dest.CommitStore.SetOCR2Config( - c.Dest.User, - c.commitOCRConfig.Signers, - c.commitOCRConfig.Transmitters, - c.commitOCRConfig.F, - c.commitOCRConfig.OnchainConfig, - c.commitOCRConfig.OffchainConfigVersion, - c.commitOCRConfig.OffchainConfig, - ) - require.NoError(t, err) - c.Dest.Chain.Commit() -} - -func (c *CCIPContracts) SetupExecOCR2Config(t *testing.T, execOnchainConfig, execOffchainConfig []byte) { - c.execOCRConfig = c.DeriveOCR2Config(t, c.Oracles, execOnchainConfig, execOffchainConfig) - // Same DON on the offramp - _, err := c.Dest.OffRamp.SetOCR2Config( - c.Dest.User, - c.execOCRConfig.Signers, - c.execOCRConfig.Transmitters, - c.execOCRConfig.F, - c.execOCRConfig.OnchainConfig, - c.execOCRConfig.OffchainConfigVersion, - c.execOCRConfig.OffchainConfig, - ) - require.NoError(t, err) - c.Dest.Chain.Commit() -} - -func (c *CCIPContracts) SetupOnchainConfig(t *testing.T, commitOnchainConfig, commitOffchainConfig, execOnchainConfig, execOffchainConfig []byte) int64 { - // Note We do NOT set the payees, payment is done in the OCR2Base implementation - blockBeforeConfig, err := c.Dest.Chain.Client().BlockByNumber(tests.Context(t), nil) - require.NoError(t, err) - - c.SetupCommitOCR2Config(t, commitOnchainConfig, commitOffchainConfig) - c.SetupExecOCR2Config(t, execOnchainConfig, execOffchainConfig) - - return blockBeforeConfig.Number().Int64() -} - -func (c *CCIPContracts) SetupLockAndMintTokenPool( - sourceTokenAddress common.Address, - wrappedTokenName, - wrappedTokenSymbol string) (common.Address, *burn_mint_erc677.BurnMintERC677, error) { - // Deploy dest token & pool - destTokenAddress, _, _, err := burn_mint_erc677.DeployBurnMintERC677(c.Dest.User, c.Dest.Chain.Client(), wrappedTokenName, wrappedTokenSymbol, 18, big.NewInt(0)) - if err != nil { - return [20]byte{}, nil, err - } - c.Dest.Chain.Commit() - - destToken, err := burn_mint_erc677.NewBurnMintERC677(destTokenAddress, c.Dest.Chain.Client()) - if err != nil { - return [20]byte{}, nil, err - } - - destPoolAddress, _, destPool, err := burn_mint_token_pool.DeployBurnMintTokenPool( - c.Dest.User, - c.Dest.Chain.Client(), - destTokenAddress, - []common.Address{}, // pool originalSender allowList - c.Dest.ARMProxy.Address(), - c.Dest.Router.Address(), - ) - if err != nil { - return [20]byte{}, nil, err - } - c.Dest.Chain.Commit() - - _, err = destToken.GrantMintAndBurnRoles(c.Dest.User, destPoolAddress) - if err != nil { - return [20]byte{}, nil, err - } - - _, err = destPool.ApplyChainUpdates(c.Dest.User, - []burn_mint_token_pool.TokenPoolChainUpdate{ - { - RemoteChainSelector: c.Source.ChainSelector, - Allowed: true, - OutboundRateLimiterConfig: burn_mint_token_pool.RateLimiterConfig{ - IsEnabled: true, - Capacity: HundredLink, - Rate: big.NewInt(1e18), - }, - InboundRateLimiterConfig: burn_mint_token_pool.RateLimiterConfig{ - IsEnabled: true, - Capacity: HundredLink, - Rate: big.NewInt(1e18), - }, - }, - }) - if err != nil { - return [20]byte{}, nil, err - } - c.Dest.Chain.Commit() - - sourcePoolAddress, _, sourcePool, err := lock_release_token_pool.DeployLockReleaseTokenPool( - c.Source.User, - c.Source.Chain.Client(), - sourceTokenAddress, - []common.Address{}, // empty allowList at deploy time indicates pool has no original sender restrictions - c.Source.ARMProxy.Address(), - true, - c.Source.Router.Address(), - ) - if err != nil { - return [20]byte{}, nil, err - } - c.Source.Chain.Commit() - - // set onRamp as valid caller for source pool - _, err = sourcePool.ApplyChainUpdates(c.Source.User, []lock_release_token_pool.TokenPoolChainUpdate{ - { - RemoteChainSelector: c.Dest.ChainSelector, - Allowed: true, - OutboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ - IsEnabled: true, - Capacity: HundredLink, - Rate: big.NewInt(1e18), - }, - InboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ - IsEnabled: true, - Capacity: HundredLink, - Rate: big.NewInt(1e18), - }, - }, - }) - if err != nil { - return [20]byte{}, nil, err - } - c.Source.Chain.Commit() - - wrappedNativeAddress, err := c.Source.Router.GetWrappedNative(nil) - if err != nil { - return [20]byte{}, nil, err - } - - // native token is used as fee token - _, err = c.Source.PriceRegistry.UpdatePrices(c.Source.User, price_registry_1_2_0.InternalPriceUpdates{ - TokenPriceUpdates: []price_registry_1_2_0.InternalTokenPriceUpdate{ - { - SourceToken: sourceTokenAddress, - UsdPerToken: big.NewInt(5), - }, - }, - GasPriceUpdates: []price_registry_1_2_0.InternalGasPriceUpdate{}, - }) - if err != nil { - return [20]byte{}, nil, err - } - c.Source.Chain.Commit() - - _, err = c.Source.PriceRegistry.ApplyFeeTokensUpdates(c.Source.User, []common.Address{wrappedNativeAddress}, nil) - if err != nil { - return [20]byte{}, nil, err - } - c.Source.Chain.Commit() - - // add new token pool created above - _, err = c.Source.OnRamp.ApplyPoolUpdates(c.Source.User, nil, []evm_2_evm_onramp.InternalPoolUpdate{ - { - Token: sourceTokenAddress, - Pool: sourcePoolAddress, - }, - }) - if err != nil { - return [20]byte{}, nil, err - } - - _, err = c.Dest.OffRamp.ApplyPoolUpdates(c.Dest.User, nil, []evm_2_evm_offramp.InternalPoolUpdate{ - { - Token: sourceTokenAddress, - Pool: destPoolAddress, - }, - }) - if err != nil { - return [20]byte{}, nil, err - } - c.Dest.Chain.Commit() - - return sourcePoolAddress, destToken, err -} - -func (c *CCIPContracts) SendMessage(t *testing.T, gasLimit, tokenAmount *big.Int, receiverAddr common.Address) { - extraArgs, err := GetEVMExtraArgsV1(gasLimit, false) - require.NoError(t, err) - msg := router.ClientEVM2AnyMessage{ - Receiver: MustEncodeAddress(t, receiverAddr), - Data: []byte("hello"), - TokenAmounts: []router.ClientEVMTokenAmount{ - { - Token: c.Source.LinkToken.Address(), - Amount: tokenAmount, - }, - }, - FeeToken: c.Source.LinkToken.Address(), - ExtraArgs: extraArgs, - } - fee, err := c.Source.Router.GetFee(nil, c.Dest.ChainSelector, msg) - require.NoError(t, err) - // Currently no overhead and 1gwei dest gas price. So fee is simply gasLimit * gasPrice. - // require.Equal(t, new(big.Int).Mul(gasLimit, gasPrice).String(), fee.String()) - // Approve the fee amount + the token amount - _, err = c.Source.LinkToken.Approve(c.Source.User, c.Source.Router.Address(), new(big.Int).Add(fee, tokenAmount)) - require.NoError(t, err) - c.Source.Chain.Commit() - c.SendRequest(t, msg) -} - -func GetBalances(t *testing.T, brs []BalanceReq) (map[string]*big.Int, error) { - m := make(map[string]*big.Int) - for _, br := range brs { - m[br.Name] = br.Getter(t, br.Addr) - if m[br.Name] == nil { - return nil, fmt.Errorf("%v getter return nil", br.Name) - } - } - return m, nil -} - -func MustAddBigInt(a *big.Int, b string) *big.Int { - bi, _ := big.NewInt(0).SetString(b, 10) - return big.NewInt(0).Add(a, bi) -} - -func MustSubBigInt(a *big.Int, b string) *big.Int { - bi, _ := big.NewInt(0).SetString(b, 10) - return big.NewInt(0).Sub(a, bi) -} - -func MustEncodeAddress(t *testing.T, address common.Address) []byte { - bts, err := utils.ABIEncode(`[{"type":"address"}]`, address) - require.NoError(t, err) - return bts -} - -func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destChainID, destChainSelector uint64) CCIPContracts { - sourceChain, sourceUser := testhelpers.SetupChain(t) - destChain, destUser := testhelpers.SetupChain(t) - - sourceChain.Commit() - destChain.Commit() - - armSourceAddress, _, _, err := mock_rmn_contract.DeployMockRMNContract( - sourceUser, - sourceChain.Client(), - ) - require.NoError(t, err) - sourceChain.Commit() - - sourceARM, err := mock_rmn_contract.NewMockRMNContract(armSourceAddress, sourceChain.Client()) - require.NoError(t, err) - armProxySourceAddress, _, _, err := rmn_proxy_contract.DeployRMNProxyContract( - sourceUser, - sourceChain.Client(), - armSourceAddress, - ) - require.NoError(t, err) - sourceChain.Commit() - - sourceARMProxy, err := rmn_proxy_contract.NewRMNProxyContract(armProxySourceAddress, sourceChain.Client()) - require.NoError(t, err) - - armDestAddress, _, _, err := mock_rmn_contract.DeployMockRMNContract( - destUser, - destChain.Client(), - ) - require.NoError(t, err) - destChain.Commit() - - armProxyDestAddress, _, _, err := rmn_proxy_contract.DeployRMNProxyContract( - destUser, - destChain.Client(), - armDestAddress, - ) - require.NoError(t, err) - destChain.Commit() - - destARM, err := mock_rmn_contract.NewMockRMNContract(armDestAddress, destChain.Client()) - require.NoError(t, err) - destARMProxy, err := rmn_proxy_contract.NewRMNProxyContract(armProxyDestAddress, destChain.Client()) - require.NoError(t, err) - - // Deploy link token and pool on source chain - sourceLinkTokenAddress, _, _, err := link_token_interface.DeployLinkToken(sourceUser, sourceChain.Client()) - require.NoError(t, err) - sourceChain.Commit() - sourceLinkToken, err := link_token_interface.NewLinkToken(sourceLinkTokenAddress, sourceChain.Client()) - require.NoError(t, err) - - // Create router - sourceWeth9addr, _, _, err := weth9.DeployWETH9(sourceUser, sourceChain.Client()) - require.NoError(t, err) - sourceChain.Commit() - - sourceWrapped, err := weth9.NewWETH9(sourceWeth9addr, sourceChain.Client()) - require.NoError(t, err) - - sourceRouterAddress, _, _, err := router.DeployRouter(sourceUser, sourceChain.Client(), sourceWeth9addr, armProxySourceAddress) - require.NoError(t, err) - sourceChain.Commit() - - sourceRouter, err := router.NewRouter(sourceRouterAddress, sourceChain.Client()) - require.NoError(t, err) - - sourceWeth9PoolAddress, _, _, err := lock_release_token_pool_1_0_0.DeployLockReleaseTokenPool( - sourceUser, - sourceChain.Client(), - sourceWeth9addr, - []common.Address{}, - armProxySourceAddress, - ) - require.NoError(t, err) - sourceChain.Commit() - - sourceWeth9Pool, err := lock_release_token_pool_1_0_0.NewLockReleaseTokenPool(sourceWeth9PoolAddress, sourceChain.Client()) - require.NoError(t, err) - - sourcePoolAddress, _, _, err := lock_release_token_pool.DeployLockReleaseTokenPool( - sourceUser, - sourceChain.Client(), - sourceLinkTokenAddress, - []common.Address{}, - armProxySourceAddress, - true, - sourceRouterAddress, - ) - require.NoError(t, err) - sourceChain.Commit() - sourcePool, err := lock_release_token_pool.NewLockReleaseTokenPool(sourcePoolAddress, sourceChain.Client()) - require.NoError(t, err) - - // Deploy custom token pool source - sourceCustomTokenAddress, _, _, err := link_token_interface.DeployLinkToken(sourceUser, sourceChain.Client()) // Just re-use this, it's an ERC20. - require.NoError(t, err) - sourceCustomToken, err := link_token_interface.NewLinkToken(sourceCustomTokenAddress, sourceChain.Client()) - require.NoError(t, err) - destChain.Commit() - - // Deploy custom token pool dest - destCustomTokenAddress, _, _, err := link_token_interface.DeployLinkToken(destUser, destChain.Client()) // Just re-use this, it's an ERC20. - require.NoError(t, err) - destCustomToken, err := link_token_interface.NewLinkToken(destCustomTokenAddress, destChain.Client()) - require.NoError(t, err) - destChain.Commit() - - // Deploy and configure onramp - sourcePricesAddress, _, _, err := price_registry_1_2_0.DeployPriceRegistry( - sourceUser, - sourceChain.Client(), - nil, - []common.Address{sourceLinkTokenAddress, sourceWeth9addr}, - 60*60*24*14, // two weeks - ) - require.NoError(t, err) - sourceChain.Commit() - - srcPriceRegistry, err := price_registry_1_2_0.NewPriceRegistry(sourcePricesAddress, sourceChain.Client()) - require.NoError(t, err) - - _, err = srcPriceRegistry.UpdatePrices(sourceUser, price_registry_1_2_0.InternalPriceUpdates{ - TokenPriceUpdates: []price_registry_1_2_0.InternalTokenPriceUpdate{ - { - SourceToken: sourceLinkTokenAddress, - UsdPerToken: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(20)), - }, - { - SourceToken: sourceWeth9addr, - UsdPerToken: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(2000)), - }, - }, - GasPriceUpdates: []price_registry_1_2_0.InternalGasPriceUpdate{ - { - DestChainSelector: destChainSelector, - UsdPerUnitGas: big.NewInt(20000e9), - }, - }, - }) - require.NoError(t, err) - sourceChain.Commit() - - onRampAddress, _, _, err := evm_2_evm_onramp.DeployEVM2EVMOnRamp( - sourceUser, // user - sourceChain.Client(), // client - evm_2_evm_onramp.EVM2EVMOnRampStaticConfig{ - LinkToken: sourceLinkTokenAddress, - ChainSelector: sourceChainSelector, - DestChainSelector: destChainSelector, - DefaultTxGasLimit: 200_000, - MaxNopFeesJuels: big.NewInt(0).Mul(big.NewInt(100_000_000), big.NewInt(1e18)), - PrevOnRamp: common.HexToAddress(""), - ArmProxy: armProxySourceAddress, // ARM - }, - evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{ - Router: sourceRouterAddress, - MaxNumberOfTokensPerMsg: 5, - DestGasOverhead: 350_000, - DestGasPerPayloadByte: 16, - DestDataAvailabilityOverheadGas: 33_596, - DestGasPerDataAvailabilityByte: 16, - DestDataAvailabilityMultiplierBps: 6840, // 0.684 - PriceRegistry: sourcePricesAddress, - MaxDataBytes: 1e5, - MaxPerMsgGasLimit: 4_000_000, - }, - []evm_2_evm_onramp.InternalPoolUpdate{ - { - Token: sourceLinkTokenAddress, - Pool: sourcePoolAddress, - }, - { - Token: sourceWeth9addr, - Pool: sourceWeth9PoolAddress, - }, - }, - evm_2_evm_onramp.RateLimiterConfig{ - IsEnabled: true, - Capacity: LinkUSDValue(100), - Rate: LinkUSDValue(1), - }, - []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs{ - { - Token: sourceLinkTokenAddress, - NetworkFeeUSDCents: 1_00, - GasMultiplierWeiPerEth: 1e18, - PremiumMultiplierWeiPerEth: 9e17, - Enabled: true, - }, - { - Token: sourceWeth9addr, - NetworkFeeUSDCents: 1_00, - GasMultiplierWeiPerEth: 1e18, - PremiumMultiplierWeiPerEth: 1e18, - Enabled: true, - }, - }, - []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs{ - { - Token: sourceLinkTokenAddress, - MinFeeUSDCents: 50, // $0.5 - MaxFeeUSDCents: 1_000_000_00, // $ 1 million - DeciBps: 5_0, // 5 bps - DestGasOverhead: 34_000, - DestBytesOverhead: 32, - }, - }, - []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight{}, - ) - require.NoError(t, err) - sourceChain.Commit() - - onRamp, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(onRampAddress, sourceChain.Client()) - require.NoError(t, err) - _, err = sourcePool.ApplyChainUpdates( - sourceUser, - []lock_release_token_pool.TokenPoolChainUpdate{{ - RemoteChainSelector: DestChainSelector, - Allowed: true, - OutboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ - IsEnabled: true, - Capacity: HundredLink, - Rate: big.NewInt(1e18), - }, - InboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ - IsEnabled: true, - Capacity: HundredLink, - Rate: big.NewInt(1e18), - }, - }}, - ) - require.NoError(t, err) - _, err = sourceWeth9Pool.ApplyRampUpdates(sourceUser, - []lock_release_token_pool_1_0_0.TokenPoolRampUpdate{{Ramp: onRampAddress, Allowed: true, - RateLimiterConfig: lock_release_token_pool_1_0_0.RateLimiterConfig{ - IsEnabled: true, - Capacity: HundredLink, - Rate: big.NewInt(1e18), - }, - }}, - []lock_release_token_pool_1_0_0.TokenPoolRampUpdate{}, - ) - require.NoError(t, err) - sourceChain.Commit() - _, err = sourceRouter.ApplyRampUpdates(sourceUser, []router.RouterOnRamp{{DestChainSelector: destChainSelector, OnRamp: onRampAddress}}, nil, nil) - require.NoError(t, err) - sourceChain.Commit() - - destWethaddr, _, _, err := weth9.DeployWETH9(destUser, destChain.Client()) - require.NoError(t, err) - destChain.Commit() - destWrapped, err := weth9.NewWETH9(destWethaddr, destChain.Client()) - require.NoError(t, err) - - // Create dest router - destRouterAddress, _, _, err := router.DeployRouter(destUser, destChain.Client(), destWethaddr, armProxyDestAddress) - require.NoError(t, err) - destChain.Commit() - destRouter, err := router.NewRouter(destRouterAddress, destChain.Client()) - require.NoError(t, err) - - // Deploy link token and pool on destination chain - destLinkTokenAddress, _, _, err := link_token_interface.DeployLinkToken(destUser, destChain.Client()) - require.NoError(t, err) - destChain.Commit() - destLinkToken, err := link_token_interface.NewLinkToken(destLinkTokenAddress, destChain.Client()) - require.NoError(t, err) - destPoolAddress, _, _, err := lock_release_token_pool.DeployLockReleaseTokenPool( - destUser, - destChain.Client(), - destLinkTokenAddress, - []common.Address{}, - armProxyDestAddress, - true, - destRouterAddress, - ) - require.NoError(t, err) - destChain.Commit() - destPool, err := lock_release_token_pool.NewLockReleaseTokenPool(destPoolAddress, destChain.Client()) - require.NoError(t, err) - destChain.Commit() - - // Float the offramp pool - o, err := destPool.Owner(nil) - require.NoError(t, err) - require.Equal(t, destUser.From.String(), o.String()) - _, err = destPool.SetRebalancer(destUser, destUser.From) - require.NoError(t, err) - _, err = destLinkToken.Approve(destUser, destPoolAddress, Link(200)) - require.NoError(t, err) - destChain.Commit() - _, err = destPool.ProvideLiquidity(destUser, Link(200)) - require.NoError(t, err) - destChain.Commit() - - destWrappedPoolAddress, _, _, err := lock_release_token_pool_1_0_0.DeployLockReleaseTokenPool( - destUser, - destChain.Client(), - destWethaddr, - []common.Address{}, - armProxyDestAddress, - ) - require.NoError(t, err) - destChain.Commit() - destWrappedPool, err := lock_release_token_pool_1_0_0.NewLockReleaseTokenPool(destWrappedPoolAddress, destChain.Client()) - require.NoError(t, err) - - poolFloatValue := big.NewInt(1e18) - - destUser.Value = poolFloatValue - _, err = destWrapped.Deposit(destUser) - require.NoError(t, err) - destChain.Commit() - destUser.Value = nil - - _, err = destWrapped.Transfer(destUser, destWrappedPool.Address(), poolFloatValue) - require.NoError(t, err) - destChain.Commit() - - // Deploy and configure ge offramp. - destPricesAddress, _, _, err := price_registry_1_2_0.DeployPriceRegistry( - destUser, - destChain.Client(), - nil, - []common.Address{destLinkTokenAddress}, - 60*60*24*14, // two weeks - ) - require.NoError(t, err) - destChain.Commit() - - destPriceRegistry, err := price_registry_1_2_0.NewPriceRegistry(destPricesAddress, destChain.Client()) - require.NoError(t, err) - - // Deploy commit store. - commitStoreAddress, _, _, err := commit_store_1_2_0.DeployCommitStore( - destUser, // user - destChain.Client(), // client - commit_store_1_2_0.CommitStoreStaticConfig{ - ChainSelector: destChainSelector, - SourceChainSelector: sourceChainSelector, - OnRamp: onRamp.Address(), - ArmProxy: destARMProxy.Address(), - }, - ) - require.NoError(t, err) - destChain.Commit() - commitStore, err := commit_store_1_2_0.NewCommitStore(commitStoreAddress, destChain.Client()) - require.NoError(t, err) - - offRampAddress, _, _, err := evm_2_evm_offramp.DeployEVM2EVMOffRamp( - destUser, - destChain.Client(), - evm_2_evm_offramp.EVM2EVMOffRampStaticConfig{ - CommitStore: commitStore.Address(), - ChainSelector: destChainSelector, - SourceChainSelector: sourceChainSelector, - OnRamp: onRampAddress, - PrevOffRamp: common.HexToAddress(""), - ArmProxy: armProxyDestAddress, - }, - []common.Address{sourceLinkTokenAddress, sourceWeth9addr}, - []common.Address{destPoolAddress, destWrappedPool.Address()}, - evm_2_evm_offramp.RateLimiterConfig{ - IsEnabled: true, - Capacity: LinkUSDValue(100), - Rate: LinkUSDValue(1), - }, - ) - require.NoError(t, err) - destChain.Commit() - - offRamp, err := evm_2_evm_offramp.NewEVM2EVMOffRamp(offRampAddress, destChain.Client()) - require.NoError(t, err) - _, err = destPool.ApplyChainUpdates(destUser, - []lock_release_token_pool.TokenPoolChainUpdate{{ - RemoteChainSelector: sourceChainSelector, - Allowed: true, - OutboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ - IsEnabled: true, - Capacity: HundredLink, - Rate: big.NewInt(1e18), - }, - InboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ - IsEnabled: true, - Capacity: HundredLink, - Rate: big.NewInt(1e18), - }, - }}, - ) - require.NoError(t, err) - - _, err = destWrappedPool.ApplyRampUpdates(destUser, - []lock_release_token_pool_1_0_0.TokenPoolRampUpdate{}, - []lock_release_token_pool_1_0_0.TokenPoolRampUpdate{{ - Ramp: offRampAddress, - Allowed: true, - RateLimiterConfig: lock_release_token_pool_1_0_0.RateLimiterConfig{ - IsEnabled: true, - Capacity: HundredLink, - Rate: big.NewInt(1e18), - }, - }}, - ) - require.NoError(t, err) - - destChain.Commit() - _, err = destPriceRegistry.ApplyPriceUpdatersUpdates(destUser, []common.Address{commitStoreAddress}, []common.Address{}) - require.NoError(t, err) - destChain.Commit() - - _, err = destRouter.ApplyRampUpdates(destUser, nil, - nil, []router.RouterOffRamp{{SourceChainSelector: sourceChainSelector, OffRamp: offRampAddress}}) - require.NoError(t, err) - destChain.Commit() - - // Deploy 2 revertable (one SS one non-SS) - revertingMessageReceiver1Address, _, _, err := maybe_revert_message_receiver.DeployMaybeRevertMessageReceiver(destUser, destChain.Client(), false) - require.NoError(t, err) - revertingMessageReceiver1, _ := maybe_revert_message_receiver.NewMaybeRevertMessageReceiver(revertingMessageReceiver1Address, destChain.Client()) - revertingMessageReceiver2Address, _, _, err := maybe_revert_message_receiver.DeployMaybeRevertMessageReceiver(destUser, destChain.Client(), false) - require.NoError(t, err) - revertingMessageReceiver2, _ := maybe_revert_message_receiver.NewMaybeRevertMessageReceiver(revertingMessageReceiver2Address, destChain.Client()) - // Need to commit here, or we will hit the block gas limit when deploying the executor - sourceChain.Commit() - destChain.Commit() - - // Ensure we have at least finality blocks. - for i := 0; i < 50; i++ { - sourceChain.Commit() - destChain.Commit() - } - - source := SourceChain{ - Common: Common{ - ChainID: sourceChainID, - ChainSelector: sourceChainSelector, - User: sourceUser, - Chain: sourceChain, - LinkToken: sourceLinkToken, - LinkTokenPool: sourcePool, - CustomToken: sourceCustomToken, - ARM: sourceARM, - ARMProxy: sourceARMProxy, - PriceRegistry: srcPriceRegistry, - WrappedNative: sourceWrapped, - WrappedNativePool: sourceWeth9Pool, - }, - Router: sourceRouter, - OnRamp: onRamp, - } - dest := DestinationChain{ - Common: Common{ - ChainID: destChainID, - ChainSelector: destChainSelector, - User: destUser, - Chain: destChain, - LinkToken: destLinkToken, - LinkTokenPool: destPool, - CustomToken: destCustomToken, - ARM: destARM, - ARMProxy: destARMProxy, - PriceRegistry: destPriceRegistry, - WrappedNative: destWrapped, - WrappedNativePool: destWrappedPool, - }, - CommitStore: commitStore, - Router: destRouter, - OffRamp: offRamp, - Receivers: []MaybeRevertReceiver{{Receiver: revertingMessageReceiver1, Strict: false}, {Receiver: revertingMessageReceiver2, Strict: true}}, - } - - return CCIPContracts{ - Source: source, - Dest: dest, - } -} - -func (c *CCIPContracts) SendRequest(t *testing.T, msg router.ClientEVM2AnyMessage) *types.Transaction { - tx, err := c.Source.Router.CcipSend(c.Source.User, c.Dest.ChainSelector, msg) - require.NoError(t, err) - testhelpers.ConfirmTxs(t, []*types.Transaction{tx}, c.Source.Chain) - return tx -} - -func (c *CCIPContracts) AssertExecState(t *testing.T, log logpoller.Log, state MessageExecutionState, offRampOpts ...common.Address) { - var offRamp *evm_2_evm_offramp.EVM2EVMOffRamp - var err error - if len(offRampOpts) > 0 { - offRamp, err = evm_2_evm_offramp.NewEVM2EVMOffRamp(offRampOpts[0], c.Dest.Chain.Client()) - require.NoError(t, err) - } else { - require.NotNil(t, c.Dest.OffRamp, "no offRamp configured") - offRamp = c.Dest.OffRamp - } - executionStateChanged, err := offRamp.ParseExecutionStateChanged(log.ToGethLog()) - require.NoError(t, err) - if MessageExecutionState(executionStateChanged.State) != state { - t.Log("Execution failed", hexutil.Encode(executionStateChanged.ReturnData)) - t.Fail() - } -} - -func GetEVMExtraArgsV1(gasLimit *big.Int, strict bool) ([]byte, error) { - EVMV1Tag := []byte{0x97, 0xa6, 0x57, 0xc9} - - encodedArgs, err := utils.ABIEncode(`[{"type":"uint256"},{"type":"bool"}]`, gasLimit, strict) - if err != nil { - return nil, err - } - - return append(EVMV1Tag, encodedArgs...), nil -} - -type ManualExecArgs struct { - SourceChainID, DestChainID uint64 - DestUser *bind.TransactOpts - SourceChain, DestChain bind.ContractBackend - SourceStartBlock *big.Int // the block in/after which failed ccip-send transaction was triggered - DestStartBlock uint64 // the start block for filtering ReportAccepted event (including the failed seq num) - // in destination chain. if not provided to be derived by ApproxDestStartBlock method - DestLatestBlockNum uint64 // current block number in destination - DestDeployedAt uint64 // destination block number for the initial destination contract deployment. - // Can be any number before the tx was reverted in destination chain. Preferably this needs to be set up with - // a value greater than zero to avoid performance issue in locating approximate destination block - SendReqLogIndex uint // log index of the CCIPSendRequested log in source chain - SendReqTxHash string // tx hash of the ccip-send transaction for which execution was reverted - CommitStore string - OnRamp string - OffRamp string - SeqNr uint64 - GasLimit *big.Int -} - -// ApproxDestStartBlock attempts to locate a block in destination chain with timestamp closest to the timestamp of the block -// in source chain in which ccip-send transaction was included -// it uses binary search to locate the block with the closest timestamp -// if the block located has a timestamp greater than the timestamp of mentioned source block -// it just returns the first block found with lesser timestamp of the source block -// providing a value of args.DestDeployedAt ensures better performance by reducing the range of block numbers to be traversed -func (args *ManualExecArgs) ApproxDestStartBlock(ctx context.Context) error { - sourceBlockHdr, err := args.SourceChain.HeaderByNumber(ctx, args.SourceStartBlock) - if err != nil { - return err - } - sendTxTime := sourceBlockHdr.Time - maxBlockNum := args.DestLatestBlockNum - // setting this to an approx value of 1000 considering destination chain would have at least 1000 blocks before the transaction started - minBlockNum := args.DestDeployedAt - closestBlockNum := uint64(math.Floor((float64(maxBlockNum) + float64(minBlockNum)) / 2)) - var closestBlockHdr *types.Header - closestBlockHdr, err = args.DestChain.HeaderByNumber(ctx, new(big.Int).SetUint64(closestBlockNum)) - if err != nil { - return err - } - // to reduce the number of RPC calls increase the value of blockOffset - blockOffset := uint64(10) - for { - blockNum := closestBlockHdr.Number.Uint64() - if minBlockNum > maxBlockNum { - break - } - timeDiff := math.Abs(float64(closestBlockHdr.Time - sendTxTime)) - // break if the difference in timestamp is lesser than 1 minute - if timeDiff < 60 { - break - } else if closestBlockHdr.Time > sendTxTime { - maxBlockNum = blockNum - 1 - } else { - minBlockNum = blockNum + 1 - } - closestBlockNum = uint64(math.Floor((float64(maxBlockNum) + float64(minBlockNum)) / 2)) - closestBlockHdr, err = args.DestChain.HeaderByNumber(ctx, new(big.Int).SetUint64(closestBlockNum)) - if err != nil { - return err - } - } - - for closestBlockHdr.Time > sendTxTime { - closestBlockNum = closestBlockNum - blockOffset - if closestBlockNum <= 0 { - return fmt.Errorf("approx destination blocknumber not found") - } - closestBlockHdr, err = args.DestChain.HeaderByNumber(ctx, new(big.Int).SetUint64(closestBlockNum)) - if err != nil { - return err - } - } - args.DestStartBlock = closestBlockHdr.Number.Uint64() - fmt.Println("using approx destination start block number", args.DestStartBlock) - return nil -} - -func (args *ManualExecArgs) FindSeqNrFromCCIPSendRequested() (uint64, error) { - var seqNr uint64 - onRampContract, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(common.HexToAddress(args.OnRamp), args.SourceChain) - if err != nil { - return seqNr, err - } - iterator, err := onRampContract.FilterCCIPSendRequested(&bind.FilterOpts{ - Start: args.SourceStartBlock.Uint64(), - }) - if err != nil { - return seqNr, err - } - for iterator.Next() { - if iterator.Event.Raw.Index == args.SendReqLogIndex && - iterator.Event.Raw.TxHash.Hex() == args.SendReqTxHash { - seqNr = iterator.Event.Message.SequenceNumber - break - } - } - if seqNr == 0 { - return seqNr, - fmt.Errorf("no CCIPSendRequested logs found for logIndex %d starting from block number %d", args.SendReqLogIndex, args.SourceStartBlock) - } - return seqNr, nil -} - -func (args *ManualExecArgs) ExecuteManually(ctx context.Context) (*types.Transaction, error) { - if args.SourceChainID == 0 || - args.DestChainID == 0 || - args.DestUser == nil { - return nil, fmt.Errorf("chain ids and owners are mandatory for source and dest chain") - } - if !common.IsHexAddress(args.CommitStore) || - !common.IsHexAddress(args.OffRamp) || - !common.IsHexAddress(args.OnRamp) { - return nil, fmt.Errorf("contract addresses must be valid hex address") - } - if args.SendReqTxHash == "" { - return nil, fmt.Errorf("tx hash of ccip-send request are required") - } - if args.SourceStartBlock == nil { - return nil, fmt.Errorf("must provide the value of source block in/after which ccip-send tx was included") - } - if args.SeqNr == 0 { - if args.SendReqLogIndex == 0 { - return nil, fmt.Errorf("must provide the value of log index of ccip-send request") - } - // locate seq nr from CCIPSendRequested log - seqNr, err := args.FindSeqNrFromCCIPSendRequested() - if err != nil { - return nil, err - } - args.SeqNr = seqNr - } - commitStore, err := commit_store_1_2_0.NewCommitStore(common.HexToAddress(args.CommitStore), args.DestChain) - if err != nil { - return nil, err - } - if args.DestStartBlock < 1 { - err = args.ApproxDestStartBlock(ctx) - if err != nil { - return nil, err - } - } - iterator, err := commitStore.FilterReportAccepted(&bind.FilterOpts{Start: args.DestStartBlock}) - if err != nil { - return nil, err - } - - var commitReport *commit_store_1_2_0.CommitStoreCommitReport - for iterator.Next() { - if iterator.Event.Report.Interval.Min <= args.SeqNr && iterator.Event.Report.Interval.Max >= args.SeqNr { - commitReport = &iterator.Event.Report - fmt.Println("Found root") - break - } - } - if commitReport == nil { - return nil, fmt.Errorf("unable to find seq num %d in commit report", args.SeqNr) - } - - return args.execute(commitReport) -} - -func (args *ManualExecArgs) execute(report *commit_store_1_2_0.CommitStoreCommitReport) (*types.Transaction, error) { - log.Info().Msg("Executing request manually") - seqNr := args.SeqNr - // Build a merkle tree for the report - mctx := hashutil.NewKeccak() - onRampContract, err := evm_2_evm_onramp_1_2_0.NewEVM2EVMOnRamp(common.HexToAddress(args.OnRamp), args.SourceChain) - if err != nil { - return nil, err - } - leafHasher := v1_2_0.NewLeafHasher(args.SourceChainID, args.DestChainID, common.HexToAddress(args.OnRamp), mctx, onRampContract) - if leafHasher == nil { - return nil, fmt.Errorf("unable to create leaf hasher") - } - - var leaves [][32]byte - var curr, prove int - var msgs []evm_2_evm_offramp.InternalEVM2EVMMessage - var manualExecGasLimits []*big.Int - var tokenData [][][]byte - sendRequestedIterator, err := onRampContract.FilterCCIPSendRequested(&bind.FilterOpts{ - Start: args.SourceStartBlock.Uint64(), - }) - if err != nil { - return nil, err - } - for sendRequestedIterator.Next() { - if sendRequestedIterator.Event.Message.SequenceNumber <= report.Interval.Max && - sendRequestedIterator.Event.Message.SequenceNumber >= report.Interval.Min { - fmt.Println("Found seq num", sendRequestedIterator.Event.Message.SequenceNumber, report.Interval) - hash, err2 := leafHasher.HashLeaf(sendRequestedIterator.Event.Raw) - if err2 != nil { - return nil, err2 - } - leaves = append(leaves, hash) - if sendRequestedIterator.Event.Message.SequenceNumber == seqNr { - fmt.Printf("Found proving %d %+v\n", curr, sendRequestedIterator.Event.Message) - var tokensAndAmounts []evm_2_evm_offramp.ClientEVMTokenAmount - for _, tokenAndAmount := range sendRequestedIterator.Event.Message.TokenAmounts { - tokensAndAmounts = append(tokensAndAmounts, evm_2_evm_offramp.ClientEVMTokenAmount{ - Token: tokenAndAmount.Token, - Amount: tokenAndAmount.Amount, - }) - } - msg := evm_2_evm_offramp.InternalEVM2EVMMessage{ - SourceChainSelector: sendRequestedIterator.Event.Message.SourceChainSelector, - Sender: sendRequestedIterator.Event.Message.Sender, - Receiver: sendRequestedIterator.Event.Message.Receiver, - SequenceNumber: sendRequestedIterator.Event.Message.SequenceNumber, - GasLimit: sendRequestedIterator.Event.Message.GasLimit, - Strict: sendRequestedIterator.Event.Message.Strict, - Nonce: sendRequestedIterator.Event.Message.Nonce, - FeeToken: sendRequestedIterator.Event.Message.FeeToken, - FeeTokenAmount: sendRequestedIterator.Event.Message.FeeTokenAmount, - Data: sendRequestedIterator.Event.Message.Data, - TokenAmounts: tokensAndAmounts, - SourceTokenData: sendRequestedIterator.Event.Message.SourceTokenData, - MessageId: sendRequestedIterator.Event.Message.MessageId, - } - msgs = append(msgs, msg) - if args.GasLimit != nil { - msg.GasLimit = args.GasLimit - } - manualExecGasLimits = append(manualExecGasLimits, msg.GasLimit) - var msgTokenData [][]byte - for range sendRequestedIterator.Event.Message.TokenAmounts { - msgTokenData = append(msgTokenData, []byte{}) - } - - tokenData = append(tokenData, msgTokenData) - prove = curr - } - curr++ - } - } - sendRequestedIterator.Close() - if msgs == nil { - return nil, fmt.Errorf("unable to find msg with seqNr %d", seqNr) - } - tree, err := merklemulti.NewTree(mctx, leaves) - if err != nil { - return nil, err - } - if tree.Root() != report.MerkleRoot { - return nil, fmt.Errorf("root doesn't match") - } - - proof, err := tree.Prove([]int{prove}) - if err != nil { - return nil, err - } - - offRampProof := evm_2_evm_offramp.InternalExecutionReport{ - Messages: msgs, - OffchainTokenData: tokenData, - Proofs: proof.Hashes, - ProofFlagBits: abihelpers.ProofFlagsToBits(proof.SourceFlags), - } - offRamp, err := evm_2_evm_offramp.NewEVM2EVMOffRamp(common.HexToAddress(args.OffRamp), args.DestChain) - if err != nil { - return nil, err - } - // Execute. - return offRamp.ManuallyExecute(args.DestUser, offRampProof, manualExecGasLimits) -} - -func (c *CCIPContracts) ExecuteMessage( - t *testing.T, - req logpoller.Log, - txHash common.Hash, - destStartBlock uint64, -) uint64 { - t.Log("Executing request manually") - ctx := tests.Context(t) - sendReqReceipt, err := c.Source.Chain.Client().TransactionReceipt(ctx, txHash) - require.NoError(t, err) - destLatest, err := c.Dest.Chain.Client().BlockByNumber(context.Background(), nil) - require.NoError(t, err) - args := ManualExecArgs{ - SourceChainID: c.Source.ChainID, - DestChainID: c.Dest.ChainID, - DestUser: c.Dest.User, - SourceChain: c.Source.Chain.Client(), - DestChain: c.Dest.Chain.Client(), - SourceStartBlock: sendReqReceipt.BlockNumber, - DestStartBlock: destStartBlock, - DestLatestBlockNum: destLatest.NumberU64(), - SendReqLogIndex: uint(req.LogIndex), - SendReqTxHash: txHash.String(), - CommitStore: c.Dest.CommitStore.Address().String(), - OnRamp: c.Source.OnRamp.Address().String(), - OffRamp: c.Dest.OffRamp.Address().String(), - } - tx, err := args.ExecuteManually(ctx) - require.NoError(t, err) - c.Dest.Chain.Commit() - c.Source.Chain.Commit() - rec, err := c.Dest.Chain.Client().TransactionReceipt(tests.Context(t), tx.Hash()) - require.NoError(t, err) - require.Equal(t, uint64(1), rec.Status, "manual execution failed") - t.Logf("Manual Execution completed for seqNum %d", args.SeqNr) - return args.SeqNr -} - -func GetBalance(t *testing.T, chain bind.ContractBackend, tokenAddr common.Address, addr common.Address) *big.Int { - token, err := link_token_interface.NewLinkToken(tokenAddr, chain) - require.NoError(t, err) - bal, err := token.BalanceOf(nil, addr) - require.NoError(t, err) - return bal -} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go deleted file mode 100644 index 30aaebd4e9e..00000000000 --- a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/chainlink.go +++ /dev/null @@ -1,1053 +0,0 @@ -package testhelpers_1_4_0 - -import ( - "context" - "encoding/hex" - "fmt" - "math" - "math/big" - "net/http" - "net/http/httptest" - "strconv" - "strings" - "testing" - "time" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - types3 "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethclient/simulated" - "github.com/google/uuid" - "github.com/hashicorp/consul/sdk/freeport" - "github.com/jmoiron/sqlx" - "github.com/onsi/gomega" - "github.com/pkg/errors" - "k8s.io/utils/ptr" - - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "go.uber.org/zap" - - "github.com/smartcontractkit/libocr/commontypes" - "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" - types4 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - - "github.com/smartcontractkit/chainlink-common/pkg/config" - "github.com/smartcontractkit/chainlink-common/pkg/loop" - "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" - "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" - - cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" - coretypes "github.com/smartcontractkit/chainlink-common/pkg/types/core/mocks" - - pb "github.com/smartcontractkit/chainlink-protos/orchestrator/feedsmanager" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - v2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - evmUtils "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" - "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - configv2 "github.com/smartcontractkit/chainlink/v2/core/config/toml" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/logger/audit" - "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - feeds2 "github.com/smartcontractkit/chainlink/v2/core/services/feeds" - feedsMocks "github.com/smartcontractkit/chainlink/v2/core/services/feeds/mocks" - "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/csakey" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" - ksMocks "github.com/smartcontractkit/chainlink/v2/core/services/keystore/mocks" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" - integrationtesthelpers "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers/integration" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" - "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" - evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" - clutils "github.com/smartcontractkit/chainlink/v2/core/utils" - "github.com/smartcontractkit/chainlink/v2/core/utils/crypto" - "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" - "github.com/smartcontractkit/chainlink/v2/plugins" -) - -const ( - execSpecTemplate = ` - type = "offchainreporting2" - schemaVersion = 1 - name = "ccip-exec-1" - externalJobID = "67ffad71-d90f-4fe3-b4e4-494924b707fb" - forwardingAllowed = false - maxTaskDuration = "0s" - contractID = "%s" - contractConfigConfirmations = 1 - contractConfigTrackerPollInterval = "20s" - ocrKeyBundleID = "%s" - relay = "evm" - pluginType = "ccip-execution" - transmitterID = "%s" - - [relayConfig] - chainID = 1_337 - - [pluginConfig] - destStartBlock = 50 - - [pluginConfig.USDCConfig] - AttestationAPI = "http://blah.com" - SourceMessageTransmitterAddress = "%s" - SourceTokenAddress = "%s" - AttestationAPITimeoutSeconds = 10 - ` - commitSpecTemplatePipeline = ` - type = "offchainreporting2" - schemaVersion = 1 - name = "ccip-commit-1" - externalJobID = "13c997cf-1a14-4ab7-9068-07ee6d2afa55" - forwardingAllowed = false - maxTaskDuration = "0s" - contractID = "%s" - contractConfigConfirmations = 1 - contractConfigTrackerPollInterval = "20s" - ocrKeyBundleID = "%s" - relay = "evm" - pluginType = "ccip-commit" - transmitterID = "%s" - - [relayConfig] - chainID = 1_337 - - [pluginConfig] - destStartBlock = 50 - offRamp = "%s" - tokenPricesUSDPipeline = """ - %s - """ - ` - commitSpecTemplateDynamicPriceGetter = ` - type = "offchainreporting2" - schemaVersion = 1 - name = "ccip-commit-1" - externalJobID = "13c997cf-1a14-4ab7-9068-07ee6d2afa55" - forwardingAllowed = false - maxTaskDuration = "0s" - contractID = "%s" - contractConfigConfirmations = 1 - contractConfigTrackerPollInterval = "20s" - ocrKeyBundleID = "%s" - relay = "evm" - pluginType = "ccip-commit" - transmitterID = "%s" - - [relayConfig] - chainID = 1_337 - - [pluginConfig] - destStartBlock = 50 - offRamp = "%s" - priceGetterConfig = """ - %s - """ - ` -) - -type Node struct { - App chainlink.Application - Transmitter common.Address - PaymentReceiver common.Address - KeyBundle ocr2key.KeyBundle -} - -func (node *Node) FindJobIDForContract(t *testing.T, addr common.Address) int32 { - jobs := node.App.JobSpawner().ActiveJobs() - for _, j := range jobs { - if j.Type == job.OffchainReporting2 && j.OCR2OracleSpec.ContractID == addr.Hex() { - return j.ID - } - } - t.Fatalf("Could not find job for contract %s", addr.Hex()) - return 0 -} - -func (node *Node) EventuallyNodeUsesUpdatedPriceRegistry(t *testing.T, ccipContracts CCIPIntegrationTestHarness) logpoller.Log { - c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) - require.NoError(t, err) - var log logpoller.Log - gomega.NewGomegaWithT(t).Eventually(func() bool { - ccipContracts.Source.Chain.Commit() - ccipContracts.Dest.Chain.Commit() - log, err := c.LogPoller().LatestLogByEventSigWithConfs( - testutils.Context(t), - v1_2_0.UsdPerUnitGasUpdated, - ccipContracts.Dest.PriceRegistry.Address(), - 0, - ) - // err can be transient errors such as sql row set empty - if err != nil { - return false - } - return log != nil - }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "node is not using updated price registry %s", ccipContracts.Dest.PriceRegistry.Address().Hex()) - return log -} - -func (node *Node) EventuallyNodeUsesNewCommitConfig(t *testing.T, ccipContracts CCIPIntegrationTestHarness, commitCfg ccipdata.CommitOnchainConfig) logpoller.Log { - c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) - require.NoError(t, err) - var log logpoller.Log - gomega.NewGomegaWithT(t).Eventually(func() bool { - ccipContracts.Source.Chain.Commit() - ccipContracts.Dest.Chain.Commit() - log, err := c.LogPoller().LatestLogByEventSigWithConfs( - testutils.Context(t), - evmrelay.OCR2AggregatorLogDecoder.EventSig(), - ccipContracts.Dest.CommitStore.Address(), - 0, - ) - require.NoError(t, err) - var latestCfg ccipdata.CommitOnchainConfig - if log != nil { - latestCfg, err = DecodeCommitOnChainConfig(log.Data) - require.NoError(t, err) - return latestCfg == commitCfg - } - return false - }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "node is using old cfg") - return log -} - -func (node *Node) EventuallyNodeUsesNewExecConfig(t *testing.T, ccipContracts CCIPIntegrationTestHarness, execCfg v1_2_0.ExecOnchainConfig) logpoller.Log { - c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) - require.NoError(t, err) - var log logpoller.Log - gomega.NewGomegaWithT(t).Eventually(func() bool { - ccipContracts.Source.Chain.Commit() - ccipContracts.Dest.Chain.Commit() - log, err := c.LogPoller().LatestLogByEventSigWithConfs( - testutils.Context(t), - evmrelay.OCR2AggregatorLogDecoder.EventSig(), - ccipContracts.Dest.OffRamp.Address(), - 0, - ) - require.NoError(t, err) - var latestCfg v1_2_0.ExecOnchainConfig - if log != nil { - latestCfg, err = DecodeExecOnChainConfig(log.Data) - require.NoError(t, err) - return latestCfg == execCfg - } - return false - }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "node is using old cfg") - return log -} - -func (node *Node) EventuallyHasReqSeqNum(t *testing.T, ccipContracts *CCIPIntegrationTestHarness, onRamp common.Address, seqNum int) logpoller.Log { - c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Source.ChainID, 10)) - require.NoError(t, err) - var log logpoller.Log - gomega.NewGomegaWithT(t).Eventually(func() bool { - ccipContracts.Source.Chain.Commit() - ccipContracts.Dest.Chain.Commit() - lgs, err := c.LogPoller().LogsDataWordRange( - testutils.Context(t), - v1_2_0.CCIPSendRequestEventSig, - onRamp, - v1_2_0.CCIPSendRequestSeqNumIndex, - abihelpers.EvmWord(uint64(seqNum)), - abihelpers.EvmWord(uint64(seqNum)), - 1, - ) - require.NoError(t, err) - t.Log("Send requested", len(lgs)) - if len(lgs) == 1 { - log = lgs[0] - return true - } - return false - }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "eventually has seq num") - return log -} - -func (node *Node) EventuallyHasExecutedSeqNums(t *testing.T, ccipContracts *CCIPIntegrationTestHarness, offRamp common.Address, minSeqNum int, maxSeqNum int) []logpoller.Log { - c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) - require.NoError(t, err) - var logs []logpoller.Log - gomega.NewGomegaWithT(t).Eventually(func() bool { - ccipContracts.Source.Chain.Commit() - ccipContracts.Dest.Chain.Commit() - lgs, err := c.LogPoller().IndexedLogsTopicRange( - testutils.Context(t), - v1_2_0.ExecutionStateChangedEvent, - offRamp, - v1_2_0.ExecutionStateChangedSeqNrIndex, - abihelpers.EvmWord(uint64(minSeqNum)), - abihelpers.EvmWord(uint64(maxSeqNum)), - 1, - ) - require.NoError(t, err) - t.Logf("Have executed logs %d want %d", len(lgs), maxSeqNum-minSeqNum+1) - if len(lgs) == maxSeqNum-minSeqNum+1 { - logs = lgs - t.Logf("Seq Num %d-%d executed", minSeqNum, maxSeqNum) - return true - } - return false - }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "eventually has not executed seq num") - return logs -} - -func (node *Node) ConsistentlySeqNumHasNotBeenExecuted(t *testing.T, ccipContracts *CCIPIntegrationTestHarness, offRamp common.Address, seqNum int) logpoller.Log { - c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) - require.NoError(t, err) - var log logpoller.Log - gomega.NewGomegaWithT(t).Consistently(func() bool { - ccipContracts.Source.Chain.Commit() - ccipContracts.Dest.Chain.Commit() - lgs, err := c.LogPoller().IndexedLogsTopicRange( - testutils.Context(t), - v1_2_0.ExecutionStateChangedEvent, - offRamp, - v1_2_0.ExecutionStateChangedSeqNrIndex, - abihelpers.EvmWord(uint64(seqNum)), - abihelpers.EvmWord(uint64(seqNum)), - 1, - ) - require.NoError(t, err) - t.Log("Executed logs", lgs) - if len(lgs) == 1 { - log = lgs[0] - return true - } - return false - }, 10*time.Second, 1*time.Second).Should(gomega.BeFalse(), "seq number got executed") - return log -} - -func (node *Node) AddJob(t *testing.T, spec *integrationtesthelpers.OCR2TaskJobSpec) { - specString, err := spec.String() - require.NoError(t, err) - ccipJob, err := validate.ValidatedOracleSpecToml( - testutils.Context(t), - node.App.GetConfig().OCR2(), - node.App.GetConfig().Insecure(), - specString, - // FIXME Ani - nil, - ) - require.NoError(t, err) - err = node.App.AddJobV2(tests.Context(t), &ccipJob) - require.NoError(t, err) -} - -func (node *Node) AddBootstrapJob(t *testing.T, spec *integrationtesthelpers.OCR2TaskJobSpec) { - specString, err := spec.String() - require.NoError(t, err) - ccipJob, err := ocrbootstrap.ValidatedBootstrapSpecToml(specString) - require.NoError(t, err) - err = node.App.AddJobV2(tests.Context(t), &ccipJob) - require.NoError(t, err) -} - -func (node *Node) AddJobsWithSpec(t *testing.T, jobSpec *integrationtesthelpers.OCR2TaskJobSpec) { - // set node specific values - jobSpec.OCR2OracleSpec.OCRKeyBundleID.SetValid(node.KeyBundle.ID()) - jobSpec.OCR2OracleSpec.TransmitterID.SetValid(node.Transmitter.Hex()) - node.AddJob(t, jobSpec) -} - -func setupNodeCCIP( - t *testing.T, - owner *bind.TransactOpts, - port int64, - dbName string, - sourceChain *simulated.Backend, destChain *simulated.Backend, - sourceChainID *big.Int, destChainID *big.Int, - bootstrapPeerID string, - bootstrapPort int64, -) (chainlink.Application, string, common.Address, ocr2key.KeyBundle) { - trueRef, falseRef := true, false - - // Do not want to load fixtures as they contain a dummy chainID. - loglevel := configv2.LogLevel(zap.DebugLevel) - config, db := heavyweight.FullTestDBNoFixturesV2(t, func(c *chainlink.Config, _ *chainlink.Secrets) { - p2pAddresses := []string{ - fmt.Sprintf("127.0.0.1:%d", port), - } - c.Log.Level = &loglevel - c.Feature.UICSAKeys = &trueRef - c.Feature.FeedsManager = &trueRef - c.OCR.Enabled = &falseRef - c.OCR.DefaultTransactionQueueDepth = ptr.To[uint32](200) - c.OCR2.Enabled = &trueRef - c.Feature.LogPoller = &trueRef - c.P2P.V2.Enabled = &trueRef - - dur, err := config.NewDuration(500 * time.Millisecond) - if err != nil { - panic(err) - } - c.P2P.V2.DeltaDial = &dur - - dur2, err := config.NewDuration(5 * time.Second) - if err != nil { - panic(err) - } - - c.P2P.V2.DeltaReconcile = &dur2 - c.P2P.V2.ListenAddresses = &p2pAddresses - c.P2P.V2.AnnounceAddresses = &p2pAddresses - - c.EVM = []*v2.EVMConfig{createConfigV2Chain(sourceChainID), createConfigV2Chain(destChainID)} - - if bootstrapPeerID != "" { - // Supply the bootstrap IP and port as a V2 peer address - c.P2P.V2.DefaultBootstrappers = &[]commontypes.BootstrapperLocator{ - { - PeerID: bootstrapPeerID, Addrs: []string{ - fmt.Sprintf("127.0.0.1:%d", bootstrapPort), - }, - }, - } - } - }) - - lggr := logger.TestLogger(t) - - // The in-memory geth sim does not let you create a custom ChainID, it will always be 1337. - // In particular this means that if you sign an eip155 tx, the chainID used MUST be 1337 - // and the CHAINID op code will always emit 1337. To work around this to simulate a "multichain" - // test, we fake different chainIDs using the wrapped sim cltest.SimulatedBackend so the RPC - // appears to operate on different chainIDs and we use an EthKeyStoreSim wrapper which always - // signs 1337 see https://github.com/smartcontractkit/chainlink-ccip/blob/a24dd436810250a458d27d8bb3fb78096afeb79c/core/services/ocr2/plugins/ccip/testhelpers/simulated_backend.go#L35 - sourceClient := client.NewSimulatedBackendClient(t, sourceChain, sourceChainID) - destClient := client.NewSimulatedBackendClient(t, destChain, destChainID) - csaKeyStore := ksMocks.NewCSA(t) - - key, err := csakey.NewV2() - require.NoError(t, err) - csaKeyStore.On("GetAll").Return([]csakey.KeyV2{key}, nil) - keyStore := NewKsa(db, lggr, csaKeyStore) - - simEthKeyStore := testhelpers.EthKeyStoreSim{ - ETHKS: keyStore.Eth(), - CSAKS: keyStore.CSA(), - } - mailMon := mailbox.NewMonitor("CCIP", lggr.Named("Mailbox")) - evmOpts := chainlink.EVMFactoryConfig{ - ChainOpts: legacyevm.ChainOpts{ - AppConfig: config, - GenEthClient: func(chainID *big.Int) client.Client { - if chainID.String() == sourceChainID.String() { - return sourceClient - } else if chainID.String() == destChainID.String() { - return destClient - } - t.Fatalf("invalid chain ID %v", chainID.String()) - return nil - }, - MailMon: mailMon, - DS: db, - }, - CSAETHKeystore: simEthKeyStore, - } - - beholderAuthHeaders, csaPubKeyHex, err := keystore.BuildBeholderAuth(keyStore) - require.NoError(t, err) - - loopRegistry := plugins.NewLoopRegistry(lggr.Named("LoopRegistry"), config.Tracing(), config.Telemetry(), beholderAuthHeaders, csaPubKeyHex) - relayerFactory := chainlink.RelayerFactory{ - Logger: lggr, - LoopRegistry: loopRegistry, - GRPCOpts: loop.GRPCOpts{}, - CapabilitiesRegistry: coretypes.NewCapabilitiesRegistry(t), - } - testCtx := testutils.Context(t) - // evm alway enabled for backward compatibility - initOps := []chainlink.CoreRelayerChainInitFunc{ - chainlink.InitEVM(testCtx, relayerFactory, evmOpts), - } - - relayChainInterops, err := chainlink.NewCoreRelayerChainInteroperators(initOps...) - if err != nil { - t.Fatal(err) - } - - app, err := chainlink.NewApplication(chainlink.ApplicationOpts{ - Config: config, - DS: db, - KeyStore: keyStore, - RelayerChainInteroperators: relayChainInterops, - Logger: lggr, - ExternalInitiatorManager: nil, - CloseLogger: lggr.Sync, - UnrestrictedHTTPClient: &http.Client{}, - RestrictedHTTPClient: &http.Client{}, - AuditLogger: audit.NoopLogger, - MailMon: mailMon, - LoopRegistry: plugins.NewLoopRegistry(lggr, config.Tracing(), config.Telemetry(), beholderAuthHeaders, csaPubKeyHex), - }) - ctx := testutils.Context(t) - require.NoError(t, err) - require.NoError(t, app.GetKeyStore().Unlock(ctx, "password")) - _, err = app.GetKeyStore().P2P().Create(ctx) - require.NoError(t, err) - - p2pIDs, err := app.GetKeyStore().P2P().GetAll() - require.NoError(t, err) - require.Len(t, p2pIDs, 1) - peerID := p2pIDs[0].PeerID() - - _, err = app.GetKeyStore().Eth().Create(testCtx, destChainID) - require.NoError(t, err) - sendingKeys, err := app.GetKeyStore().Eth().EnabledKeysForChain(testCtx, destChainID) - require.NoError(t, err) - require.Len(t, sendingKeys, 1) - transmitter := sendingKeys[0].Address - s, err := app.GetKeyStore().Eth().GetState(testCtx, sendingKeys[0].ID(), destChainID) - require.NoError(t, err) - lggr.Debug(fmt.Sprintf("Transmitter address %s chainID %s", transmitter, s.EVMChainID.String())) - - // Fund the commitTransmitter address with some ETH - destChain.Commit() - n, err := destChain.Client().NonceAt(tests.Context(t), owner.From, nil) - require.NoError(t, err) - tx := types3.NewTransaction(n, transmitter, big.NewInt(1000000000000000000), 21000, big.NewInt(1000000000), nil) - signedTx, err := owner.Signer(owner.From, tx) - require.NoError(t, err) - err = destChain.Client().SendTransaction(tests.Context(t), signedTx) - require.NoError(t, err) - destChain.Commit() - - kb, err := app.GetKeyStore().OCR2().Create(ctx, chaintype.EVM) - require.NoError(t, err) - return app, peerID.Raw(), transmitter, kb -} - -func createConfigV2Chain(chainId *big.Int) *v2.EVMConfig { - // NOTE: For the executor jobs, the default of 500k is insufficient for a 3 message batch - defaultGasLimit := uint64(5000000) - tr := true - - sourceC := v2.Defaults((*evmUtils.Big)(chainId)) - sourceC.GasEstimator.LimitDefault = &defaultGasLimit - fixedPrice := "FixedPrice" - sourceC.GasEstimator.Mode = &fixedPrice - d, _ := config.NewDuration(100 * time.Millisecond) - sourceC.LogPollInterval = &d - fd := uint32(2) - sourceC.FinalityDepth = &fd - return &v2.EVMConfig{ - ChainID: (*evmUtils.Big)(chainId), - Enabled: &tr, - Chain: sourceC, - Nodes: v2.EVMNodes{&v2.Node{}}, - } -} - -type CCIPIntegrationTestHarness struct { - CCIPContracts - Nodes []Node - Bootstrap Node -} - -func SetupCCIPIntegrationTH(t *testing.T, sourceChainID, sourceChainSelector, destChainId, destChainSelector uint64) CCIPIntegrationTestHarness { - return CCIPIntegrationTestHarness{ - CCIPContracts: SetupCCIPContracts(t, sourceChainID, sourceChainSelector, destChainId, destChainSelector), - } -} - -func (c *CCIPIntegrationTestHarness) CreatePricesPipeline(t *testing.T) (string, *httptest.Server, *httptest.Server) { - linkUSD := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { - _, err := w.Write([]byte(`{"UsdPerLink": "8000000000000000000"}`)) - require.NoError(t, err) - })) - ethUSD := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { - _, err := w.Write([]byte(`{"UsdPerETH": "1700000000000000000000"}`)) - require.NoError(t, err) - })) - sourceWrappedNative, err := c.Source.Router.GetWrappedNative(nil) - require.NoError(t, err) - destWrappedNative, err := c.Dest.Router.GetWrappedNative(nil) - require.NoError(t, err) - tokenPricesUSDPipeline := fmt.Sprintf(` -// Price 1 -link [type=http method=GET url="%s"]; -link_parse [type=jsonparse path="UsdPerLink"]; -link->link_parse; -eth [type=http method=GET url="%s"]; -eth_parse [type=jsonparse path="UsdPerETH"]; -eth->eth_parse; -merge [type=merge left="{}" right="{\\\"%s\\\":$(link_parse), \\\"%s\\\":$(eth_parse), \\\"%s\\\":$(eth_parse)}"];`, - linkUSD.URL, ethUSD.URL, c.Dest.LinkToken.Address(), sourceWrappedNative, destWrappedNative) - - return tokenPricesUSDPipeline, linkUSD, ethUSD -} - -func (c *CCIPIntegrationTestHarness) AddAllJobs(t *testing.T, jobParams integrationtesthelpers.CCIPJobSpecParams) { - jobParams.OffRamp = c.Dest.OffRamp.Address() - - commitSpec, err := jobParams.CommitJobSpec() - require.NoError(t, err) - geExecutionSpec, err := jobParams.ExecutionJobSpec() - require.NoError(t, err) - nodes := c.Nodes - for _, node := range nodes { - node.AddJobsWithSpec(t, commitSpec) - node.AddJobsWithSpec(t, geExecutionSpec) - } -} - -func (c *CCIPIntegrationTestHarness) jobSpecProposal(t *testing.T, specTemplate string, f func() (*integrationtesthelpers.OCR2TaskJobSpec, error), feedsManagerId int64, version int32, opts ...any) feeds2.ProposeJobArgs { - spec, err := f() - require.NoError(t, err) - - args := []any{spec.OCR2OracleSpec.ContractID} - args = append(args, opts...) - - return feeds2.ProposeJobArgs{ - FeedsManagerID: feedsManagerId, - RemoteUUID: uuid.New(), - Multiaddrs: nil, - Version: version, - Spec: fmt.Sprintf(specTemplate, args...), - } -} - -func (c *CCIPIntegrationTestHarness) SetupFeedsManager(t *testing.T) { - ctx := testutils.Context(t) - for _, node := range c.Nodes { - f := node.App.GetFeedsService() - - managers, err := f.ListManagers(ctx) - require.NoError(t, err) - if len(managers) > 0 { - // Use at most one feeds manager, don't register if one already exists - continue - } - - secret := utils.RandomBytes32() - pkey, err := crypto.PublicKeyFromHex(hex.EncodeToString(secret[:])) - require.NoError(t, err) - - m := feeds2.RegisterManagerParams{ - Name: "CCIP", - URI: "http://localhost:8080", - PublicKey: *pkey, - } - - _, err = f.RegisterManager(testutils.Context(t), m) - require.NoError(t, err) - - connManager := feedsMocks.NewConnectionsManager(t) - connManager.On("GetClient", mock.Anything).Maybe().Return(NoopFeedsClient{}, nil) - connManager.On("Close").Maybe().Return() - connManager.On("IsConnected", mock.Anything).Maybe().Return(true) - f.Unsafe_SetConnectionsManager(connManager) - } -} - -func (c *CCIPIntegrationTestHarness) ApproveJobSpecs(t *testing.T, jobParams integrationtesthelpers.CCIPJobSpecParams) { - ctx := testutils.Context(t) - - for _, node := range c.Nodes { - f := node.App.GetFeedsService() - managers, err := f.ListManagers(ctx) - require.NoError(t, err) - require.Len(t, managers, 1, "expected exactly one feeds manager") - - execSpec := c.jobSpecProposal( - t, - execSpecTemplate, - jobParams.ExecutionJobSpec, - managers[0].ID, - 1, - node.KeyBundle.ID(), - node.Transmitter.Hex(), - utils.RandomAddress().String(), - utils.RandomAddress().String(), - ) - execId, err := f.ProposeJob(ctx, &execSpec) - require.NoError(t, err) - - err = f.ApproveSpec(ctx, execId, true) - require.NoError(t, err) - - var commitSpec feeds2.ProposeJobArgs - if jobParams.TokenPricesUSDPipeline != "" { - commitSpec = c.jobSpecProposal( - t, - commitSpecTemplatePipeline, - jobParams.CommitJobSpec, - managers[0].ID, - 2, - node.KeyBundle.ID(), - node.Transmitter.Hex(), - jobParams.OffRamp.String(), - jobParams.TokenPricesUSDPipeline, - ) - } else { - commitSpec = c.jobSpecProposal( - t, - commitSpecTemplateDynamicPriceGetter, - jobParams.CommitJobSpec, - managers[0].ID, - 2, - node.KeyBundle.ID(), - node.Transmitter.Hex(), - jobParams.OffRamp.String(), - jobParams.PriceGetterConfig, - ) - } - - commitId, err := f.ProposeJob(ctx, &commitSpec) - require.NoError(t, err) - - err = f.ApproveSpec(ctx, commitId, true) - require.NoError(t, err) - } -} - -func (c *CCIPIntegrationTestHarness) AllNodesHaveReqSeqNum(t *testing.T, seqNum int, onRampOpts ...common.Address) logpoller.Log { - var log logpoller.Log - nodes := c.Nodes - var onRamp common.Address - if len(onRampOpts) > 0 { - onRamp = onRampOpts[0] - } else { - require.NotNil(t, c.Source.OnRamp, "no onramp configured") - onRamp = c.Source.OnRamp.Address() - } - for _, node := range nodes { - log = node.EventuallyHasReqSeqNum(t, c, onRamp, seqNum) - } - return log -} - -func (c *CCIPIntegrationTestHarness) AllNodesHaveExecutedSeqNums(t *testing.T, minSeqNum int, maxSeqNum int, offRampOpts ...common.Address) []logpoller.Log { - var logs []logpoller.Log - nodes := c.Nodes - var offRamp common.Address - - if len(offRampOpts) > 0 { - offRamp = offRampOpts[0] - } else { - require.NotNil(t, c.Dest.OffRamp, "no offramp configured") - offRamp = c.Dest.OffRamp.Address() - } - for _, node := range nodes { - logs = node.EventuallyHasExecutedSeqNums(t, c, offRamp, minSeqNum, maxSeqNum) - } - return logs -} - -func (c *CCIPIntegrationTestHarness) NoNodesHaveExecutedSeqNum(t *testing.T, seqNum int, offRampOpts ...common.Address) logpoller.Log { - var log logpoller.Log - nodes := c.Nodes - var offRamp common.Address - if len(offRampOpts) > 0 { - offRamp = offRampOpts[0] - } else { - require.NotNil(t, c.Dest.OffRamp, "no offramp configured") - offRamp = c.Dest.OffRamp.Address() - } - for _, node := range nodes { - log = node.ConsistentlySeqNumHasNotBeenExecuted(t, c, offRamp, seqNum) - } - return log -} - -func (c *CCIPIntegrationTestHarness) EventuallyCommitReportAccepted(t *testing.T, currentBlock uint64, commitStoreOpts ...common.Address) commit_store_1_2_0.CommitStoreCommitReport { - var commitStore *commit_store_1_2_0.CommitStore - var err error - if len(commitStoreOpts) > 0 { - commitStore, err = commit_store_1_2_0.NewCommitStore(commitStoreOpts[0], c.Dest.Chain.Client()) - require.NoError(t, err) - } else { - require.NotNil(t, c.Dest.CommitStore, "no commitStore configured") - commitStore = c.Dest.CommitStore - } - g := gomega.NewGomegaWithT(t) - var report commit_store_1_2_0.CommitStoreCommitReport - g.Eventually(func() bool { - it, err := commitStore.FilterReportAccepted(&bind.FilterOpts{Start: currentBlock}) - g.Expect(err).NotTo(gomega.HaveOccurred(), "Error filtering ReportAccepted event") - g.Expect(it.Next()).To(gomega.BeTrue(), "No ReportAccepted event found") - report = it.Event.Report - if report.MerkleRoot != [32]byte{} { - t.Log("Report Accepted by commitStore") - return true - } - return false - }, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue(), "report has not been committed") - return report -} - -func (c *CCIPIntegrationTestHarness) EventuallyExecutionStateChangedToSuccess(t *testing.T, seqNum []uint64, blockNum uint64, offRampOpts ...common.Address) { - var offRamp *evm_2_evm_offramp_1_2_0.EVM2EVMOffRamp - var err error - if len(offRampOpts) > 0 { - offRamp, err = evm_2_evm_offramp_1_2_0.NewEVM2EVMOffRamp(offRampOpts[0], c.Dest.Chain.Client()) - require.NoError(t, err) - } else { - require.NotNil(t, c.Dest.OffRamp, "no offRamp configured") - offRamp = c.Dest.OffRamp - } - gomega.NewGomegaWithT(t).Eventually(func() bool { - it, err := offRamp.FilterExecutionStateChanged(&bind.FilterOpts{Start: blockNum}, seqNum, [][32]byte{}) - require.NoError(t, err) - for it.Next() { - if cciptypes.MessageExecutionState(it.Event.State) == cciptypes.ExecutionStateSuccess { - t.Logf("ExecutionStateChanged event found for seqNum %d", it.Event.SequenceNumber) - return true - } - } - c.Source.Chain.Commit() - c.Dest.Chain.Commit() - return false - }, testutils.WaitTimeout(t), time.Second). - Should(gomega.BeTrue(), "ExecutionStateChanged Event") -} - -func (c *CCIPIntegrationTestHarness) EventuallyReportCommitted(t *testing.T, max int, commitStoreOpts ...common.Address) uint64 { - var commitStore *commit_store_1_2_0.CommitStore - var err error - var committedSeqNum uint64 - if len(commitStoreOpts) > 0 { - commitStore, err = commit_store_1_2_0.NewCommitStore(commitStoreOpts[0], c.Dest.Chain.Client()) - require.NoError(t, err) - } else { - require.NotNil(t, c.Dest.CommitStore, "no commitStore configured") - commitStore = c.Dest.CommitStore - } - gomega.NewGomegaWithT(t).Eventually(func() bool { - minSeqNum, err := commitStore.GetExpectedNextSequenceNumber(nil) - require.NoError(t, err) - c.Source.Chain.Commit() - c.Dest.Chain.Commit() - t.Log("next expected seq num reported", minSeqNum) - committedSeqNum = minSeqNum - return minSeqNum > uint64(max) - }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue(), "report has not been committed") - return committedSeqNum -} - -func (c *CCIPIntegrationTestHarness) EventuallySendRequested(t *testing.T, seqNum uint64, onRampOpts ...common.Address) { - var onRamp *evm_2_evm_onramp_1_2_0.EVM2EVMOnRamp - var err error - if len(onRampOpts) > 0 { - onRamp, err = evm_2_evm_onramp_1_2_0.NewEVM2EVMOnRamp(onRampOpts[0], c.Source.Chain.Client()) - require.NoError(t, err) - } else { - require.NotNil(t, c.Source.OnRamp, "no onRamp configured") - onRamp = c.Source.OnRamp - } - gomega.NewGomegaWithT(t).Eventually(func() bool { - it, err := onRamp.FilterCCIPSendRequested(nil) - require.NoError(t, err) - for it.Next() { - if it.Event.Message.SequenceNumber == seqNum { - t.Log("sendRequested generated for", seqNum) - return true - } - } - c.Source.Chain.Commit() - c.Dest.Chain.Commit() - return false - }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue(), "sendRequested has not been generated") -} - -func (c *CCIPIntegrationTestHarness) ConsistentlyReportNotCommitted(t *testing.T, max int, commitStoreOpts ...common.Address) { - var commitStore *commit_store_1_2_0.CommitStore - var err error - if len(commitStoreOpts) > 0 { - commitStore, err = commit_store_1_2_0.NewCommitStore(commitStoreOpts[0], c.Dest.Chain.Client()) - require.NoError(t, err) - } else { - require.NotNil(t, c.Dest.CommitStore, "no commitStore configured") - commitStore = c.Dest.CommitStore - } - gomega.NewGomegaWithT(t).Consistently(func() bool { - minSeqNum, err := commitStore.GetExpectedNextSequenceNumber(nil) - require.NoError(t, err) - c.Source.Chain.Commit() - c.Dest.Chain.Commit() - t.Log("min seq num reported", minSeqNum) - require.GreaterOrEqual(t, max, 0) - return minSeqNum > uint64(max) //nolint:gosec // G115 false positive - }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeFalse(), "report has been committed") -} - -func (c *CCIPIntegrationTestHarness) SetupAndStartNodes(ctx context.Context, t *testing.T, bootstrapNodePort int64) (Node, []Node, uint64) { - appBootstrap, bootstrapPeerID, bootstrapTransmitter, bootstrapKb := setupNodeCCIP(t, c.Dest.User, bootstrapNodePort, - "bootstrap_ccip", c.Source.Chain, c.Dest.Chain, big.NewInt(0).SetUint64(c.Source.ChainID), - big.NewInt(0).SetUint64(c.Dest.ChainID), "", 0) - var ( - oracles []confighelper.OracleIdentityExtra - nodes []Node - ) - err := appBootstrap.Start(ctx) - require.NoError(t, err) - t.Cleanup(func() { - require.NoError(t, appBootstrap.Stop()) - }) - bootstrapNode := Node{ - App: appBootstrap, - Transmitter: bootstrapTransmitter, - KeyBundle: bootstrapKb, - } - // Set up the minimum 4 oracles all funded with destination ETH - for i := int64(0); i < 4; i++ { - app, peerID, transmitter, kb := setupNodeCCIP( - t, - c.Dest.User, - int64(freeport.GetOne(t)), - fmt.Sprintf("oracle_ccip%d", i), - c.Source.Chain, - c.Dest.Chain, - big.NewInt(0).SetUint64(c.Source.ChainID), - big.NewInt(0).SetUint64(c.Dest.ChainID), - bootstrapPeerID, - bootstrapNodePort, - ) - nodes = append(nodes, Node{ - App: app, - Transmitter: transmitter, - KeyBundle: kb, - }) - offchainPublicKey, _ := hex.DecodeString(strings.TrimPrefix(kb.OnChainPublicKey(), "0x")) - oracles = append(oracles, confighelper.OracleIdentityExtra{ - OracleIdentity: confighelper.OracleIdentity{ - OnchainPublicKey: offchainPublicKey, - TransmitAccount: types4.Account(transmitter.String()), - OffchainPublicKey: kb.OffchainPublicKey(), - PeerID: peerID, - }, - ConfigEncryptionPublicKey: kb.ConfigEncryptionPublicKey(), - }) - err = app.Start(ctx) - require.NoError(t, err) - t.Cleanup(func() { - require.NoError(t, app.Stop()) - }) - } - - c.Oracles = oracles - commitOnchainConfig := c.CreateDefaultCommitOnchainConfig(t) - commitOffchainConfig := c.CreateDefaultCommitOffchainConfig(t) - execOnchainConfig := c.CreateDefaultExecOnchainConfig(t) - execOffchainConfig := c.CreateDefaultExecOffchainConfig(t) - - configBlock := c.SetupOnchainConfig(t, commitOnchainConfig, commitOffchainConfig, execOnchainConfig, execOffchainConfig) - c.Nodes = nodes - c.Bootstrap = bootstrapNode - //nolint:gosec // G115 - return bootstrapNode, nodes, uint64(configBlock) -} - -func (c *CCIPIntegrationTestHarness) SetUpNodesAndJobs(t *testing.T, pricePipeline string, priceGetterConfig string, usdcAttestationAPI string) integrationtesthelpers.CCIPJobSpecParams { - // setup Jobs - ctx := tests.Context(t) - // Starts nodes and configures them in the OCR contracts. - bootstrapNode, _, configBlock := c.SetupAndStartNodes(ctx, t, int64(freeport.GetOne(t))) - - jobParams := c.NewCCIPJobSpecParams(pricePipeline, priceGetterConfig, configBlock, usdcAttestationAPI) - - // Add the bootstrap job - c.Bootstrap.AddBootstrapJob(t, jobParams.BootstrapJob(c.Dest.CommitStore.Address().Hex())) - c.AddAllJobs(t, jobParams) - - // Replay for bootstrap. - bc, err := bootstrapNode.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(c.Dest.ChainID, 10)) - require.NoError(t, err) - require.LessOrEqual(t, configBlock, uint64(math.MaxInt64)) - require.NoError(t, bc.LogPoller().Replay(tests.Context(t), int64(configBlock))) //nolint:gosec // G115 false positive - c.Dest.Chain.Commit() - - return jobParams -} - -func (c *CCIPIntegrationTestHarness) NewCCIPJobSpecParams(tokenPricesUSDPipeline string, priceGetterConfig string, configBlock uint64, usdcAttestationAPI string) integrationtesthelpers.CCIPJobSpecParams { - return integrationtesthelpers.CCIPJobSpecParams{ - CommitStore: c.Dest.CommitStore.Address(), - OffRamp: c.Dest.OffRamp.Address(), - DestEvmChainId: c.Dest.ChainID, - SourceChainName: "SimulatedSource", - DestChainName: "SimulatedDest", - TokenPricesUSDPipeline: tokenPricesUSDPipeline, - PriceGetterConfig: priceGetterConfig, - DestStartBlock: configBlock, - USDCAttestationAPI: usdcAttestationAPI, - } -} - -func DecodeCommitOnChainConfig(encoded []byte) (ccipdata.CommitOnchainConfig, error) { - var onchainConfig ccipdata.CommitOnchainConfig - unpacked, err := abihelpers.DecodeOCR2Config(encoded) - if err != nil { - return onchainConfig, err - } - onChainCfg := unpacked.OnchainConfig - onchainConfig, err = abihelpers.DecodeAbiStruct[ccipdata.CommitOnchainConfig](onChainCfg) - if err != nil { - return onchainConfig, err - } - return onchainConfig, nil -} - -func DecodeExecOnChainConfig(encoded []byte) (v1_2_0.ExecOnchainConfig, error) { - var onchainConfig v1_2_0.ExecOnchainConfig - unpacked, err := abihelpers.DecodeOCR2Config(encoded) - if err != nil { - return onchainConfig, errors.Wrap(err, "failed to unpack log data") - } - onChainCfg := unpacked.OnchainConfig - onchainConfig, err = abihelpers.DecodeAbiStruct[v1_2_0.ExecOnchainConfig](onChainCfg) - if err != nil { - return onchainConfig, err - } - return onchainConfig, nil -} - -type ksa struct { - keystore.Master - csa keystore.CSA -} - -func (k *ksa) CSA() keystore.CSA { - return k.csa -} - -func NewKsa(db *sqlx.DB, lggr logger.Logger, csa keystore.CSA) *ksa { - return &ksa{ - Master: keystore.New(db, clutils.FastScryptParams, lggr), - csa: csa, - } -} - -type NoopFeedsClient struct{} - -func (n NoopFeedsClient) ApprovedJob(context.Context, *pb.ApprovedJobRequest) (*pb.ApprovedJobResponse, error) { - return &pb.ApprovedJobResponse{}, nil -} - -func (n NoopFeedsClient) Healthcheck(context.Context, *pb.HealthcheckRequest) (*pb.HealthcheckResponse, error) { - return &pb.HealthcheckResponse{}, nil -} - -func (n NoopFeedsClient) UpdateNode(context.Context, *pb.UpdateNodeRequest) (*pb.UpdateNodeResponse, error) { - return &pb.UpdateNodeResponse{}, nil -} - -func (n NoopFeedsClient) RejectedJob(context.Context, *pb.RejectedJobRequest) (*pb.RejectedJobResponse, error) { - return &pb.RejectedJobResponse{}, nil -} - -func (n NoopFeedsClient) CancelledJob(context.Context, *pb.CancelledJobRequest) (*pb.CancelledJobResponse, error) { - return &pb.CancelledJobResponse{}, nil -} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/config_1_4_0.go b/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/config_1_4_0.go deleted file mode 100644 index 087c21e9333..00000000000 --- a/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0/config_1_4_0.go +++ /dev/null @@ -1,75 +0,0 @@ -// Package with set of configs that should be used only within tests suites - -package testhelpers_1_4_0 - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink-common/pkg/config" - - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata/v1_2_0" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" -) - -var PermissionLessExecutionThresholdSeconds = uint32(testhelpers.FirstBlockAge.Seconds()) - -func (c *CCIPContracts) CreateDefaultCommitOnchainConfig(t *testing.T) []byte { - config, err := abihelpers.EncodeAbiStruct(ccipdata.CommitOnchainConfig{ - PriceRegistry: c.Dest.PriceRegistry.Address(), - }) - require.NoError(t, err) - return config -} - -func (c *CCIPContracts) CreateDefaultCommitOffchainConfig(t *testing.T) []byte { - return c.createCommitOffchainConfig(t, 10*time.Second, 5*time.Second) -} - -func (c *CCIPContracts) createCommitOffchainConfig(t *testing.T, feeUpdateHearBeat time.Duration, inflightCacheExpiry time.Duration) []byte { - config, err := NewCommitOffchainConfig( - *config.MustNewDuration(feeUpdateHearBeat), - 1, - 1, - *config.MustNewDuration(feeUpdateHearBeat), - 1, - *config.MustNewDuration(inflightCacheExpiry), - false, - ).Encode() - require.NoError(t, err) - return config -} - -func (c *CCIPContracts) CreateDefaultExecOnchainConfig(t *testing.T) []byte { - config, err := abihelpers.EncodeAbiStruct(v1_2_0.ExecOnchainConfig{ - PermissionLessExecutionThresholdSeconds: PermissionLessExecutionThresholdSeconds, - Router: c.Dest.Router.Address(), - PriceRegistry: c.Dest.PriceRegistry.Address(), - MaxDataBytes: 1e5, - MaxNumberOfTokensPerMsg: 5, - MaxPoolReleaseOrMintGas: 200_000, - }) - require.NoError(t, err) - return config -} - -func (c *CCIPContracts) CreateDefaultExecOffchainConfig(t *testing.T) []byte { - return c.createExecOffchainConfig(t, 1*time.Minute, 1*time.Minute) -} - -func (c *CCIPContracts) createExecOffchainConfig(t *testing.T, inflightCacheExpiry time.Duration, rootSnoozeTime time.Duration) []byte { - config, err := NewExecOffchainConfig( - 1, - 5_000_000, - 0.07, - *config.MustNewDuration(inflightCacheExpiry), - *config.MustNewDuration(rootSnoozeTime), - uint32(0), - ).Encode() - require.NoError(t, err) - return config -} diff --git a/core/services/ocr2/plugins/mercury/plugin.go b/core/services/ocr2/plugins/mercury/plugin.go index 8a4101804dd..b0983e55c89 100644 --- a/core/services/ocr2/plugins/mercury/plugin.go +++ b/core/services/ocr2/plugins/mercury/plugin.go @@ -1,6 +1,7 @@ package mercury import ( + "context" "encoding/json" "fmt" "os/exec" @@ -79,14 +80,13 @@ func NewServices( return nil, errors.New("expected job to have a non-nil PipelineSpec") } - var err error var pluginConfig config.PluginConfig if len(jb.OCR2OracleSpec.PluginConfig) == 0 { if !enableTriggerCapability { return nil, fmt.Errorf("at least one transmission option must be configured") } } else { - err = json.Unmarshal(jb.OCR2OracleSpec.PluginConfig.Bytes(), &pluginConfig) + err := json.Unmarshal(jb.OCR2OracleSpec.PluginConfig.Bytes(), &pluginConfig) if err != nil { return nil, errors.WithStack(err) } @@ -101,8 +101,8 @@ func NewServices( // encapsulate all the subservices and ensure we close them all if any fail to start srvs := []job.ServiceCtx{ocr2Provider} abort := func() { - if err = services.MultiCloser(srvs).Close(); err != nil { - lggr.Errorw("Error closing unused services", "err", err) + if cerr := services.MultiCloser(srvs).Close(); cerr != nil { + lggr.Errorw("Error closing unused services", "err", cerr) } } saver := ocrcommon.NewResultRunSaver(pipelineRunner, lggr, cfg.MaxSuccessfulRuns(), cfg.ResultWriteQueueDepth()) @@ -112,6 +112,7 @@ func NewServices( var ( factory ocr3types.MercuryPluginFactory factoryServices []job.ServiceCtx + fErr error ) fCfg := factoryCfg{ orm: orm, @@ -127,31 +128,31 @@ func NewServices( } switch feedID.Version() { case 1: - factory, factoryServices, err = newv1factory(fCfg) - if err != nil { + factory, factoryServices, fErr = newv1factory(fCfg) + if fErr != nil { abort() - return nil, fmt.Errorf("failed to create mercury v1 factory: %w", err) + return nil, fmt.Errorf("failed to create mercury v1 factory: %w", fErr) } srvs = append(srvs, factoryServices...) case 2: - factory, factoryServices, err = newv2factory(fCfg) - if err != nil { + factory, factoryServices, fErr = newv2factory(fCfg) + if fErr != nil { abort() - return nil, fmt.Errorf("failed to create mercury v2 factory: %w", err) + return nil, fmt.Errorf("failed to create mercury v2 factory: %w", fErr) } srvs = append(srvs, factoryServices...) case 3: - factory, factoryServices, err = newv3factory(fCfg) - if err != nil { + factory, factoryServices, fErr = newv3factory(fCfg) + if fErr != nil { abort() - return nil, fmt.Errorf("failed to create mercury v3 factory: %w", err) + return nil, fmt.Errorf("failed to create mercury v3 factory: %w", fErr) } srvs = append(srvs, factoryServices...) case 4: - factory, factoryServices, err = newv4factory(fCfg) - if err != nil { + factory, factoryServices, fErr = newv4factory(fCfg) + if fErr != nil { abort() - return nil, fmt.Errorf("failed to create mercury v4 factory: %w", err) + return nil, fmt.Errorf("failed to create mercury v4 factory: %w", fErr) } srvs = append(srvs, factoryServices...) default: @@ -214,13 +215,14 @@ func newv4factory(factoryCfg factoryCfg) (ocr3types.MercuryPluginFactory, []job. loopEnabled := loopCmd != "" if loopEnabled { - cmdFn, opts, mercuryLggr, err := initLoop(loopCmd, factoryCfg.cfg, factoryCfg.feedID, factoryCfg.lggr) + cmdFn, unregisterer, opts, mercuryLggr, err := initLoop(loopCmd, factoryCfg.cfg, factoryCfg.feedID, factoryCfg.lggr) if err != nil { return nil, nil, fmt.Errorf("failed to init loop for feed %s: %w", factoryCfg.feedID, err) } // in loop mode, the factory is grpc server, and we need to handle the server lifecycle + // and unregistration of the loop factoryServer := loop.NewMercuryV4Service(mercuryLggr, opts, cmdFn, factoryCfg.ocr2Provider, ds) - srvs = append(srvs, factoryServer) + srvs = append(srvs, factoryServer, unregisterer) // adapt the grpc server to the vanilla mercury plugin factory interface used by the oracle factory = factoryServer } else { @@ -253,13 +255,14 @@ func newv3factory(factoryCfg factoryCfg) (ocr3types.MercuryPluginFactory, []job. loopEnabled := loopCmd != "" if loopEnabled { - cmdFn, opts, mercuryLggr, err := initLoop(loopCmd, factoryCfg.cfg, factoryCfg.feedID, factoryCfg.lggr) + cmdFn, unregisterer, opts, mercuryLggr, err := initLoop(loopCmd, factoryCfg.cfg, factoryCfg.feedID, factoryCfg.lggr) if err != nil { return nil, nil, fmt.Errorf("failed to init loop for feed %s: %w", factoryCfg.feedID, err) } // in loopp mode, the factory is grpc server, and we need to handle the server lifecycle + // and unregistration of the loop factoryServer := loop.NewMercuryV3Service(mercuryLggr, opts, cmdFn, factoryCfg.ocr2Provider, ds) - srvs = append(srvs, factoryServer) + srvs = append(srvs, factoryServer, unregisterer) // adapt the grpc server to the vanilla mercury plugin factory interface used by the oracle factory = factoryServer } else { @@ -292,13 +295,14 @@ func newv2factory(factoryCfg factoryCfg) (ocr3types.MercuryPluginFactory, []job. loopEnabled := loopCmd != "" if loopEnabled { - cmdFn, opts, mercuryLggr, err := initLoop(loopCmd, factoryCfg.cfg, factoryCfg.feedID, factoryCfg.lggr) + cmdFn, unregisterer, opts, mercuryLggr, err := initLoop(loopCmd, factoryCfg.cfg, factoryCfg.feedID, factoryCfg.lggr) if err != nil { return nil, nil, fmt.Errorf("failed to init loop for feed %s: %w", factoryCfg.feedID, err) } // in loopp mode, the factory is grpc server, and we need to handle the server lifecycle + // and unregistration of the loop factoryServer := loop.NewMercuryV2Service(mercuryLggr, opts, cmdFn, factoryCfg.ocr2Provider, ds) - srvs = append(srvs, factoryServer) + srvs = append(srvs, factoryServer, unregisterer) // adapt the grpc server to the vanilla mercury plugin factory interface used by the oracle factory = factoryServer } else { @@ -329,13 +333,14 @@ func newv1factory(factoryCfg factoryCfg) (ocr3types.MercuryPluginFactory, []job. loopEnabled := loopCmd != "" if loopEnabled { - cmdFn, opts, mercuryLggr, err := initLoop(loopCmd, factoryCfg.cfg, factoryCfg.feedID, factoryCfg.lggr) + cmdFn, unregisterer, opts, mercuryLggr, err := initLoop(loopCmd, factoryCfg.cfg, factoryCfg.feedID, factoryCfg.lggr) if err != nil { return nil, nil, fmt.Errorf("failed to init loop for feed %s: %w", factoryCfg.feedID, err) } // in loopp mode, the factory is grpc server, and we need to handle the server lifecycle + // and unregistration of the loop factoryServer := loop.NewMercuryV1Service(mercuryLggr, opts, cmdFn, factoryCfg.ocr2Provider, ds) - srvs = append(srvs, factoryServer) + srvs = append(srvs, factoryServer, unregisterer) // adapt the grpc server to the vanilla mercury plugin factory interface used by the oracle factory = factoryServer } else { @@ -344,20 +349,46 @@ func newv1factory(factoryCfg factoryCfg) (ocr3types.MercuryPluginFactory, []job. return factory, srvs, nil } -func initLoop(cmd string, cfg Config, feedID utils.FeedID, lggr logger.Logger) (func() *exec.Cmd, loop.GRPCOpts, logger.Logger, error) { +func initLoop(cmd string, cfg Config, feedID utils.FeedID, lggr logger.Logger) (func() *exec.Cmd, *loopUnregisterCloser, loop.GRPCOpts, logger.Logger, error) { lggr.Debugw("Initializing Mercury loop", "command", cmd) mercuryLggr := lggr.Named(fmt.Sprintf("MercuryV%d", feedID.Version())).Named(feedID.String()) envVars, err := plugins.ParseEnvFile(env.MercuryPlugin.Env.Get()) if err != nil { - return nil, loop.GRPCOpts{}, nil, fmt.Errorf("failed to parse mercury env file: %w", err) + return nil, nil, loop.GRPCOpts{}, nil, fmt.Errorf("failed to parse mercury env file: %w", err) } + loopID := mercuryLggr.Name() cmdFn, opts, err := cfg.RegisterLOOP(plugins.CmdConfig{ - ID: mercuryLggr.Name(), + ID: loopID, Cmd: cmd, Env: envVars, }) if err != nil { - return nil, loop.GRPCOpts{}, nil, fmt.Errorf("failed to register loop: %w", err) + return nil, nil, loop.GRPCOpts{}, nil, fmt.Errorf("failed to register loop: %w", err) + } + return cmdFn, newLoopUnregister(cfg, loopID), opts, mercuryLggr, nil +} + +// loopUnregisterCloser is a helper to unregister a loop +// as a service +// TODO BCF-3451 all other jobs that use custom plugin providers that should be refactored to use this pattern +// perhaps it can be implemented in the delegate on job delete. +type loopUnregisterCloser struct { + r plugins.RegistrarConfig + id string +} + +func (l *loopUnregisterCloser) Close() error { + l.r.UnregisterLOOP(l.id) + return nil +} + +func (l *loopUnregisterCloser) Start(ctx context.Context) error { + return nil +} + +func newLoopUnregister(r plugins.RegistrarConfig, id string) *loopUnregisterCloser { + return &loopUnregisterCloser{ + r: r, + id: id, } - return cmdFn, opts, mercuryLggr, nil } diff --git a/core/services/ocr2/plugins/mercury/plugin_test.go b/core/services/ocr2/plugins/mercury/plugin_test.go index 22aaf7522de..eb67da53100 100644 --- a/core/services/ocr2/plugins/mercury/plugin_test.go +++ b/core/services/ocr2/plugins/mercury/plugin_test.go @@ -2,6 +2,7 @@ package mercury_test import ( "context" + "errors" "os/exec" "reflect" "testing" @@ -9,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/google/uuid" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/config/env" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -22,6 +24,7 @@ import ( v2 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v2" v3 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v3" v4 "github.com/smartcontractkit/chainlink-common/pkg/types/mercury/v4" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" mercuryocr2 "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/mercury" @@ -92,21 +95,23 @@ var ( // this is kind of gross, but it's the best way to test return values of the services expectedEmbeddedServiceCnt = 3 - expectedLoopServiceCnt = expectedEmbeddedServiceCnt + 1 + expectedLoopServiceCnt = expectedEmbeddedServiceCnt + 2 // factory server and loop unregisterer ) func TestNewServices(t *testing.T) { type args struct { pluginConfig job.JSONConfig feedID utils.FeedID + cfg mercuryocr2.Config } - tests := []struct { + testCases := []struct { name string args args loopMode bool wantLoopFactory any wantServiceCnt int wantErr bool + wantErrStr string }{ { name: "no plugin config error ", @@ -186,6 +191,19 @@ func TestNewServices(t *testing.T) { wantErr: false, wantLoopFactory: &loop.MercuryV3Service{}, }, + { + name: "v3 loop err", + loopMode: true, + args: args{ + pluginConfig: v3jsonCfg, + feedID: v3FeedId, + cfg: mercuryocr2.NewMercuryConfig(1, 1, &testRegistrarConfig{failRegister: true}), + }, + wantServiceCnt: expectedLoopServiceCnt, + wantErr: true, + wantLoopFactory: &loop.MercuryV3Service{}, + wantErrStr: "failed to init loop for feed", + }, { name: "v4 loop", loopMode: true, @@ -198,17 +216,27 @@ func TestNewServices(t *testing.T) { wantLoopFactory: &loop.MercuryV4Service{}, }, } - for _, tt := range tests { + for _, tt := range testCases { t.Run(tt.name, func(t *testing.T) { if tt.loopMode { t.Setenv(string(env.MercuryPlugin.Cmd), "fake_cmd") assert.NotEmpty(t, env.MercuryPlugin.Cmd.Get()) } - got, err := newServicesTestWrapper(t, tt.args.pluginConfig, tt.args.feedID) + // use default config if not provided + if tt.args.cfg == nil { + tt.args.cfg = testCfg + } + got, err := newServicesTestWrapper(t, tt.args.pluginConfig, tt.args.feedID, tt.args.cfg) if (err != nil) != tt.wantErr { t.Errorf("NewServices() error = %v, wantErr %v", err, tt.wantErr) return } + if err != nil { + if tt.wantErrStr != "" { + assert.Contains(t, err.Error(), tt.wantErrStr) + } + return + } assert.Len(t, got, tt.wantServiceCnt) if tt.loopMode { foundLoopFactory := false @@ -222,15 +250,97 @@ func TestNewServices(t *testing.T) { } }) } + + t.Run("restartable loop", func(t *testing.T) { + // setup a real loop registry to test restartability + registry := plugins.NewLoopRegistry(logger.TestLogger(t), nil, nil, nil, "") + loopRegistrarConfig := plugins.NewRegistrarConfig(loop.GRPCOpts{}, registry.Register, registry.Unregister) + prodCfg := mercuryocr2.NewMercuryConfig(1, 1, loopRegistrarConfig) + type args struct { + pluginConfig job.JSONConfig + feedID utils.FeedID + cfg mercuryocr2.Config + } + testCases := []struct { + name string + args args + wantErr bool + }{ + { + name: "v1 loop", + args: args{ + pluginConfig: v1jsonCfg, + feedID: v1FeedId, + cfg: prodCfg, + }, + wantErr: false, + }, + { + name: "v2 loop", + args: args{ + pluginConfig: v2jsonCfg, + feedID: v2FeedId, + cfg: prodCfg, + }, + wantErr: false, + }, + { + name: "v3 loop", + args: args{ + pluginConfig: v3jsonCfg, + feedID: v3FeedId, + cfg: prodCfg, + }, + wantErr: false, + }, + { + name: "v4 loop", + args: args{ + pluginConfig: v4jsonCfg, + feedID: v4FeedId, + cfg: prodCfg, + }, + wantErr: false, + }, + } + + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + t.Setenv(string(env.MercuryPlugin.Cmd), "fake_cmd") + assert.NotEmpty(t, env.MercuryPlugin.Cmd.Get()) + + got, err := newServicesTestWrapper(t, tt.args.pluginConfig, tt.args.feedID, tt.args.cfg) + if (err != nil) != tt.wantErr { + t.Errorf("NewServices() error = %v, wantErr %v", err, tt.wantErr) + return + } + // hack to simulate a restart. we don't have enough boilerplate to start the oracle service + // only care about the subservices so we start all except the oracle, which happens to be the last one + for i := 0; i < len(got)-1; i++ { + require.NoError(t, got[i].Start(tests.Context(t))) + } + // if we don't close the services, we get conflicts with the loop registry + _, err = newServicesTestWrapper(t, tt.args.pluginConfig, tt.args.feedID, tt.args.cfg) + require.ErrorContains(t, err, "plugin already registered") + + // close all services and try again + for i := len(got) - 2; i >= 0; i-- { + require.NoError(t, got[i].Close()) + } + _, err = newServicesTestWrapper(t, tt.args.pluginConfig, tt.args.feedID, tt.args.cfg) + require.NoError(t, err) + }) + } + }) } // we are only varying the version via feedID (and the plugin config) // this wrapper supplies dummy values for the rest of the arguments -func newServicesTestWrapper(t *testing.T, pluginConfig job.JSONConfig, feedID utils.FeedID) ([]job.ServiceCtx, error) { +func newServicesTestWrapper(t *testing.T, pluginConfig job.JSONConfig, feedID utils.FeedID, cfg mercuryocr2.Config) ([]job.ServiceCtx, error) { t.Helper() jb := testJob jb.OCR2OracleSpec.PluginConfig = pluginConfig - return mercuryocr2.NewServices(jb, &testProvider{}, nil, logger.TestLogger(t), testArgsNoPlugin, testCfg, nil, &testDataSourceORM{}, feedID, false) + return mercuryocr2.NewServices(jb, &testProvider{}, nil, logger.TestLogger(t), testArgsNoPlugin, cfg, nil, &testDataSourceORM{}, feedID, false) } type testProvider struct{} @@ -292,16 +402,21 @@ func (*testProvider) ReportCodecV3() v3.ReportCodec { return nil } func (*testProvider) ReportCodecV4() v4.ReportCodec { return nil } // Start implements types.MercuryProvider. -func (*testProvider) Start(context.Context) error { panic("unimplemented") } +func (*testProvider) Start(context.Context) error { return nil } var _ commontypes.MercuryProvider = (*testProvider)(nil) -type testRegistrarConfig struct{} +type testRegistrarConfig struct { + failRegister bool +} func (c *testRegistrarConfig) UnregisterLOOP(ID string) {} // RegisterLOOP implements plugins.RegistrarConfig. -func (*testRegistrarConfig) RegisterLOOP(config plugins.CmdConfig) (func() *exec.Cmd, loop.GRPCOpts, error) { +func (c *testRegistrarConfig) RegisterLOOP(config plugins.CmdConfig) (func() *exec.Cmd, loop.GRPCOpts, error) { + if c.failRegister { + return nil, loop.GRPCOpts{}, errors.New("failed to register") + } return nil, loop.GRPCOpts{}, nil } diff --git a/core/services/ocr3/promwrapper/factory.go b/core/services/ocr3/promwrapper/factory.go index 6518cea3c0d..e369b3260ef 100644 --- a/core/services/ocr3/promwrapper/factory.go +++ b/core/services/ocr3/promwrapper/factory.go @@ -47,6 +47,7 @@ func (r ReportingPluginFactory[RI]) NewReportingPlugin(ctx context.Context, conf config.ConfigDigest.String(), promOCR3ReportsGenerated, promOCR3Durations, + promOCR3Sizes, promOCR3PluginStatus, ) return wrapped, info, err diff --git a/core/services/ocr3/promwrapper/plugin.go b/core/services/ocr3/promwrapper/plugin.go index dcee5050d1e..aa5fb87a6ee 100644 --- a/core/services/ocr3/promwrapper/plugin.go +++ b/core/services/ocr3/promwrapper/plugin.go @@ -21,6 +21,7 @@ type reportingPlugin[RI any] struct { // Prometheus components for tracking metrics reportsGenerated *prometheus.CounterVec durations *prometheus.HistogramVec + sizes *prometheus.CounterVec status *prometheus.GaugeVec } @@ -31,6 +32,7 @@ func newReportingPlugin[RI any]( configDigest string, reportsGenerated *prometheus.CounterVec, durations *prometheus.HistogramVec, + sizes *prometheus.CounterVec, status *prometheus.GaugeVec, ) *reportingPlugin[RI] { return &reportingPlugin[RI]{ @@ -40,6 +42,7 @@ func newReportingPlugin[RI any]( configDigest: configDigest, reportsGenerated: reportsGenerated, durations: durations, + sizes: sizes, status: status, } } @@ -51,9 +54,11 @@ func (p *reportingPlugin[RI]) Query(ctx context.Context, outctx ocr3types.Outcom } func (p *reportingPlugin[RI]) Observation(ctx context.Context, outctx ocr3types.OutcomeContext, query ocrtypes.Query) (ocrtypes.Observation, error) { - return withObservedExecution(p, observation, func() (ocrtypes.Observation, error) { + result, err := withObservedExecution(p, observation, func() (ocrtypes.Observation, error) { return p.ReportingPlugin.Observation(ctx, outctx, query) }) + p.trackSize(observation, len(result), err) + return result, err } func (p *reportingPlugin[RI]) ValidateObservation(ctx context.Context, outctx ocr3types.OutcomeContext, query ocrtypes.Query, ao ocrtypes.AttributedObservation) error { @@ -65,9 +70,11 @@ func (p *reportingPlugin[RI]) ValidateObservation(ctx context.Context, outctx oc } func (p *reportingPlugin[RI]) Outcome(ctx context.Context, outctx ocr3types.OutcomeContext, query ocrtypes.Query, aos []ocrtypes.AttributedObservation) (ocr3types.Outcome, error) { - return withObservedExecution(p, outcome, func() (ocr3types.Outcome, error) { + result, err := withObservedExecution(p, outcome, func() (ocr3types.Outcome, error) { return p.ReportingPlugin.Outcome(ctx, outctx, query, aos) }) + p.trackSize(outcome, len(result), err) + return result, err } func (p *reportingPlugin[RI]) Reports(ctx context.Context, seqNr uint64, outcome ocr3types.Outcome) ([]ocr3types.ReportPlus[RI], error) { @@ -111,6 +118,15 @@ func (p *reportingPlugin[RI]) updateStatus(status bool) { Set(float64(boolToInt(status))) } +func (p *reportingPlugin[RI]) trackSize(function functionType, size int, err error) { + if err != nil { + return + } + p.sizes. + WithLabelValues(p.chainID, p.plugin, string(function)). + Add(float64(size)) +} + func boolToInt(arg bool) int { if arg { return 1 diff --git a/core/services/ocr3/promwrapper/plugin_test.go b/core/services/ocr3/promwrapper/plugin_test.go index 9a7b6f2e648..a10a467799f 100644 --- a/core/services/ocr3/promwrapper/plugin_test.go +++ b/core/services/ocr3/promwrapper/plugin_test.go @@ -17,17 +17,20 @@ import ( ) func Test_ReportsGeneratedGauge(t *testing.T) { + pluginObservationSize := 5 + pluginOutcomeSize := 3 + plugin1 := newReportingPlugin( fakePlugin[uint]{reports: make([]ocr3types.ReportPlus[uint], 2)}, - "123", "empty", "abc", promOCR3ReportsGenerated, promOCR3Durations, promOCR3PluginStatus, + "123", "empty", "abc", promOCR3ReportsGenerated, promOCR3Durations, promOCR3Sizes, promOCR3PluginStatus, ) plugin2 := newReportingPlugin( - fakePlugin[bool]{reports: make([]ocr3types.ReportPlus[bool], 10)}, - "solana", "different_plugin", "abc", promOCR3ReportsGenerated, promOCR3Durations, promOCR3PluginStatus, + fakePlugin[bool]{reports: make([]ocr3types.ReportPlus[bool], 10), observationSize: pluginObservationSize, outcomeSize: pluginOutcomeSize}, + "solana", "different_plugin", "abc", promOCR3ReportsGenerated, promOCR3Durations, promOCR3Sizes, promOCR3PluginStatus, ) plugin3 := newReportingPlugin( fakePlugin[string]{err: errors.New("error")}, - "1234", "empty", "abc", promOCR3ReportsGenerated, promOCR3Durations, promOCR3PluginStatus, + "1234", "empty", "abc", promOCR3ReportsGenerated, promOCR3Durations, promOCR3Sizes, promOCR3PluginStatus, ) r1, err := plugin1.Reports(tests.Context(t), 1, nil) @@ -64,20 +67,33 @@ func Test_ReportsGeneratedGauge(t *testing.T) { require.NoError(t, plugin1.Close()) pluginHealth = testutil.ToFloat64(promOCR3PluginStatus.WithLabelValues("123", "empty", "abc")) require.Equal(t, 0, int(pluginHealth)) + + iterations := 10 + for i := 0; i < iterations; i++ { + _, err1 := plugin2.Outcome(tests.Context(t), ocr3types.OutcomeContext{}, nil, nil) + require.NoError(t, err1) + } + _, err1 := plugin2.Observation(tests.Context(t), ocr3types.OutcomeContext{}, nil) + require.NoError(t, err1) + + outcomesLen := testutil.ToFloat64(promOCR3Sizes.WithLabelValues("solana", "different_plugin", "outcome")) + require.Equal(t, pluginOutcomeSize*iterations, int(outcomesLen)) + observationLen := testutil.ToFloat64(promOCR3Sizes.WithLabelValues("solana", "different_plugin", "observation")) + require.Equal(t, pluginObservationSize, int(observationLen)) } func Test_DurationHistograms(t *testing.T) { plugin1 := newReportingPlugin( fakePlugin[uint]{}, - "123", "empty", "abc", promOCR3ReportsGenerated, promOCR3Durations, promOCR3PluginStatus, + "123", "empty", "abc", promOCR3ReportsGenerated, promOCR3Durations, promOCR3Sizes, promOCR3PluginStatus, ) plugin2 := newReportingPlugin( fakePlugin[uint]{err: errors.New("error")}, - "123", "empty", "abc", promOCR3ReportsGenerated, promOCR3Durations, promOCR3PluginStatus, + "123", "empty", "abc", promOCR3ReportsGenerated, promOCR3Durations, promOCR3Sizes, promOCR3PluginStatus, ) plugin3 := newReportingPlugin( fakePlugin[uint]{}, - "solana", "commit", "abc", promOCR3ReportsGenerated, promOCR3Durations, promOCR3PluginStatus, + "solana", "commit", "abc", promOCR3ReportsGenerated, promOCR3Durations, promOCR3Sizes, promOCR3PluginStatus, ) for _, p := range []*reportingPlugin[uint]{plugin1, plugin2, plugin3} { @@ -102,8 +118,10 @@ func Test_DurationHistograms(t *testing.T) { } type fakePlugin[RI any] struct { - reports []ocr3types.ReportPlus[RI] - err error + reports []ocr3types.ReportPlus[RI] + observationSize int + outcomeSize int + err error } func (f fakePlugin[RI]) Query(context.Context, ocr3types.OutcomeContext) (ocrtypes.Query, error) { @@ -117,7 +135,7 @@ func (f fakePlugin[RI]) Observation(context.Context, ocr3types.OutcomeContext, o if f.err != nil { return nil, f.err } - return ocrtypes.Observation{}, nil + return make([]byte, f.observationSize), nil } func (f fakePlugin[RI]) ValidateObservation(context.Context, ocr3types.OutcomeContext, ocrtypes.Query, ocrtypes.AttributedObservation) error { @@ -132,7 +150,7 @@ func (f fakePlugin[RI]) Outcome(context.Context, ocr3types.OutcomeContext, ocrty if f.err != nil { return nil, f.err } - return ocr3types.Outcome{}, nil + return make([]byte, f.outcomeSize), nil } func (f fakePlugin[RI]) Reports(context.Context, uint64, ocr3types.Outcome) ([]ocr3types.ReportPlus[RI], error) { diff --git a/core/services/ocr3/promwrapper/types.go b/core/services/ocr3/promwrapper/types.go index 2fa29dcdf20..59468358783 100644 --- a/core/services/ocr3/promwrapper/types.go +++ b/core/services/ocr3/promwrapper/types.go @@ -48,6 +48,13 @@ var ( }, []string{"chainID", "plugin", "function", "success"}, ) + promOCR3Sizes = promauto.NewCounterVec( + prometheus.CounterOpts{ + Name: "ocr3_reporting_plugin_data_sizes", + Help: "Tracks the size of the data produced by OCR3 plugin in bytes (e.g. reports, observations etc.)", + }, + []string{"chainID", "plugin", "function"}, + ) promOCR3PluginStatus = promauto.NewGaugeVec( prometheus.GaugeOpts{ Name: "ocr3_reporting_plugin_status", diff --git a/core/services/relay/evm/capabilities/testutils/backend.go b/core/services/relay/evm/capabilities/testutils/backend.go index e76dbc3bc73..cd04373e29e 100644 --- a/core/services/relay/evm/capabilities/testutils/backend.go +++ b/core/services/relay/evm/capabilities/testutils/backend.go @@ -118,5 +118,5 @@ func (th *EVMBackendTH) NewContractReader(ctx context.Context, t *testing.T, cfg return nil, err } - return svc, svc.Start(ctx) + return svc, err } diff --git a/core/services/relay/evm/capabilities/workflows/syncer/workflow_syncer_test.go b/core/services/relay/evm/capabilities/workflows/syncer/workflow_syncer_test.go index 3bcf8164a7b..c7c164803cb 100644 --- a/core/services/relay/evm/capabilities/workflows/syncer/workflow_syncer_test.go +++ b/core/services/relay/evm/capabilities/workflows/syncer/workflow_syncer_test.go @@ -3,9 +3,12 @@ package workflow_registry_syncer_test import ( "context" "crypto/rand" + "encoding/base64" "encoding/hex" - "encoding/json" "fmt" + rand2 "math/rand/v2" + "strings" + "sync" "testing" "time" @@ -16,30 +19,52 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/custmsg" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/workflows" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/workflow/generated/workflow_registry_wrapper" coretestutils "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/workflowkey" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/capabilities/testutils" - evmtypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" "github.com/smartcontractkit/chainlink/v2/core/services/workflows/syncer" "github.com/smartcontractkit/chainlink/v2/core/utils/crypto" "github.com/stretchr/testify/require" + + crypto2 "github.com/ethereum/go-ethereum/crypto" ) type testEvtHandler struct { events []syncer.Event + mux sync.Mutex } func (m *testEvtHandler) Handle(ctx context.Context, event syncer.Event) error { + m.mux.Lock() + defer m.mux.Unlock() m.events = append(m.events, event) return nil } +func (m *testEvtHandler) ClearEvents() { + m.mux.Lock() + defer m.mux.Unlock() + m.events = make([]syncer.Event, 0) +} + +func (m *testEvtHandler) GetEvents() []syncer.Event { + m.mux.Lock() + defer m.mux.Unlock() + + eventsCopy := make([]syncer.Event, len(m.events)) + copy(eventsCopy, m.events) + + return eventsCopy +} + func newTestEvtHandler() *testEvtHandler { return &testEvtHandler{ events: make([]syncer.Event, 0), @@ -66,6 +91,138 @@ func (m *testWorkflowRegistryContractLoader) LoadWorkflows(ctx context.Context, }, nil } +func Test_EventHandlerStateSync(t *testing.T) { + lggr := logger.TestLogger(t) + backendTH := testutils.NewEVMBackendTH(t) + donID := uint32(1) + + eventPollTicker := time.NewTicker(50 * time.Millisecond) + defer eventPollTicker.Stop() + + // Deploy a test workflow_registry + wfRegistryAddr, _, wfRegistryC, err := workflow_registry_wrapper.DeployWorkflowRegistry(backendTH.ContractsOwner, backendTH.Backend.Client()) + backendTH.Backend.Commit() + require.NoError(t, err) + + // setup contract state to allow the secrets to be updated + updateAllowedDONs(t, backendTH, wfRegistryC, []uint32{donID}, true) + updateAuthorizedAddress(t, backendTH, wfRegistryC, []common.Address{backendTH.ContractsOwner.From}, true) + + // Create some initial static state + numberWorkflows := 20 + for i := 0; i < numberWorkflows; i++ { + var workflowID [32]byte + _, err = rand.Read((workflowID)[:]) + require.NoError(t, err) + workflow := RegisterWorkflowCMD{ + Name: fmt.Sprintf("test-wf-%d", i), + DonID: donID, + Status: uint8(1), + SecretsURL: "someurl", + } + workflow.ID = workflowID + registerWorkflow(t, backendTH, wfRegistryC, workflow) + } + + testEventHandler := newTestEvtHandler() + loader := syncer.NewWorkflowRegistryContractLoader(lggr, wfRegistryAddr.Hex(), func(ctx context.Context, bytes []byte) (syncer.ContractReader, error) { + return backendTH.NewContractReader(ctx, t, bytes) + }, testEventHandler) + + // Create the registry + registry := syncer.NewWorkflowRegistry( + lggr, + func(ctx context.Context, bytes []byte) (syncer.ContractReader, error) { + return backendTH.NewContractReader(ctx, t, bytes) + }, + wfRegistryAddr.Hex(), + syncer.WorkflowEventPollerConfig{ + QueryCount: 20, + }, + testEventHandler, + loader, + &testDonNotifier{ + don: capabilities.DON{ + ID: donID, + }, + err: nil, + }, + syncer.WithTicker(eventPollTicker.C), + ) + + servicetest.Run(t, registry) + + require.Eventually(t, func() bool { + numEvents := len(testEventHandler.GetEvents()) + return numEvents == numberWorkflows + }, 5*time.Second, time.Second) + + for _, event := range testEventHandler.GetEvents() { + assert.Equal(t, syncer.WorkflowRegisteredEvent, event.GetEventType()) + } + + testEventHandler.ClearEvents() + + // Create different event types for a number of workflows and confirm that the event handler processes them in order + numberOfEventCycles := 50 + for i := 0; i < numberOfEventCycles; i++ { + var workflowID [32]byte + _, err = rand.Read((workflowID)[:]) + require.NoError(t, err) + workflow := RegisterWorkflowCMD{ + Name: "test-wf-register-event", + DonID: donID, + Status: uint8(1), + SecretsURL: "", + } + workflow.ID = workflowID + + // Generate events of different types with some jitter + registerWorkflow(t, backendTH, wfRegistryC, workflow) + time.Sleep(time.Millisecond * time.Duration(rand2.IntN(10))) + data := append(backendTH.ContractsOwner.From.Bytes(), []byte(workflow.Name)...) + workflowKey := crypto2.Keccak256Hash(data) + activateWorkflow(t, backendTH, wfRegistryC, workflowKey) + time.Sleep(time.Millisecond * time.Duration(rand2.IntN(10))) + pauseWorkflow(t, backendTH, wfRegistryC, workflowKey) + time.Sleep(time.Millisecond * time.Duration(rand2.IntN(10))) + var newWorkflowID [32]byte + _, err = rand.Read((newWorkflowID)[:]) + require.NoError(t, err) + updateWorkflow(t, backendTH, wfRegistryC, workflowKey, newWorkflowID, workflow.BinaryURL+"2", workflow.ConfigURL, workflow.SecretsURL) + time.Sleep(time.Millisecond * time.Duration(rand2.IntN(10))) + deleteWorkflow(t, backendTH, wfRegistryC, workflowKey) + } + + // Confirm the expected number of events are received in the correct order + require.Eventually(t, func() bool { + events := testEventHandler.GetEvents() + numEvents := len(events) + expectedNumEvents := 5 * numberOfEventCycles + + if numEvents == expectedNumEvents { + // verify the events are the expected types in the expected order + for idx, event := range events { + switch idx % 5 { + case 0: + assert.Equal(t, syncer.WorkflowRegisteredEvent, event.GetEventType()) + case 1: + assert.Equal(t, syncer.WorkflowActivatedEvent, event.GetEventType()) + case 2: + assert.Equal(t, syncer.WorkflowPausedEvent, event.GetEventType()) + case 3: + assert.Equal(t, syncer.WorkflowUpdatedEvent, event.GetEventType()) + case 4: + assert.Equal(t, syncer.WorkflowDeletedEvent, event.GetEventType()) + } + } + return true + } + + return false + }, 50*time.Second, time.Second) +} + func Test_InitialStateSync(t *testing.T) { lggr := logger.TestLogger(t) backendTH := testutils.NewEVMBackendTH(t) @@ -126,10 +283,10 @@ func Test_InitialStateSync(t *testing.T) { servicetest.Run(t, worker) require.Eventually(t, func() bool { - return len(testEventHandler.events) == numberWorkflows + return len(testEventHandler.GetEvents()) == numberWorkflows }, 5*time.Second, time.Second) - for _, event := range testEventHandler.events { + for _, event := range testEventHandler.GetEvents() { assert.Equal(t, syncer.WorkflowRegisteredEvent, event.GetEventType()) } } @@ -157,8 +314,6 @@ func Test_SecretsWorker(t *testing.T) { fetcherFn = func(_ context.Context, _ string) ([]byte, error) { return []byte(wantContents), nil } - contractName = syncer.WorkflowRegistryContractName - forceUpdateSecretsEvent = string(syncer.ForceUpdateSecretsEvent) ) defer giveTicker.Stop() @@ -174,38 +329,6 @@ func Test_SecretsWorker(t *testing.T) { backendTH.Backend.Commit() require.NoError(t, err) - lggr.Infof("deployed workflow registry at %s\n", wfRegistryAddr.Hex()) - - // Build the ContractReader config - contractReaderCfg := evmtypes.ChainReaderConfig{ - Contracts: map[string]evmtypes.ChainContractReader{ - contractName: { - ContractPollingFilter: evmtypes.ContractPollingFilter{ - GenericEventNames: []string{forceUpdateSecretsEvent}, - }, - ContractABI: workflow_registry_wrapper.WorkflowRegistryABI, - Configs: map[string]*evmtypes.ChainReaderDefinition{ - forceUpdateSecretsEvent: { - ChainSpecificName: forceUpdateSecretsEvent, - ReadType: evmtypes.Event, - }, - syncer.GetWorkflowMetadataListByDONMethodName: { - ChainSpecificName: syncer.GetWorkflowMetadataListByDONMethodName, - }, - }, - }, - }, - } - - contractReaderCfgBytes, err := json.Marshal(contractReaderCfg) - require.NoError(t, err) - - contractReader, err := backendTH.NewContractReader(ctx, t, contractReaderCfgBytes) - require.NoError(t, err) - - err = contractReader.Bind(ctx, []types.BoundContract{{Name: contractName, Address: wfRegistryAddr.Hex()}}) - require.NoError(t, err) - // Seed the DB hash, err := crypto.Keccak256(append(backendTH.ContractsOwner.From[:], []byte(giveSecretsURL)...)) require.NoError(t, err) @@ -226,17 +349,23 @@ func Test_SecretsWorker(t *testing.T) { handler := syncer.NewEventHandler(lggr, orm, fetcherFn, nil, nil, emitter, clockwork.NewFakeClock(), workflowkey.Key{}) - worker := syncer.NewWorkflowRegistry(lggr, func(ctx context.Context, bytes []byte) (syncer.ContractReader, error) { - return contractReader, nil - }, wfRegistryAddr.Hex(), - syncer.WorkflowEventPollerConfig{ - QueryCount: 20, - }, handler, &testWorkflowRegistryContractLoader{}, &testDonNotifier{ + worker := syncer.NewWorkflowRegistry( + lggr, + func(ctx context.Context, bytes []byte) (syncer.ContractReader, error) { + return backendTH.NewContractReader(ctx, t, bytes) + }, + wfRegistryAddr.Hex(), + syncer.WorkflowEventPollerConfig{QueryCount: 20}, + handler, + &testWorkflowRegistryContractLoader{}, + &testDonNotifier{ don: capabilities.DON{ ID: donID, }, err: nil, - }, syncer.WithTicker(giveTicker.C)) + }, + syncer.WithTicker(giveTicker.C), + ) // setup contract state to allow the secrets to be updated updateAllowedDONs(t, backendTH, wfRegistryC, []uint32{donID}, true) @@ -257,6 +386,195 @@ func Test_SecretsWorker(t *testing.T) { }, 15*time.Second, time.Second) } +func Test_RegistrySyncer_WorkflowRegistered_InitiallyPaused(t *testing.T) { + var ( + ctx = coretestutils.Context(t) + lggr = logger.TestLogger(t) + emitter = custmsg.NewLabeler() + backendTH = testutils.NewEVMBackendTH(t) + db = pgtest.NewSqlxDB(t) + orm = syncer.NewWorkflowRegistryDS(db, lggr) + + giveTicker = time.NewTicker(500 * time.Millisecond) + giveBinaryURL = "https://original-url.com" + donID = uint32(1) + giveWorkflow = RegisterWorkflowCMD{ + Name: "test-wf", + DonID: donID, + Status: uint8(1), + BinaryURL: giveBinaryURL, + } + wantContents = "updated contents" + fetcherFn = func(_ context.Context, _ string) ([]byte, error) { + return []byte(base64.StdEncoding.EncodeToString([]byte(wantContents))), nil + } + ) + + defer giveTicker.Stop() + + // Deploy a test workflow_registry + wfRegistryAddr, _, wfRegistryC, err := workflow_registry_wrapper.DeployWorkflowRegistry(backendTH.ContractsOwner, backendTH.Backend.Client()) + backendTH.Backend.Commit() + require.NoError(t, err) + + from := [20]byte(backendTH.ContractsOwner.From) + id, err := workflows.GenerateWorkflowID(from[:], "test-wf", []byte(wantContents), []byte(""), "") + require.NoError(t, err) + giveWorkflow.ID = id + + er := syncer.NewEngineRegistry() + handler := syncer.NewEventHandler(lggr, orm, fetcherFn, nil, nil, + emitter, clockwork.NewFakeClock(), workflowkey.Key{}, syncer.WithEngineRegistry(er)) + + worker := syncer.NewWorkflowRegistry( + lggr, + func(ctx context.Context, bytes []byte) (syncer.ContractReader, error) { + return backendTH.NewContractReader(ctx, t, bytes) + }, + wfRegistryAddr.Hex(), + syncer.WorkflowEventPollerConfig{QueryCount: 20}, + handler, + &testWorkflowRegistryContractLoader{}, + &testDonNotifier{ + don: capabilities.DON{ + ID: donID, + }, + err: nil, + }, + syncer.WithTicker(giveTicker.C), + ) + + // setup contract state to allow the secrets to be updated + updateAllowedDONs(t, backendTH, wfRegistryC, []uint32{donID}, true) + updateAuthorizedAddress(t, backendTH, wfRegistryC, []common.Address{backendTH.ContractsOwner.From}, true) + + servicetest.Run(t, worker) + + // generate a log event + registerWorkflow(t, backendTH, wfRegistryC, giveWorkflow) + + // Require the secrets contents to eventually be updated + require.Eventually(t, func() bool { + _, err = er.Get("test-wf") + if err == nil { + return false + } + + owner := strings.ToLower(backendTH.ContractsOwner.From.Hex()[2:]) + _, err := orm.GetWorkflowSpec(ctx, owner, "test-wf") + return err == nil + }, 15*time.Second, time.Second) +} + +type mockService struct{} + +func (m *mockService) Start(context.Context) error { return nil } + +func (m *mockService) Close() error { return nil } + +func (m *mockService) HealthReport() map[string]error { return map[string]error{"svc": nil} } + +func (m *mockService) Ready() error { return nil } + +func (m *mockService) Name() string { return "svc" } + +type mockEngineFactory struct{} + +func (m *mockEngineFactory) new(ctx context.Context, wfid string, owner string, name string, config []byte, binary []byte) (services.Service, error) { + return &mockService{}, nil +} + +func Test_RegistrySyncer_WorkflowRegistered_InitiallyActivated(t *testing.T) { + var ( + ctx = coretestutils.Context(t) + lggr = logger.TestLogger(t) + emitter = custmsg.NewLabeler() + backendTH = testutils.NewEVMBackendTH(t) + db = pgtest.NewSqlxDB(t) + orm = syncer.NewWorkflowRegistryDS(db, lggr) + + giveTicker = time.NewTicker(500 * time.Millisecond) + giveBinaryURL = "https://original-url.com" + donID = uint32(1) + giveWorkflow = RegisterWorkflowCMD{ + Name: "test-wf", + DonID: donID, + Status: uint8(0), + BinaryURL: giveBinaryURL, + } + wantContents = "updated contents" + fetcherFn = func(_ context.Context, _ string) ([]byte, error) { + return []byte(base64.StdEncoding.EncodeToString([]byte(wantContents))), nil + } + ) + + defer giveTicker.Stop() + + // Deploy a test workflow_registry + wfRegistryAddr, _, wfRegistryC, err := workflow_registry_wrapper.DeployWorkflowRegistry(backendTH.ContractsOwner, backendTH.Backend.Client()) + backendTH.Backend.Commit() + require.NoError(t, err) + + from := [20]byte(backendTH.ContractsOwner.From) + id, err := workflows.GenerateWorkflowID(from[:], "test-wf", []byte(wantContents), []byte(""), "") + require.NoError(t, err) + giveWorkflow.ID = id + + mf := &mockEngineFactory{} + er := syncer.NewEngineRegistry() + handler := syncer.NewEventHandler( + lggr, + orm, + fetcherFn, + nil, + nil, + emitter, + clockwork.NewFakeClock(), + workflowkey.Key{}, + syncer.WithEngineRegistry(er), + syncer.WithEngineFactoryFn(mf.new), + ) + + worker := syncer.NewWorkflowRegistry( + lggr, + func(ctx context.Context, bytes []byte) (syncer.ContractReader, error) { + return backendTH.NewContractReader(ctx, t, bytes) + }, + wfRegistryAddr.Hex(), + syncer.WorkflowEventPollerConfig{QueryCount: 20}, + handler, + &testWorkflowRegistryContractLoader{}, + &testDonNotifier{ + don: capabilities.DON{ + ID: donID, + }, + err: nil, + }, + syncer.WithTicker(giveTicker.C), + ) + + // setup contract state to allow the secrets to be updated + updateAllowedDONs(t, backendTH, wfRegistryC, []uint32{donID}, true) + updateAuthorizedAddress(t, backendTH, wfRegistryC, []common.Address{backendTH.ContractsOwner.From}, true) + + servicetest.Run(t, worker) + + // generate a log event + registerWorkflow(t, backendTH, wfRegistryC, giveWorkflow) + + // Require the secrets contents to eventually be updated + require.Eventually(t, func() bool { + _, err := er.Get("test-wf") + if err != nil { + return err != nil + } + + owner := strings.ToLower(backendTH.ContractsOwner.From.Hex()[2:]) + _, err = orm.GetWorkflowSpec(ctx, owner, "test-wf") + return err == nil + }, 15*time.Second, time.Second) +} + func updateAuthorizedAddress( t *testing.T, th *testutils.EVMBackendTH, @@ -334,3 +652,59 @@ func requestForceUpdateSecrets( th.Backend.Commit() th.Backend.Commit() } + +func activateWorkflow( + t *testing.T, + th *testutils.EVMBackendTH, + wfRegC *workflow_registry_wrapper.WorkflowRegistry, + workflowKey [32]byte, +) { + t.Helper() + _, err := wfRegC.ActivateWorkflow(th.ContractsOwner, workflowKey) + require.NoError(t, err, "failed to activate workflow") + th.Backend.Commit() + th.Backend.Commit() + th.Backend.Commit() +} + +func pauseWorkflow( + t *testing.T, + th *testutils.EVMBackendTH, + wfRegC *workflow_registry_wrapper.WorkflowRegistry, + workflowKey [32]byte, +) { + t.Helper() + _, err := wfRegC.PauseWorkflow(th.ContractsOwner, workflowKey) + require.NoError(t, err, "failed to pause workflow") + th.Backend.Commit() + th.Backend.Commit() + th.Backend.Commit() +} + +func deleteWorkflow( + t *testing.T, + th *testutils.EVMBackendTH, + wfRegC *workflow_registry_wrapper.WorkflowRegistry, + workflowKey [32]byte, +) { + t.Helper() + _, err := wfRegC.DeleteWorkflow(th.ContractsOwner, workflowKey) + require.NoError(t, err, "failed to delete workflow") + th.Backend.Commit() + th.Backend.Commit() + th.Backend.Commit() +} + +func updateWorkflow( + t *testing.T, + th *testutils.EVMBackendTH, + wfRegC *workflow_registry_wrapper.WorkflowRegistry, + workflowKey [32]byte, newWorkflowID [32]byte, binaryURL string, configURL string, secretsURL string, +) { + t.Helper() + _, err := wfRegC.UpdateWorkflow(th.ContractsOwner, workflowKey, newWorkflowID, binaryURL, configURL, secretsURL) + require.NoError(t, err, "failed to update workflow") + th.Backend.Commit() + th.Backend.Commit() + th.Backend.Commit() +} diff --git a/core/services/relay/evm/chain_reader.go b/core/services/relay/evm/chain_reader.go index 4de739a44b4..99be89eae17 100644 --- a/core/services/relay/evm/chain_reader.go +++ b/core/services/relay/evm/chain_reader.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "iter" "maps" "slices" "strings" @@ -298,6 +299,41 @@ func (cr *chainReader) QueryKey( return sequenceOfValues, nil } +func (cr *chainReader) QueryKeys(ctx context.Context, filters []commontypes.ContractKeyFilter, + limitAndSort query.LimitAndSort) (iter.Seq2[string, commontypes.Sequence], error) { + eventQueries := make([]read.EventQuery, 0, len(filters)) + for _, filter := range filters { + binding, address, err := cr.bindings.GetReader(filter.Contract.ReadIdentifier(filter.KeyFilter.Key)) + if err != nil { + return nil, err + } + + sequenceDataType := filter.SequenceDataType + _, isValuePtr := filter.SequenceDataType.(*values.Value) + if isValuePtr { + sequenceDataType, err = cr.CreateContractType(filter.Contract.ReadIdentifier(filter.Key), false) + if err != nil { + return nil, err + } + } + + eventBinding, ok := binding.(*read.EventBinding) + if !ok { + return nil, fmt.Errorf("query key %s is not an event", filter.KeyFilter.Key) + } + + eventQueries = append(eventQueries, read.EventQuery{ + Filter: filter.KeyFilter, + SequenceDataType: sequenceDataType, + IsValuePtr: isValuePtr, + EventBinding: eventBinding, + Address: common.HexToAddress(address), + }) + } + + return read.MultiEventTypeQuery(ctx, cr.lp, eventQueries, limitAndSort) +} + func (cr *chainReader) CreateContractType(readIdentifier string, forEncoding bool) (any, error) { return cr.codec.CreateType(cr.bindings.ReadTypeIdentifier(readIdentifier, forEncoding), forEncoding) } diff --git a/core/services/relay/evm/evmtesting/bindings_test_adapter.go b/core/services/relay/evm/evmtesting/bindings_test_adapter.go index 6c391aa0a7f..408acb0d5a8 100644 --- a/core/services/relay/evm/evmtesting/bindings_test_adapter.go +++ b/core/services/relay/evm/evmtesting/bindings_test_adapter.go @@ -36,6 +36,8 @@ func WrapContractReaderTesterWithBindings(t *testing.T, wrapped *EVMChainCompone interfacetests.ContractReaderBatchGetLatestValueSetsErrorsProperly, interfacetests.ContractReaderBatchGetLatestValueNoArgumentsWithSliceReturn, interfacetests.ContractReaderBatchGetLatestValueWithModifiersOwnMapstructureOverride, interfacetests.ContractReaderQueryKeyNotFound, interfacetests.ContractReaderQueryKeyReturnsData, interfacetests.ContractReaderQueryKeyReturnsDataAsValuesDotValue, interfacetests.ContractReaderQueryKeyReturnsDataAsValuesDotValue, interfacetests.ContractReaderQueryKeyCanFilterWithValueComparator, interfacetests.ContractReaderQueryKeyCanLimitResultsWithCursor, + interfacetests.ContractReaderQueryKeysNotFound, interfacetests.ContractReaderQueryKeysReturnsData, interfacetests.ContractReaderQueryKeysReturnsDataTwoEventTypes, interfacetests.ContractReaderQueryKeysReturnsDataAsValuesDotValue, + interfacetests.ContractReaderQueryKeysCanFilterWithValueComparator, interfacetests.ContractReaderQueryKeysCanLimitResultsWithCursor, ContractReaderQueryKeyFilterOnDataWordsWithValueComparator, ContractReaderQueryKeyOnDataWordsWithValueComparatorOnNestedField, ContractReaderQueryKeyFilterOnDataWordsWithValueComparatorOnDynamicField, ContractReaderQueryKeyFilteringOnDataWordsUsingValueComparatorsOnFieldsWithManualIndex, // TODO BCFR-1073 - Fix flaky tests @@ -71,6 +73,7 @@ func newBindingsMapping() bindingsMapping { interfacetests.MethodSettingStruct: "AddTestStruct", interfacetests.MethodSettingUint64: "SetAlterablePrimitiveValue", interfacetests.MethodTriggeringEvent: "TriggerEvent", + interfacetests.MethodTriggeringEventWithDynamicTopic: "TriggerEventWithDynamicTopic", } methodNameMappingByContract[interfacetests.AnySecondContractName] = map[string]string{ interfacetests.MethodReturningUint64: "GetDifferentPrimitiveValue", @@ -249,6 +252,10 @@ func (b bindingChainWriterProxy) SubmitTransaction(ctx context.Context, contract bindingsInput := bindings.TriggerEventInput{} _ = convertStruct(args, &bindingsInput) return chainReaderTesters.TriggerEvent(ctx, bindingsInput, transactionID, toAddress, meta) + case interfacetests.MethodTriggeringEventWithDynamicTopic: + bindingsInput := bindings.TriggerEventWithDynamicTopicInput{} + _ = convertStruct(args, &bindingsInput) + return chainReaderTesters.TriggerEventWithDynamicTopic(ctx, bindingsInput, transactionID, toAddress, meta) default: return errors.New("No logic implemented for method: " + method) } diff --git a/core/services/relay/evm/read/errors.go b/core/services/relay/evm/read/errors.go index 422b7ded1d8..e767da495e7 100644 --- a/core/services/relay/evm/read/errors.go +++ b/core/services/relay/evm/read/errors.go @@ -75,6 +75,58 @@ func (e Error) Unwrap() error { return e.Err } +type MultiCallError struct { + Err error + Type readType + Detail *callsReadDetail + Result *string +} + +type callsReadDetail struct { + Calls []Call + Block string +} + +func newErrorFromCalls(err error, calls []Call, block string, tp readType) MultiCallError { + return MultiCallError{ + Err: err, + Type: tp, + Detail: &callsReadDetail{ + Calls: calls, + Block: block, + }, + } +} + +func (e MultiCallError) Error() string { + var builder strings.Builder + + builder.WriteString("[read error]") + builder.WriteString(fmt.Sprintf(" err: %s;", e.Err.Error())) + builder.WriteString(fmt.Sprintf(" type: %s;", e.Type)) + + if e.Detail != nil { + builder.WriteString(fmt.Sprintf(" block: %s;", e.Detail.Block)) + for _, call := range e.Detail.Calls { + builder.WriteString(fmt.Sprintf(" address: %s;", call.ContractAddress.Hex())) + builder.WriteString(fmt.Sprintf(" contract-name: %s;", call.ContractName)) + builder.WriteString(fmt.Sprintf(" read-name: %s;", call.ReadName)) + builder.WriteString(fmt.Sprintf(" params: %+v;", call.Params)) + builder.WriteString(fmt.Sprintf(" expected return type: %s;", reflect.TypeOf(call.ReturnVal))) + } + + if e.Result != nil { + builder.WriteString(fmt.Sprintf("encoded result: %s;", *e.Result)) + } + } + + return builder.String() +} + +func (e MultiCallError) Unwrap() error { + return e.Err +} + type ConfigError struct { Msg string } diff --git a/core/services/relay/evm/read/multieventtype.go b/core/services/relay/evm/read/multieventtype.go new file mode 100644 index 00000000000..1b561912d18 --- /dev/null +++ b/core/services/relay/evm/read/multieventtype.go @@ -0,0 +1,216 @@ +package read + +import ( + "context" + "errors" + "fmt" + "iter" + "reflect" + "sort" + "strconv" + "strings" + + "github.com/ethereum/go-ethereum/common" + + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/query" + "github.com/smartcontractkit/chainlink-common/pkg/values" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" +) + +type EventQuery struct { + Filter query.KeyFilter + EventBinding *EventBinding + SequenceDataType any + IsValuePtr bool + Address common.Address +} + +func MultiEventTypeQuery(ctx context.Context, lp logpoller.LogPoller, eventQueries []EventQuery, limitAndSort query.LimitAndSort) (iter.Seq2[string, commontypes.Sequence], error) { + seqIter, err := multiEventTypeQueryWithoutErrorWrapping(ctx, lp, eventQueries, limitAndSort) + if err != nil { + if len(eventQueries) > 0 { + var calls []Call + for _, eq := range eventQueries { + calls = append(calls, Call{ + ContractAddress: eq.Address, + ContractName: eq.EventBinding.contractName, + ReadName: eq.EventBinding.eventName, + ReturnVal: eq.SequenceDataType, + }) + } + + err = newErrorFromCalls(err, calls, "", eventReadType) + } else { + err = fmt.Errorf("no event queries provided: %w", err) + } + } + + return seqIter, err +} + +func multiEventTypeQueryWithoutErrorWrapping(ctx context.Context, lp logpoller.LogPoller, eventQueries []EventQuery, limitAndSort query.LimitAndSort) (iter.Seq2[string, commontypes.Sequence], error) { + if err := validateEventQueries(eventQueries); err != nil { + return nil, fmt.Errorf("error validating event queries: %w", err) + } + + for _, eq := range eventQueries { + if err := eq.EventBinding.validateBound(eq.Address); err != nil { + return nil, err + } + } + + allFilterExpressions := make([]query.Expression, 0, len(eventQueries)) + for _, eq := range eventQueries { + var expressions []query.Expression + + defaultExpressions := []query.Expression{ + logpoller.NewAddressFilter(eq.Address), + logpoller.NewEventSigFilter(eq.EventBinding.hash), + } + expressions = append(expressions, defaultExpressions...) + + remapped, remapErr := eq.EventBinding.remap(eq.Filter) + if remapErr != nil { + return nil, fmt.Errorf("error remapping filter: %w", remapErr) + } + expressions = append(expressions, remapped.Expressions...) + + filterExpression := query.And(expressions...) + + allFilterExpressions = append(allFilterExpressions, filterExpression) + } + + eventQuery := query.Or(allFilterExpressions...) + + queryName := createQueryName(eventQueries) + + logs, err := lp.FilteredLogs(ctx, []query.Expression{eventQuery}, limitAndSort, queryName) + if err != nil { + return nil, wrapInternalErr(err) + } + + seqIter, err := decodeMultiEventTypeLogsIntoSequences(ctx, logs, eventQueries) + if err != nil { + return nil, wrapInternalErr(err) + } + + return seqIter, nil +} + +func createQueryName(eventQueries []EventQuery) string { + queryName := "" + contractToEvents := map[string][]string{} + for _, eq := range eventQueries { + contractName := eq.EventBinding.contractName + "-" + eq.Address.String() + + if _, exists := contractToEvents[contractName]; !exists { + contractToEvents[contractName] = []string{} + } + contractToEvents[contractName] = append(contractToEvents[contractName], eq.EventBinding.eventName) + } + + contractNames := make([]string, 0, len(contractToEvents)) + for contractName := range contractToEvents { + contractNames = append(contractNames, contractName) + } + + sort.Strings(contractNames) + + for _, contractName := range contractNames { + queryName += contractName + "-" + for _, event := range contractToEvents[contractName] { + queryName += event + "-" + } + } + + queryName = strings.TrimSuffix(queryName, "-") + return queryName +} + +func validateEventQueries(eventQueries []EventQuery) error { + duplicateCheck := map[common.Hash]EventQuery{} + for _, eq := range eventQueries { + if eq.EventBinding == nil { + return errors.New("event binding is nil") + } + + if eq.SequenceDataType == nil { + return errors.New("sequence data type is nil") + } + + // TODO support queries with the same event signature but different filters + if _, exists := duplicateCheck[eq.EventBinding.hash]; exists { + return fmt.Errorf("duplicate event query for event signature %s, event name %s", eq.EventBinding.hash, eq.EventBinding.eventName) + } + duplicateCheck[eq.EventBinding.hash] = eq + } + return nil +} + +func decodeMultiEventTypeLogsIntoSequences(ctx context.Context, logs []logpoller.Log, eventQueries []EventQuery) (iter.Seq2[string, commontypes.Sequence], error) { + type sequenceWithKey struct { + Key string + Sequence commontypes.Sequence + } + sequenceWithKeys := make([]sequenceWithKey, 0, len(logs)) + eventSigToEventQuery := map[common.Hash]EventQuery{} + for _, eq := range eventQueries { + eventSigToEventQuery[eq.EventBinding.hash] = eq + } + + for _, logEntry := range logs { + eventSignatureHash := logEntry.EventSig + + eq, exists := eventSigToEventQuery[eventSignatureHash] + if !exists { + return nil, fmt.Errorf("no event query found for log with event signature %s", eventSignatureHash) + } + + seqWithKey := sequenceWithKey{ + Key: eq.Filter.Key, + Sequence: commontypes.Sequence{ + Cursor: logpoller.FormatContractReaderCursor(logEntry), + Head: commontypes.Head{ + Height: strconv.FormatInt(logEntry.BlockNumber, 10), + Hash: logEntry.BlockHash.Bytes(), + Timestamp: uint64(logEntry.BlockTimestamp.Unix()), //nolint:gosec // G115 false positive + }, + }, + } + + var typeVal reflect.Value + + typeInto := reflect.TypeOf(eq.SequenceDataType) + if typeInto.Kind() == reflect.Pointer { + typeVal = reflect.New(typeInto.Elem()) + } else { + typeVal = reflect.Indirect(reflect.New(typeInto)) + } + + // create a new value of the same type as 'into' for the data to be extracted to + seqWithKey.Sequence.Data = typeVal.Interface() + + if err := eq.EventBinding.decodeLog(ctx, &logEntry, seqWithKey.Sequence.Data); err != nil { + return nil, err + } + + if eq.IsValuePtr { + wrappedValue, err := values.Wrap(seqWithKey.Sequence.Data) + if err != nil { + return nil, err + } + seqWithKey.Sequence.Data = &wrappedValue + } + + sequenceWithKeys = append(sequenceWithKeys, seqWithKey) + } + + return func(yield func(string, commontypes.Sequence) bool) { + for _, s := range sequenceWithKeys { + if !yield(s.Key, s.Sequence) { + return + } + } + }, nil +} diff --git a/core/services/relay/evm/read/multieventtype_test.go b/core/services/relay/evm/read/multieventtype_test.go new file mode 100644 index 00000000000..8fb39ecc526 --- /dev/null +++ b/core/services/relay/evm/read/multieventtype_test.go @@ -0,0 +1,119 @@ +package read + +import ( + "github.com/ethereum/go-ethereum/common" + + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink-common/pkg/types/query" +) + +func TestCreateQueryName(t *testing.T) { + eventQueries := []EventQuery{ + { + Filter: query.KeyFilter{Key: "key1"}, + EventBinding: &EventBinding{ + contractName: "ContractA", + eventName: "EventA", + hash: common.HexToHash("0x1"), + }, + SequenceDataType: "dataType1", + Address: common.HexToAddress("0x123"), + }, + { + Filter: query.KeyFilter{Key: "key2"}, + EventBinding: &EventBinding{ + contractName: "ContractB", + eventName: "EventB", + hash: common.HexToHash("0x2"), + }, + SequenceDataType: "dataType2", + Address: common.HexToAddress("0x456"), + }, + { + Filter: query.KeyFilter{Key: "key1"}, + EventBinding: &EventBinding{ + contractName: "ContractA", + eventName: "EventA1", + hash: common.HexToHash("0x1"), + }, + SequenceDataType: "dataType1", + Address: common.HexToAddress("0x123"), + }, + } + + expectedQueryName := "ContractA-0x0000000000000000000000000000000000000123-EventA-EventA1-ContractB-0x0000000000000000000000000000000000000456-EventB" + queryName := createQueryName(eventQueries) + + assert.Equal(t, expectedQueryName, queryName) +} + +func TestValidateEventQueries(t *testing.T) { + tests := []struct { + name string + eventQueries []EventQuery + expectedError string + }{ + { + name: "valid event queries", + eventQueries: []EventQuery{ + { + EventBinding: &EventBinding{hash: common.HexToHash("0x1")}, + SequenceDataType: "dataType1", + }, + { + EventBinding: &EventBinding{hash: common.HexToHash("0x2")}, + SequenceDataType: "dataType2", + }, + }, + expectedError: "", + }, + { + name: "nil event binding", + eventQueries: []EventQuery{ + { + EventBinding: nil, + SequenceDataType: "dataType1", + }, + }, + expectedError: "event binding is nil", + }, + { + name: "nil sequence data type", + eventQueries: []EventQuery{ + { + EventBinding: &EventBinding{hash: common.HexToHash("0x1")}, + SequenceDataType: nil, + }, + }, + expectedError: "sequence data type is nil", + }, + { + name: "duplicate event query", + eventQueries: []EventQuery{ + { + EventBinding: &EventBinding{hash: common.HexToHash("0x1")}, + SequenceDataType: "dataType1", + }, + { + EventBinding: &EventBinding{hash: common.HexToHash("0x1")}, + SequenceDataType: "dataType2", + }, + }, + expectedError: "duplicate event query for event signature 0x0000000000000000000000000000000000000000000000000000000000000001, event name ", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := validateEventQueries(tt.eventQueries) + if tt.expectedError == "" { + assert.NoError(t, err) + } else { + assert.EqualError(t, err, tt.expectedError) + } + }) + } +} diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go index 11d2bdc3480..943802d1962 100644 --- a/core/services/workflows/engine.go +++ b/core/services/workflows/engine.go @@ -1179,6 +1179,14 @@ func (e *Engine) Close() error { }) } +func (e *Engine) HealthReport() map[string]error { + return map[string]error{e.Name(): nil} +} + +func (e *Engine) Name() string { + return e.logger.Name() +} + type Config struct { Workflow sdk.WorkflowSpec WorkflowID string diff --git a/core/services/workflows/syncer/contract_reader_mock.go b/core/services/workflows/syncer/contract_reader_mock.go deleted file mode 100644 index 391ba5eacdb..00000000000 --- a/core/services/workflows/syncer/contract_reader_mock.go +++ /dev/null @@ -1,211 +0,0 @@ -// Code generated by mockery v2.46.3. DO NOT EDIT. - -package syncer - -import ( - context "context" - - query "github.com/smartcontractkit/chainlink-common/pkg/types/query" - primitives "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" - mock "github.com/stretchr/testify/mock" - - types "github.com/smartcontractkit/chainlink-common/pkg/types" -) - -// MockContractReader is an autogenerated mock type for the ContractReader type -type MockContractReader struct { - mock.Mock -} - -type MockContractReader_Expecter struct { - mock *mock.Mock -} - -func (_m *MockContractReader) EXPECT() *MockContractReader_Expecter { - return &MockContractReader_Expecter{mock: &_m.Mock} -} - -// Bind provides a mock function with given fields: _a0, _a1 -func (_m *MockContractReader) Bind(_a0 context.Context, _a1 []types.BoundContract) error { - ret := _m.Called(_a0, _a1) - - if len(ret) == 0 { - panic("no return value specified for Bind") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, []types.BoundContract) error); ok { - r0 = rf(_a0, _a1) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockContractReader_Bind_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Bind' -type MockContractReader_Bind_Call struct { - *mock.Call -} - -// Bind is a helper method to define mock.On call -// - _a0 context.Context -// - _a1 []types.BoundContract -func (_e *MockContractReader_Expecter) Bind(_a0 interface{}, _a1 interface{}) *MockContractReader_Bind_Call { - return &MockContractReader_Bind_Call{Call: _e.mock.On("Bind", _a0, _a1)} -} - -func (_c *MockContractReader_Bind_Call) Run(run func(_a0 context.Context, _a1 []types.BoundContract)) *MockContractReader_Bind_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].([]types.BoundContract)) - }) - return _c -} - -func (_c *MockContractReader_Bind_Call) Return(_a0 error) *MockContractReader_Bind_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockContractReader_Bind_Call) RunAndReturn(run func(context.Context, []types.BoundContract) error) *MockContractReader_Bind_Call { - _c.Call.Return(run) - return _c -} - -// GetLatestValueWithHeadData provides a mock function with given fields: ctx, readName, confidenceLevel, params, returnVal -func (_m *MockContractReader) GetLatestValueWithHeadData(ctx context.Context, readName string, confidenceLevel primitives.ConfidenceLevel, params any, returnVal any) (*types.Head, error) { - ret := _m.Called(ctx, readName, confidenceLevel, params, returnVal) - - if len(ret) == 0 { - panic("no return value specified for GetLatestValueWithHeadData") - } - - var r0 *types.Head - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string, primitives.ConfidenceLevel, any, any) (*types.Head, error)); ok { - return rf(ctx, readName, confidenceLevel, params, returnVal) - } - if rf, ok := ret.Get(0).(func(context.Context, string, primitives.ConfidenceLevel, any, any) *types.Head); ok { - r0 = rf(ctx, readName, confidenceLevel, params, returnVal) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.Head) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, string, primitives.ConfidenceLevel, any, any) error); ok { - r1 = rf(ctx, readName, confidenceLevel, params, returnVal) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockContractReader_GetLatestValueWithHeadData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLatestValueWithHeadData' -type MockContractReader_GetLatestValueWithHeadData_Call struct { - *mock.Call -} - -// GetLatestValueWithHeadData is a helper method to define mock.On call -// - ctx context.Context -// - readName string -// - confidenceLevel primitives.ConfidenceLevel -// - params any -// - returnVal any -func (_e *MockContractReader_Expecter) GetLatestValueWithHeadData(ctx interface{}, readName interface{}, confidenceLevel interface{}, params interface{}, returnVal interface{}) *MockContractReader_GetLatestValueWithHeadData_Call { - return &MockContractReader_GetLatestValueWithHeadData_Call{Call: _e.mock.On("GetLatestValueWithHeadData", ctx, readName, confidenceLevel, params, returnVal)} -} - -func (_c *MockContractReader_GetLatestValueWithHeadData_Call) Run(run func(ctx context.Context, readName string, confidenceLevel primitives.ConfidenceLevel, params any, returnVal any)) *MockContractReader_GetLatestValueWithHeadData_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(primitives.ConfidenceLevel), args[3].(any), args[4].(any)) - }) - return _c -} - -func (_c *MockContractReader_GetLatestValueWithHeadData_Call) Return(head *types.Head, err error) *MockContractReader_GetLatestValueWithHeadData_Call { - _c.Call.Return(head, err) - return _c -} - -func (_c *MockContractReader_GetLatestValueWithHeadData_Call) RunAndReturn(run func(context.Context, string, primitives.ConfidenceLevel, any, any) (*types.Head, error)) *MockContractReader_GetLatestValueWithHeadData_Call { - _c.Call.Return(run) - return _c -} - -// QueryKey provides a mock function with given fields: _a0, _a1, _a2, _a3, _a4 -func (_m *MockContractReader) QueryKey(_a0 context.Context, _a1 types.BoundContract, _a2 query.KeyFilter, _a3 query.LimitAndSort, _a4 any) ([]types.Sequence, error) { - ret := _m.Called(_a0, _a1, _a2, _a3, _a4) - - if len(ret) == 0 { - panic("no return value specified for QueryKey") - } - - var r0 []types.Sequence - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, types.BoundContract, query.KeyFilter, query.LimitAndSort, any) ([]types.Sequence, error)); ok { - return rf(_a0, _a1, _a2, _a3, _a4) - } - if rf, ok := ret.Get(0).(func(context.Context, types.BoundContract, query.KeyFilter, query.LimitAndSort, any) []types.Sequence); ok { - r0 = rf(_a0, _a1, _a2, _a3, _a4) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]types.Sequence) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, types.BoundContract, query.KeyFilter, query.LimitAndSort, any) error); ok { - r1 = rf(_a0, _a1, _a2, _a3, _a4) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockContractReader_QueryKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'QueryKey' -type MockContractReader_QueryKey_Call struct { - *mock.Call -} - -// QueryKey is a helper method to define mock.On call -// - _a0 context.Context -// - _a1 types.BoundContract -// - _a2 query.KeyFilter -// - _a3 query.LimitAndSort -// - _a4 any -func (_e *MockContractReader_Expecter) QueryKey(_a0 interface{}, _a1 interface{}, _a2 interface{}, _a3 interface{}, _a4 interface{}) *MockContractReader_QueryKey_Call { - return &MockContractReader_QueryKey_Call{Call: _e.mock.On("QueryKey", _a0, _a1, _a2, _a3, _a4)} -} - -func (_c *MockContractReader_QueryKey_Call) Run(run func(_a0 context.Context, _a1 types.BoundContract, _a2 query.KeyFilter, _a3 query.LimitAndSort, _a4 any)) *MockContractReader_QueryKey_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(types.BoundContract), args[2].(query.KeyFilter), args[3].(query.LimitAndSort), args[4].(any)) - }) - return _c -} - -func (_c *MockContractReader_QueryKey_Call) Return(_a0 []types.Sequence, _a1 error) *MockContractReader_QueryKey_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockContractReader_QueryKey_Call) RunAndReturn(run func(context.Context, types.BoundContract, query.KeyFilter, query.LimitAndSort, any) ([]types.Sequence, error)) *MockContractReader_QueryKey_Call { - _c.Call.Return(run) - return _c -} - -// NewMockContractReader creates a new instance of MockContractReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockContractReader(t interface { - mock.TestingT - Cleanup(func()) -}) *MockContractReader { - mock := &MockContractReader{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/core/services/workflows/syncer/engine_registry.go b/core/services/workflows/syncer/engine_registry.go index 809381c191c..fa3771c5a0f 100644 --- a/core/services/workflows/syncer/engine_registry.go +++ b/core/services/workflows/syncer/engine_registry.go @@ -4,29 +4,29 @@ import ( "errors" "sync" - "github.com/smartcontractkit/chainlink/v2/core/services/workflows" + "github.com/smartcontractkit/chainlink-common/pkg/services" ) -type engineRegistry struct { - engines map[string]*workflows.Engine +type EngineRegistry struct { + engines map[string]services.Service mu sync.RWMutex } -func newEngineRegistry() *engineRegistry { - return &engineRegistry{ - engines: make(map[string]*workflows.Engine), +func NewEngineRegistry() *EngineRegistry { + return &EngineRegistry{ + engines: make(map[string]services.Service), } } // Add adds an engine to the registry. -func (r *engineRegistry) Add(id string, engine *workflows.Engine) { +func (r *EngineRegistry) Add(id string, engine services.Service) { r.mu.Lock() defer r.mu.Unlock() r.engines[id] = engine } // Get retrieves an engine from the registry. -func (r *engineRegistry) Get(id string) (*workflows.Engine, error) { +func (r *EngineRegistry) Get(id string) (services.Service, error) { r.mu.RLock() defer r.mu.RUnlock() engine, found := r.engines[id] @@ -37,7 +37,7 @@ func (r *engineRegistry) Get(id string) (*workflows.Engine, error) { } // IsRunning is true if the engine exists and is ready. -func (r *engineRegistry) IsRunning(id string) bool { +func (r *EngineRegistry) IsRunning(id string) bool { r.mu.RLock() defer r.mu.RUnlock() engine, found := r.engines[id] @@ -49,7 +49,7 @@ func (r *engineRegistry) IsRunning(id string) bool { } // Pop removes an engine from the registry and returns the engine if found. -func (r *engineRegistry) Pop(id string) (*workflows.Engine, error) { +func (r *EngineRegistry) Pop(id string) (services.Service, error) { r.mu.Lock() defer r.mu.Unlock() engine, ok := r.engines[id] @@ -61,7 +61,7 @@ func (r *engineRegistry) Pop(id string) (*workflows.Engine, error) { } // Close closes all engines in the registry. -func (r *engineRegistry) Close() error { +func (r *EngineRegistry) Close() error { r.mu.Lock() defer r.mu.Unlock() var err error diff --git a/core/services/workflows/syncer/handler.go b/core/services/workflows/syncer/handler.go index 46dcd21ed90..4ef7f952249 100644 --- a/core/services/workflows/syncer/handler.go +++ b/core/services/workflows/syncer/handler.go @@ -3,6 +3,7 @@ package syncer import ( "bytes" "context" + "encoding/base64" "encoding/hex" "encoding/json" "errors" @@ -13,6 +14,7 @@ import ( "github.com/jonboulle/clockwork" "github.com/smartcontractkit/chainlink-common/pkg/custmsg" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types/core" pkgworkflows "github.com/smartcontractkit/chainlink-common/pkg/workflows" "github.com/smartcontractkit/chainlink-common/pkg/workflows/secrets" @@ -59,14 +61,14 @@ type WorkflowRegistryForceUpdateSecretsRequestedV1 struct { } type WorkflowRegistryWorkflowRegisteredV1 struct { - WorkflowID [32]byte - Owner []byte - DonID uint32 - Status uint8 - WorkflowName string - BinaryURL string - ConfigURL string - SecretsURL string + WorkflowID [32]byte + WorkflowOwner []byte + DonID uint32 + Status uint8 + WorkflowName string + BinaryURL string + ConfigURL string + SecretsURL string } type WorkflowRegistryWorkflowUpdatedV1 struct { @@ -125,6 +127,8 @@ func newLastFetchedAtMap() *lastFetchedAtMap { } } +type engineFactoryFn func(ctx context.Context, wfid string, owner string, name string, config []byte, binary []byte) (services.Service, error) + // eventHandler is a handler for WorkflowRegistryEvent events. Each event type has a corresponding // method that handles the event. type eventHandler struct { @@ -133,12 +137,13 @@ type eventHandler struct { fetcher FetcherFunc workflowStore store.Store capRegistry core.CapabilitiesRegistry - engineRegistry *engineRegistry + engineRegistry *EngineRegistry emitter custmsg.MessageEmitter lastFetchedAtMap *lastFetchedAtMap clock clockwork.Clock secretsFreshnessDuration time.Duration encryptionKey workflowkey.Key + engineFactory engineFactoryFn } type Event interface { @@ -148,6 +153,18 @@ type Event interface { var defaultSecretsFreshnessDuration = 24 * time.Hour +func WithEngineRegistry(er *EngineRegistry) func(*eventHandler) { + return func(e *eventHandler) { + e.engineRegistry = er + } +} + +func WithEngineFactoryFn(efn engineFactoryFn) func(*eventHandler) { + return func(e *eventHandler) { + e.engineFactory = efn + } +} + // NewEventHandler returns a new eventHandler instance. func NewEventHandler( lggr logger.Logger, @@ -158,20 +175,26 @@ func NewEventHandler( emitter custmsg.MessageEmitter, clock clockwork.Clock, encryptionKey workflowkey.Key, + opts ...func(*eventHandler), ) *eventHandler { - return &eventHandler{ + eh := &eventHandler{ lggr: lggr, orm: orm, fetcher: gateway, workflowStore: workflowStore, capRegistry: capRegistry, - engineRegistry: newEngineRegistry(), + engineRegistry: NewEngineRegistry(), emitter: emitter, lastFetchedAtMap: newLastFetchedAtMap(), clock: clock, secretsFreshnessDuration: defaultSecretsFreshnessDuration, encryptionKey: encryptionKey, } + eh.engineFactory = eh.engineFactoryFn + for _, o := range opts { + o(eh) + } + return eh } func (h *eventHandler) refreshSecrets(ctx context.Context, workflowOwner, workflowName, workflowID, secretsURLHash string) (string, error) { @@ -276,7 +299,7 @@ func (h *eventHandler) Handle(ctx context.Context, event Event) error { cma := h.emitter.With( platform.KeyWorkflowID, wfID, platform.KeyWorkflowName, payload.WorkflowName, - platform.KeyWorkflowOwner, hex.EncodeToString(payload.Owner), + platform.KeyWorkflowOwner, hex.EncodeToString(payload.WorkflowOwner), ) if err := h.workflowRegisteredEvent(ctx, payload); err != nil { @@ -383,18 +406,29 @@ func (h *eventHandler) workflowRegisteredEvent( return fmt.Errorf("failed to fetch binary from %s : %w", payload.BinaryURL, err) } - config, err := h.fetcher(ctx, payload.ConfigURL) + decodedBinary, err := base64.StdEncoding.DecodeString(string(binary)) if err != nil { - return fmt.Errorf("failed to fetch config from %s : %w", payload.ConfigURL, err) + return fmt.Errorf("failed to decode binary: %w", err) } - secrets, err := h.fetcher(ctx, payload.SecretsURL) - if err != nil { - return fmt.Errorf("failed to fetch secrets from %s : %w", payload.SecretsURL, err) + var config []byte + if payload.ConfigURL != "" { + config, err = h.fetcher(ctx, payload.ConfigURL) + if err != nil { + return fmt.Errorf("failed to fetch config from %s : %w", payload.ConfigURL, err) + } + } + + var secrets []byte + if payload.SecretsURL != "" { + secrets, err = h.fetcher(ctx, payload.SecretsURL) + if err != nil { + return fmt.Errorf("failed to fetch secrets from %s : %w", payload.SecretsURL, err) + } } // Calculate the hash of the binary and config files - hash, err := pkgworkflows.GenerateWorkflowID(payload.Owner, binary, config, payload.SecretsURL) + hash, err := pkgworkflows.GenerateWorkflowID(payload.WorkflowOwner, payload.WorkflowName, decodedBinary, config, payload.SecretsURL) if err != nil { return fmt.Errorf("failed to generate workflow id: %w", err) } @@ -404,8 +438,13 @@ func (h *eventHandler) workflowRegisteredEvent( return fmt.Errorf("workflowID mismatch: %x != %x", hash, payload.WorkflowID) } + // Ensure that there is no running workflow engine for the given workflow ID. + if h.engineRegistry.IsRunning(hex.EncodeToString(payload.WorkflowID[:])) { + return fmt.Errorf("workflow is already running, so not starting it : %s", hex.EncodeToString(payload.WorkflowID[:])) + } + // Save the workflow secrets - urlHash, err := h.orm.GetSecretsURLHash(payload.Owner, []byte(payload.SecretsURL)) + urlHash, err := h.orm.GetSecretsURLHash(payload.WorkflowOwner, []byte(payload.SecretsURL)) if err != nil { return fmt.Errorf("failed to get secrets URL hash: %w", err) } @@ -417,12 +456,13 @@ func (h *eventHandler) workflowRegisteredEvent( } wfID := hex.EncodeToString(payload.WorkflowID[:]) + owner := hex.EncodeToString(payload.WorkflowOwner) entry := &job.WorkflowSpec{ - Workflow: hex.EncodeToString(binary), + Workflow: hex.EncodeToString(decodedBinary), Config: string(config), WorkflowID: wfID, Status: status, - WorkflowOwner: hex.EncodeToString(payload.Owner), + WorkflowOwner: owner, WorkflowName: payload.WorkflowName, SpecType: job.WASMFile, BinaryURL: payload.BinaryURL, @@ -438,36 +478,47 @@ func (h *eventHandler) workflowRegisteredEvent( } // If status == active, start a new WorkflowEngine instance, and add it to local engine registry + engine, err := h.engineFactory( + ctx, + wfID, + owner, + payload.WorkflowName, + config, + decodedBinary, + ) + if err != nil { + return fmt.Errorf("failed to create workflow engine: %w", err) + } + + if err := engine.Start(ctx); err != nil { + return fmt.Errorf("failed to start workflow engine: %w", err) + } + + h.engineRegistry.Add(wfID, engine) + + return nil +} + +func (h *eventHandler) engineFactoryFn(ctx context.Context, id string, owner string, name string, config []byte, binary []byte) (services.Service, error) { moduleConfig := &host.ModuleConfig{Logger: h.lggr, Labeler: h.emitter} sdkSpec, err := host.GetWorkflowSpec(ctx, moduleConfig, binary, config) if err != nil { - return fmt.Errorf("failed to get workflow sdk spec: %w", err) + return nil, fmt.Errorf("failed to get workflow sdk spec: %w", err) } cfg := workflows.Config{ Lggr: h.lggr, Workflow: *sdkSpec, - WorkflowID: wfID, - WorkflowOwner: string(payload.Owner), // this gets hex encoded in the engine. - WorkflowName: payload.WorkflowName, + WorkflowID: id, + WorkflowOwner: owner, // this gets hex encoded in the engine. + WorkflowName: name, Registry: h.capRegistry, Store: h.workflowStore, Config: config, Binary: binary, SecretsFetcher: h, } - e, err := workflows.NewEngine(ctx, cfg) - if err != nil { - return fmt.Errorf("failed to create workflow engine: %w", err) - } - - if err := e.Start(ctx); err != nil { - return fmt.Errorf("failed to start workflow engine: %w", err) - } - - h.engineRegistry.Add(wfID, e) - - return nil + return workflows.NewEngine(ctx, cfg) } // workflowUpdatedEvent handles the WorkflowUpdatedEvent event type by first finding the @@ -483,14 +534,14 @@ func (h *eventHandler) workflowUpdatedEvent( } registeredEvent := WorkflowRegistryWorkflowRegisteredV1{ - WorkflowID: payload.NewWorkflowID, - Owner: payload.WorkflowOwner, - DonID: payload.DonID, - Status: 0, - WorkflowName: payload.WorkflowName, - BinaryURL: payload.BinaryURL, - ConfigURL: payload.ConfigURL, - SecretsURL: payload.SecretsURL, + WorkflowID: payload.NewWorkflowID, + WorkflowOwner: payload.WorkflowOwner, + DonID: payload.DonID, + Status: 0, + WorkflowName: payload.WorkflowName, + BinaryURL: payload.BinaryURL, + ConfigURL: payload.ConfigURL, + SecretsURL: payload.SecretsURL, } return h.workflowRegisteredEvent(ctx, registeredEvent) @@ -545,14 +596,14 @@ func (h *eventHandler) workflowActivatedEvent( // start a new workflow engine registeredEvent := WorkflowRegistryWorkflowRegisteredV1{ - WorkflowID: payload.WorkflowID, - Owner: payload.WorkflowOwner, - DonID: payload.DonID, - Status: 0, - WorkflowName: payload.WorkflowName, - BinaryURL: spec.BinaryURL, - ConfigURL: spec.ConfigURL, - SecretsURL: secretsURL, + WorkflowID: payload.WorkflowID, + WorkflowOwner: payload.WorkflowOwner, + DonID: payload.DonID, + Status: 0, + WorkflowName: payload.WorkflowName, + BinaryURL: spec.BinaryURL, + ConfigURL: spec.ConfigURL, + SecretsURL: secretsURL, } return h.workflowRegisteredEvent(ctx, registeredEvent) diff --git a/core/services/workflows/syncer/handler_test.go b/core/services/workflows/syncer/handler_test.go index bb0a61aea4d..f205cbde1cd 100644 --- a/core/services/workflows/syncer/handler_test.go +++ b/core/services/workflows/syncer/handler_test.go @@ -3,6 +3,7 @@ package syncer import ( "context" "database/sql" + "encoding/base64" "encoding/hex" "encoding/json" "errors" @@ -10,6 +11,7 @@ import ( "time" "github.com/smartcontractkit/chainlink-common/pkg/custmsg" + "github.com/smartcontractkit/chainlink-common/pkg/services" pkgworkflows "github.com/smartcontractkit/chainlink-common/pkg/workflows" "github.com/smartcontractkit/chainlink-common/pkg/workflows/secrets" "github.com/smartcontractkit/chainlink/v2/core/capabilities" @@ -46,6 +48,28 @@ func newMockFetcher(m map[string]mockFetchResp) FetcherFunc { return (&mockFetcher{responseMap: m}).Fetch } +type mockEngine struct { + CloseErr error + ReadyErr error + StartErr error +} + +func (m *mockEngine) Ready() error { + return m.ReadyErr +} + +func (m *mockEngine) Close() error { + return m.CloseErr +} + +func (m *mockEngine) Start(_ context.Context) error { + return m.StartErr +} + +func (m *mockEngine) HealthReport() map[string]error { return nil } + +func (m *mockEngine) Name() string { return "mockEngine" } + func Test_Handler(t *testing.T) { lggr := logger.TestLogger(t) emitter := custmsg.NewLabeler() @@ -173,59 +197,238 @@ const ( ) func Test_workflowRegisteredHandler(t *testing.T) { - t.Run("success with paused workflow registered", func(t *testing.T) { - var ( - ctx = testutils.Context(t) - lggr = logger.TestLogger(t) - db = pgtest.NewSqlxDB(t) - orm = NewWorkflowRegistryDS(db, lggr) - emitter = custmsg.NewLabeler() - - binary = wasmtest.CreateTestBinary(binaryCmd, binaryLocation, true, t) - config = []byte("") - secretsURL = "http://example.com" - binaryURL = "http://example.com/binary" - configURL = "http://example.com/config" - wfOwner = []byte("0xOwner") - - fetcher = newMockFetcher(map[string]mockFetchResp{ - binaryURL: {Body: binary, Err: nil}, - configURL: {Body: config, Err: nil}, - secretsURL: {Body: []byte("secrets"), Err: nil}, - }) - ) - - giveWFID, err := pkgworkflows.GenerateWorkflowID(wfOwner, binary, config, secretsURL) - require.NoError(t, err) - - paused := WorkflowRegistryWorkflowRegisteredV1{ - Status: uint8(1), - WorkflowID: giveWFID, - Owner: wfOwner, - WorkflowName: "workflow-name", - BinaryURL: binaryURL, - ConfigURL: configURL, - SecretsURL: secretsURL, - } + var binaryURL = "http://example.com/binary" + var secretsURL = "http://example.com/secrets" + var configURL = "http://example.com/config" + var config = []byte("") + var wfOwner = []byte("0xOwner") + var binary = wasmtest.CreateTestBinary(binaryCmd, binaryLocation, true, t) + var encodedBinary = []byte(base64.StdEncoding.EncodeToString(binary)) - h := &eventHandler{ - lggr: lggr, - orm: orm, - fetcher: fetcher, - emitter: emitter, - } - err = h.workflowRegisteredEvent(ctx, paused) + defaultValidationFn := func(t *testing.T, ctx context.Context, event WorkflowRegistryWorkflowRegisteredV1, h *eventHandler, wfOwner []byte, wfName string, wfID string) { + err := h.workflowRegisteredEvent(ctx, event) require.NoError(t, err) // Verify the record is updated in the database - dbSpec, err := orm.GetWorkflowSpec(ctx, hex.EncodeToString(wfOwner), "workflow-name") + dbSpec, err := h.orm.GetWorkflowSpec(ctx, hex.EncodeToString(wfOwner), "workflow-name") require.NoError(t, err) require.Equal(t, hex.EncodeToString(wfOwner), dbSpec.WorkflowOwner) require.Equal(t, "workflow-name", dbSpec.WorkflowName) - require.Equal(t, job.WorkflowSpecStatusPaused, dbSpec.Status) - }) + require.Equal(t, job.WorkflowSpecStatusActive, dbSpec.Status) + + // Verify the engine is started + engine, err := h.engineRegistry.Get(wfID) + require.NoError(t, err) + err = engine.Ready() + require.NoError(t, err) + } + + var tt = []testCase{ + { + Name: "success with active workflow registered", + fetcher: newMockFetcher(map[string]mockFetchResp{ + binaryURL: {Body: encodedBinary, Err: nil}, + configURL: {Body: config, Err: nil}, + secretsURL: {Body: []byte("secrets"), Err: nil}, + }), + engineFactoryFn: func(ctx context.Context, wfid string, owner string, name string, config []byte, binary []byte) (services.Service, error) { + return &mockEngine{}, nil + }, + GiveConfig: config, + ConfigURL: configURL, + SecretsURL: secretsURL, + BinaryURL: binaryURL, + GiveBinary: binary, + WFOwner: wfOwner, + Event: func(wfID []byte) WorkflowRegistryWorkflowRegisteredV1 { + return WorkflowRegistryWorkflowRegisteredV1{ + Status: uint8(0), + WorkflowID: [32]byte(wfID), + WorkflowOwner: wfOwner, + WorkflowName: "workflow-name", + BinaryURL: binaryURL, + ConfigURL: configURL, + SecretsURL: secretsURL, + } + }, + validationFn: defaultValidationFn, + }, + { + Name: "fails to start engine", + fetcher: newMockFetcher(map[string]mockFetchResp{ + binaryURL: {Body: encodedBinary, Err: nil}, + configURL: {Body: config, Err: nil}, + secretsURL: {Body: []byte("secrets"), Err: nil}, + }), + engineFactoryFn: func(ctx context.Context, wfid string, owner string, name string, config []byte, binary []byte) (services.Service, error) { + return &mockEngine{StartErr: assert.AnError}, nil + }, + GiveConfig: config, + ConfigURL: configURL, + SecretsURL: secretsURL, + BinaryURL: binaryURL, + GiveBinary: binary, + WFOwner: wfOwner, + Event: func(wfID []byte) WorkflowRegistryWorkflowRegisteredV1 { + return WorkflowRegistryWorkflowRegisteredV1{ + Status: uint8(0), + WorkflowID: [32]byte(wfID), + WorkflowOwner: wfOwner, + WorkflowName: "workflow-name", + BinaryURL: binaryURL, + ConfigURL: configURL, + SecretsURL: secretsURL, + } + }, + validationFn: func(t *testing.T, ctx context.Context, event WorkflowRegistryWorkflowRegisteredV1, h *eventHandler, wfOwner []byte, wfName string, wfID string) { + err := h.workflowRegisteredEvent(ctx, event) + require.Error(t, err) + require.ErrorIs(t, err, assert.AnError) + }, + }, + { + Name: "fails if running engine exists", + fetcher: newMockFetcher(map[string]mockFetchResp{ + binaryURL: {Body: encodedBinary, Err: nil}, + configURL: {Body: config, Err: nil}, + secretsURL: {Body: []byte("secrets"), Err: nil}, + }), + GiveConfig: config, + ConfigURL: configURL, + SecretsURL: secretsURL, + BinaryURL: binaryURL, + GiveBinary: binary, + WFOwner: wfOwner, + Event: func(wfID []byte) WorkflowRegistryWorkflowRegisteredV1 { + return WorkflowRegistryWorkflowRegisteredV1{ + Status: uint8(0), + WorkflowID: [32]byte(wfID), + WorkflowOwner: wfOwner, + WorkflowName: "workflow-name", + BinaryURL: binaryURL, + ConfigURL: configURL, + SecretsURL: secretsURL, + } + }, + validationFn: func(t *testing.T, ctx context.Context, event WorkflowRegistryWorkflowRegisteredV1, h *eventHandler, wfOwner []byte, wfName string, wfID string) { + me := &mockEngine{} + h.engineRegistry.Add(wfID, me) + err := h.workflowRegisteredEvent(ctx, event) + require.Error(t, err) + require.ErrorContains(t, err, "workflow is already running") + }, + }, + { + Name: "success with paused workflow registered", + fetcher: newMockFetcher(map[string]mockFetchResp{ + binaryURL: {Body: encodedBinary, Err: nil}, + configURL: {Body: config, Err: nil}, + secretsURL: {Body: []byte("secrets"), Err: nil}, + }), + GiveConfig: config, + ConfigURL: configURL, + SecretsURL: secretsURL, + BinaryURL: binaryURL, + GiveBinary: binary, + WFOwner: wfOwner, + Event: func(wfID []byte) WorkflowRegistryWorkflowRegisteredV1 { + return WorkflowRegistryWorkflowRegisteredV1{ + Status: uint8(1), + WorkflowID: [32]byte(wfID), + WorkflowOwner: wfOwner, + WorkflowName: "workflow-name", + BinaryURL: binaryURL, + ConfigURL: configURL, + SecretsURL: secretsURL, + } + }, + validationFn: func(t *testing.T, ctx context.Context, event WorkflowRegistryWorkflowRegisteredV1, h *eventHandler, wfOwner []byte, wfName string, wfID string) { + err := h.workflowRegisteredEvent(ctx, event) + require.NoError(t, err) + + // Verify the record is updated in the database + dbSpec, err := h.orm.GetWorkflowSpec(ctx, hex.EncodeToString(wfOwner), "workflow-name") + require.NoError(t, err) + require.Equal(t, hex.EncodeToString(wfOwner), dbSpec.WorkflowOwner) + require.Equal(t, "workflow-name", dbSpec.WorkflowName) + require.Equal(t, job.WorkflowSpecStatusPaused, dbSpec.Status) + + // Verify there is no running engine + _, err = h.engineRegistry.Get(wfID) + require.Error(t, err) + }, + }, + { + Name: "skips fetch if config url is missing", + GiveConfig: make([]byte, 0), + ConfigURL: "", + SecretsURL: secretsURL, + BinaryURL: binaryURL, + GiveBinary: binary, + WFOwner: wfOwner, + fetcher: newMockFetcher(map[string]mockFetchResp{ + binaryURL: {Body: encodedBinary, Err: nil}, + secretsURL: {Body: []byte("secrets"), Err: nil}, + }), + validationFn: defaultValidationFn, + Event: func(wfID []byte) WorkflowRegistryWorkflowRegisteredV1 { + return WorkflowRegistryWorkflowRegisteredV1{ + Status: uint8(0), + WorkflowID: [32]byte(wfID), + WorkflowOwner: wfOwner, + WorkflowName: "workflow-name", + BinaryURL: binaryURL, + SecretsURL: secretsURL, + } + }, + }, + { + Name: "skips fetch if secrets url is missing", + GiveConfig: config, + ConfigURL: configURL, + BinaryURL: binaryURL, + GiveBinary: binary, + WFOwner: wfOwner, + fetcher: newMockFetcher(map[string]mockFetchResp{ + binaryURL: {Body: encodedBinary, Err: nil}, + configURL: {Body: config, Err: nil}, + }), + validationFn: defaultValidationFn, + Event: func(wfID []byte) WorkflowRegistryWorkflowRegisteredV1 { + return WorkflowRegistryWorkflowRegisteredV1{ + Status: uint8(0), + WorkflowID: [32]byte(wfID), + WorkflowOwner: wfOwner, + WorkflowName: "workflow-name", + BinaryURL: binaryURL, + ConfigURL: configURL, + } + }, + }, + } - t.Run("success with active workflow registered", func(t *testing.T) { + for _, tc := range tt { + testRunningWorkflow(t, tc) + } +} + +type testCase struct { + Name string + SecretsURL string + BinaryURL string + GiveBinary []byte + GiveConfig []byte + ConfigURL string + WFOwner []byte + fetcher FetcherFunc + Event func([]byte) WorkflowRegistryWorkflowRegisteredV1 + validationFn func(t *testing.T, ctx context.Context, event WorkflowRegistryWorkflowRegisteredV1, h *eventHandler, wfOwner []byte, wfName string, wfID string) + engineFactoryFn func(ctx context.Context, wfid string, owner string, name string, config []byte, binary []byte) (services.Service, error) +} + +func testRunningWorkflow(t *testing.T, tc testCase) { + t.Helper() + t.Run(tc.Name, func(t *testing.T) { var ( ctx = testutils.Context(t) lggr = logger.TestLogger(t) @@ -233,63 +436,35 @@ func Test_workflowRegisteredHandler(t *testing.T) { orm = NewWorkflowRegistryDS(db, lggr) emitter = custmsg.NewLabeler() - binary = wasmtest.CreateTestBinary(binaryCmd, binaryLocation, true, t) - config = []byte("") - secretsURL = "http://example.com" - binaryURL = "http://example.com/binary" - configURL = "http://example.com/config" - wfOwner = []byte("0xOwner") + binary = tc.GiveBinary + config = tc.GiveConfig + secretsURL = tc.SecretsURL + wfOwner = tc.WFOwner - fetcher = newMockFetcher(map[string]mockFetchResp{ - binaryURL: {Body: binary, Err: nil}, - configURL: {Body: config, Err: nil}, - secretsURL: {Body: []byte("secrets"), Err: nil}, - }) + fetcher = tc.fetcher ) - giveWFID, err := pkgworkflows.GenerateWorkflowID(wfOwner, binary, config, secretsURL) + giveWFID, err := pkgworkflows.GenerateWorkflowID(wfOwner, "workflow-name", binary, config, secretsURL) require.NoError(t, err) - require.NoError(t, err) + wfID := hex.EncodeToString(giveWFID[:]) - active := WorkflowRegistryWorkflowRegisteredV1{ - Status: uint8(0), - WorkflowID: giveWFID, - Owner: wfOwner, - WorkflowName: "workflow-name", - BinaryURL: binaryURL, - ConfigURL: configURL, - SecretsURL: secretsURL, - } + event := tc.Event(giveWFID[:]) - er := newEngineRegistry() + er := NewEngineRegistry() + opts := []func(*eventHandler){ + WithEngineRegistry(er), + } + if tc.engineFactoryFn != nil { + opts = append(opts, WithEngineFactoryFn(tc.engineFactoryFn)) + } store := wfstore.NewDBStore(db, lggr, clockwork.NewFakeClock()) registry := capabilities.NewRegistry(lggr) registry.SetLocalRegistry(&capabilities.TestMetadataRegistry{}) - h := &eventHandler{ - lggr: lggr, - orm: orm, - fetcher: fetcher, - emitter: emitter, - engineRegistry: er, - capRegistry: registry, - workflowStore: store, - } - err = h.workflowRegisteredEvent(ctx, active) - require.NoError(t, err) - - // Verify the record is updated in the database - dbSpec, err := orm.GetWorkflowSpec(ctx, hex.EncodeToString(wfOwner), "workflow-name") - require.NoError(t, err) - require.Equal(t, hex.EncodeToString(wfOwner), dbSpec.WorkflowOwner) - require.Equal(t, "workflow-name", dbSpec.WorkflowName) - require.Equal(t, job.WorkflowSpecStatusActive, dbSpec.Status) + h := NewEventHandler(lggr, orm, fetcher, store, registry, emitter, clockwork.NewFakeClock(), + workflowkey.Key{}, opts...) - // Verify the engine is started - engine, err := h.engineRegistry.Get(hex.EncodeToString(giveWFID[:])) - require.NoError(t, err) - err = engine.Ready() - require.NoError(t, err) + tc.validationFn(t, ctx, event, h, wfOwner, "workflow-name", wfID) }) } @@ -302,48 +477,51 @@ func Test_workflowDeletedHandler(t *testing.T) { orm = NewWorkflowRegistryDS(db, lggr) emitter = custmsg.NewLabeler() - binary = wasmtest.CreateTestBinary(binaryCmd, binaryLocation, true, t) - config = []byte("") - secretsURL = "http://example.com" - binaryURL = "http://example.com/binary" - configURL = "http://example.com/config" - wfOwner = []byte("0xOwner") + binary = wasmtest.CreateTestBinary(binaryCmd, binaryLocation, true, t) + encodedBinary = []byte(base64.StdEncoding.EncodeToString(binary)) + config = []byte("") + secretsURL = "http://example.com" + binaryURL = "http://example.com/binary" + configURL = "http://example.com/config" + wfOwner = []byte("0xOwner") fetcher = newMockFetcher(map[string]mockFetchResp{ - binaryURL: {Body: binary, Err: nil}, + binaryURL: {Body: encodedBinary, Err: nil}, configURL: {Body: config, Err: nil}, secretsURL: {Body: []byte("secrets"), Err: nil}, }) ) - giveWFID, err := pkgworkflows.GenerateWorkflowID(wfOwner, binary, config, secretsURL) + giveWFID, err := pkgworkflows.GenerateWorkflowID(wfOwner, "workflow-name", binary, config, secretsURL) require.NoError(t, err) wfIDs := hex.EncodeToString(giveWFID[:]) active := WorkflowRegistryWorkflowRegisteredV1{ - Status: uint8(0), - WorkflowID: giveWFID, - Owner: wfOwner, - WorkflowName: "workflow-name", - BinaryURL: binaryURL, - ConfigURL: configURL, - SecretsURL: secretsURL, + Status: uint8(0), + WorkflowID: giveWFID, + WorkflowOwner: wfOwner, + WorkflowName: "workflow-name", + BinaryURL: binaryURL, + ConfigURL: configURL, + SecretsURL: secretsURL, } - er := newEngineRegistry() + er := NewEngineRegistry() store := wfstore.NewDBStore(db, lggr, clockwork.NewFakeClock()) registry := capabilities.NewRegistry(lggr) registry.SetLocalRegistry(&capabilities.TestMetadataRegistry{}) - h := &eventHandler{ - lggr: lggr, - orm: orm, - fetcher: fetcher, - emitter: emitter, - engineRegistry: er, - capRegistry: registry, - workflowStore: store, - } + h := NewEventHandler( + lggr, + orm, + fetcher, + store, + registry, + emitter, + clockwork.NewFakeClock(), + workflowkey.Key{}, + WithEngineRegistry(er), + ) err = h.workflowRegisteredEvent(ctx, active) require.NoError(t, err) @@ -388,26 +566,27 @@ func Test_workflowPausedActivatedUpdatedHandler(t *testing.T) { orm = NewWorkflowRegistryDS(db, lggr) emitter = custmsg.NewLabeler() - binary = wasmtest.CreateTestBinary(binaryCmd, binaryLocation, true, t) - config = []byte("") - updateConfig = []byte("updated") - secretsURL = "http://example.com" - binaryURL = "http://example.com/binary" - configURL = "http://example.com/config" - newConfigURL = "http://example.com/new-config" - wfOwner = []byte("0xOwner") + binary = wasmtest.CreateTestBinary(binaryCmd, binaryLocation, true, t) + encodedBinary = []byte(base64.StdEncoding.EncodeToString(binary)) + config = []byte("") + updateConfig = []byte("updated") + secretsURL = "http://example.com" + binaryURL = "http://example.com/binary" + configURL = "http://example.com/config" + newConfigURL = "http://example.com/new-config" + wfOwner = []byte("0xOwner") fetcher = newMockFetcher(map[string]mockFetchResp{ - binaryURL: {Body: binary, Err: nil}, + binaryURL: {Body: encodedBinary, Err: nil}, configURL: {Body: config, Err: nil}, newConfigURL: {Body: updateConfig, Err: nil}, secretsURL: {Body: []byte("secrets"), Err: nil}, }) ) - giveWFID, err := pkgworkflows.GenerateWorkflowID(wfOwner, binary, config, secretsURL) + giveWFID, err := pkgworkflows.GenerateWorkflowID(wfOwner, "workflow-name", binary, config, secretsURL) require.NoError(t, err) - updatedWFID, err := pkgworkflows.GenerateWorkflowID(wfOwner, binary, updateConfig, secretsURL) + updatedWFID, err := pkgworkflows.GenerateWorkflowID(wfOwner, "workflow-name", binary, updateConfig, secretsURL) require.NoError(t, err) require.NoError(t, err) @@ -417,28 +596,30 @@ func Test_workflowPausedActivatedUpdatedHandler(t *testing.T) { newWFIDs := hex.EncodeToString(updatedWFID[:]) active := WorkflowRegistryWorkflowRegisteredV1{ - Status: uint8(0), - WorkflowID: giveWFID, - Owner: wfOwner, - WorkflowName: "workflow-name", - BinaryURL: binaryURL, - ConfigURL: configURL, - SecretsURL: secretsURL, + Status: uint8(0), + WorkflowID: giveWFID, + WorkflowOwner: wfOwner, + WorkflowName: "workflow-name", + BinaryURL: binaryURL, + ConfigURL: configURL, + SecretsURL: secretsURL, } - er := newEngineRegistry() + er := NewEngineRegistry() store := wfstore.NewDBStore(db, lggr, clockwork.NewFakeClock()) registry := capabilities.NewRegistry(lggr) registry.SetLocalRegistry(&capabilities.TestMetadataRegistry{}) - h := &eventHandler{ - lggr: lggr, - orm: orm, - fetcher: fetcher, - emitter: emitter, - engineRegistry: er, - capRegistry: registry, - workflowStore: store, - } + h := NewEventHandler( + lggr, + orm, + fetcher, + store, + registry, + emitter, + clockwork.NewFakeClock(), + workflowkey.Key{}, + WithEngineRegistry(er), + ) err = h.workflowRegisteredEvent(ctx, active) require.NoError(t, err) diff --git a/core/services/workflows/syncer/heap.go b/core/services/workflows/syncer/heap.go deleted file mode 100644 index 061293928a3..00000000000 --- a/core/services/workflows/syncer/heap.go +++ /dev/null @@ -1,63 +0,0 @@ -package syncer - -import "container/heap" - -type Heap interface { - // Push adds a new item to the heap. - Push(x WorkflowRegistryEventResponse) - - // Pop removes the smallest item from the heap and returns it. - Pop() WorkflowRegistryEventResponse - - // Len returns the number of items in the heap. - Len() int -} - -// publicHeap is a wrapper around the heap.Interface that exposes the Push and Pop methods. -type publicHeap[T any] struct { - heap heap.Interface -} - -func (h *publicHeap[T]) Push(x T) { - heap.Push(h.heap, x) -} - -func (h *publicHeap[T]) Pop() T { - return heap.Pop(h.heap).(T) -} - -func (h *publicHeap[T]) Len() int { - return h.heap.Len() -} - -// blockHeightHeap is a heap.Interface that sorts WorkflowRegistryEventResponses by block height. -type blockHeightHeap []WorkflowRegistryEventResponse - -// newBlockHeightHeap returns an initialized heap that sorts WorkflowRegistryEventResponses by block height. -func newBlockHeightHeap() Heap { - h := blockHeightHeap(make([]WorkflowRegistryEventResponse, 0)) - heap.Init(&h) - return &publicHeap[WorkflowRegistryEventResponse]{heap: &h} -} - -func (h *blockHeightHeap) Len() int { return len(*h) } - -func (h *blockHeightHeap) Less(i, j int) bool { - return (*h)[i].Event.Head.Height < (*h)[j].Event.Head.Height -} - -func (h *blockHeightHeap) Swap(i, j int) { - (*h)[i], (*h)[j] = (*h)[j], (*h)[i] -} - -func (h *blockHeightHeap) Push(x any) { - *h = append(*h, x.(WorkflowRegistryEventResponse)) -} - -func (h *blockHeightHeap) Pop() any { - old := *h - n := len(old) - x := old[n-1] - *h = old[0 : n-1] - return x -} diff --git a/core/services/workflows/syncer/orm.go b/core/services/workflows/syncer/orm.go index 97f2c834f36..bd0501795e6 100644 --- a/core/services/workflows/syncer/orm.go +++ b/core/services/workflows/syncer/orm.go @@ -161,6 +161,10 @@ func (orm *orm) GetContentsByWorkflowID(ctx context.Context, workflowID string) return "", "", ErrEmptySecrets } + if jr.Contents.String == "" { + return "", "", ErrEmptySecrets + } + return jr.SecretsURLHash.String, jr.Contents.String, nil } @@ -328,10 +332,13 @@ func (orm *orm) UpsertWorkflowSpecWithSecrets( status = EXCLUDED.status, binary_url = EXCLUDED.binary_url, config_url = EXCLUDED.config_url, - secrets_id = EXCLUDED.secrets_id, created_at = EXCLUDED.created_at, updated_at = EXCLUDED.updated_at, - spec_type = EXCLUDED.spec_type + spec_type = EXCLUDED.spec_type, + secrets_id = CASE + WHEN workflow_specs.secrets_id IS NULL THEN EXCLUDED.secrets_id + ELSE workflow_specs.secrets_id + END RETURNING id ` diff --git a/core/services/workflows/syncer/orm_test.go b/core/services/workflows/syncer/orm_test.go index 08c60447498..a94233e78a1 100644 --- a/core/services/workflows/syncer/orm_test.go +++ b/core/services/workflows/syncer/orm_test.go @@ -256,3 +256,120 @@ func Test_GetContentsByWorkflowID(t *testing.T) { assert.Equal(t, giveHash, gotHash) assert.Equal(t, giveContent, gotContent) } + +func Test_GetContentsByWorkflowID_SecretsProvidedButEmpty(t *testing.T) { + db := pgtest.NewSqlxDB(t) + ctx := testutils.Context(t) + lggr := logger.TestLogger(t) + orm := &orm{ds: db, lggr: lggr} + + // workflow_id is missing + _, _, err := orm.GetContentsByWorkflowID(ctx, "doesnt-exist") + require.ErrorContains(t, err, "no rows in result set") + + // secrets_id is nil; should return EmptySecrets + workflowID := "aWorkflowID" + giveURL := "https://example.com" + giveBytes, err := crypto.Keccak256([]byte(giveURL)) + require.NoError(t, err) + giveHash := hex.EncodeToString(giveBytes) + giveContent := "" + _, err = orm.UpsertWorkflowSpecWithSecrets(ctx, &job.WorkflowSpec{ + Workflow: "", + Config: "", + WorkflowID: workflowID, + WorkflowOwner: "aWorkflowOwner", + WorkflowName: "aWorkflowName", + BinaryURL: "", + ConfigURL: "", + CreatedAt: time.Now(), + SpecType: job.DefaultSpecType, + }, giveURL, giveHash, giveContent) + require.NoError(t, err) + + _, _, err = orm.GetContentsByWorkflowID(ctx, workflowID) + require.ErrorIs(t, err, ErrEmptySecrets) +} + +func Test_UpsertWorkflowSpecWithSecrets(t *testing.T) { + db := pgtest.NewSqlxDB(t) + ctx := testutils.Context(t) + lggr := logger.TestLogger(t) + orm := &orm{ds: db, lggr: lggr} + + t.Run("inserts new spec and new secrets", func(t *testing.T) { + giveURL := "https://example.com" + giveBytes, err := crypto.Keccak256([]byte(giveURL)) + require.NoError(t, err) + giveHash := hex.EncodeToString(giveBytes) + giveContent := "some contents" + + spec := &job.WorkflowSpec{ + Workflow: "test_workflow", + Config: "test_config", + WorkflowID: "cid-123", + WorkflowOwner: "owner-123", + WorkflowName: "Test Workflow", + Status: job.WorkflowSpecStatusActive, + BinaryURL: "http://example.com/binary", + ConfigURL: "http://example.com/config", + CreatedAt: time.Now(), + SpecType: job.WASMFile, + } + + _, err = orm.UpsertWorkflowSpecWithSecrets(ctx, spec, giveURL, giveHash, giveContent) + require.NoError(t, err) + + // Verify the record exists in the database + var dbSpec job.WorkflowSpec + err = db.Get(&dbSpec, `SELECT * FROM workflow_specs WHERE workflow_owner = $1 AND workflow_name = $2`, spec.WorkflowOwner, spec.WorkflowName) + require.NoError(t, err) + require.Equal(t, spec.Workflow, dbSpec.Workflow) + + // Verify the secrets exists in the database + contents, err := orm.GetContents(ctx, giveURL) + require.NoError(t, err) + require.Equal(t, giveContent, contents) + }) + + t.Run("updates existing spec and secrets", func(t *testing.T) { + giveURL := "https://example.com" + giveBytes, err := crypto.Keccak256([]byte(giveURL)) + require.NoError(t, err) + giveHash := hex.EncodeToString(giveBytes) + giveContent := "some contents" + + spec := &job.WorkflowSpec{ + Workflow: "test_workflow", + Config: "test_config", + WorkflowID: "cid-123", + WorkflowOwner: "owner-123", + WorkflowName: "Test Workflow", + Status: job.WorkflowSpecStatusActive, + BinaryURL: "http://example.com/binary", + ConfigURL: "http://example.com/config", + CreatedAt: time.Now(), + SpecType: job.WASMFile, + } + + _, err = orm.UpsertWorkflowSpecWithSecrets(ctx, spec, giveURL, giveHash, giveContent) + require.NoError(t, err) + + // Update the status + spec.Status = job.WorkflowSpecStatusPaused + + _, err = orm.UpsertWorkflowSpecWithSecrets(ctx, spec, giveURL, giveHash, "new contents") + require.NoError(t, err) + + // Verify the record is updated in the database + var dbSpec job.WorkflowSpec + err = db.Get(&dbSpec, `SELECT * FROM workflow_specs WHERE workflow_owner = $1 AND workflow_name = $2`, spec.WorkflowOwner, spec.WorkflowName) + require.NoError(t, err) + require.Equal(t, spec.Config, dbSpec.Config) + + // Verify the secrets is updated in the database + contents, err := orm.GetContents(ctx, giveURL) + require.NoError(t, err) + require.Equal(t, "new contents", contents) + }) +} diff --git a/core/services/workflows/syncer/workflow_registry.go b/core/services/workflows/syncer/workflow_registry.go index 024975539af..223fbe8e758 100644 --- a/core/services/workflows/syncer/workflow_registry.go +++ b/core/services/workflows/syncer/workflow_registry.go @@ -5,13 +5,14 @@ import ( "encoding/hex" "encoding/json" "fmt" + "iter" "sync" "time" "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/services" - types "github.com/smartcontractkit/chainlink-common/pkg/types" - query "github.com/smartcontractkit/chainlink-common/pkg/types/query" + "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/query" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" "github.com/smartcontractkit/chainlink-common/pkg/values" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/workflow/generated/workflow_registry_wrapper" @@ -39,8 +40,19 @@ type GetWorkflowMetadataListByDONParams struct { Limit uint64 } +type GetWorkflowMetadata struct { + WorkflowID [32]byte + Owner []byte + DonID uint32 + Status uint8 + WorkflowName string + BinaryURL string + ConfigURL string + SecretsURL string +} + type GetWorkflowMetadataListByDONReturnVal struct { - WorkflowMetadataList []WorkflowRegistryWorkflowRegisteredV1 + WorkflowMetadataList []GetWorkflowMetadata } // WorkflowRegistryEvent is an event emitted by the WorkflowRegistry. Each event is typed @@ -79,17 +91,19 @@ type WorkflowLoadConfig struct { // FetcherFunc is an abstraction for fetching the contents stored at a URL. type FetcherFunc func(ctx context.Context, url string) ([]byte, error) -type ContractReaderFactory interface { - NewContractReader(context.Context, []byte) (types.ContractReader, error) -} - // ContractReader is a subset of types.ContractReader defined locally to enable mocking. type ContractReader interface { + Start(ctx context.Context) error + Close() error Bind(context.Context, []types.BoundContract) error - QueryKey(context.Context, types.BoundContract, query.KeyFilter, query.LimitAndSort, any) ([]types.Sequence, error) + QueryKeys(ctx context.Context, keyQueries []types.ContractKeyFilter, limitAndSort query.LimitAndSort) (iter.Seq2[string, types.Sequence], error) GetLatestValueWithHeadData(ctx context.Context, readName string, confidenceLevel primitives.ConfidenceLevel, params any, returnVal any) (head *types.Head, err error) } +type ContractReaderFactory interface { + NewContractReader(context.Context, []byte) (types.ContractReader, error) +} + // WorkflowRegistrySyncer is the public interface of the package. type WorkflowRegistrySyncer interface { services.Service @@ -115,21 +129,11 @@ type workflowRegistry struct { newContractReaderFn newContractReaderFn - eventPollerCfg WorkflowEventPollerConfig - eventTypes []WorkflowRegistryEventType - - // eventsCh is read by the handler and each event is handled once received. - eventsCh chan WorkflowRegistryEventResponse + eventPollerCfg WorkflowEventPollerConfig + eventTypes []WorkflowRegistryEventType handler evtHandler initialWorkflowsStateLoader initialWorkflowsStateLoader - // batchCh is a channel that receives batches of events from the contract query goroutines. - batchCh chan []WorkflowRegistryEventResponse - - // heap is a min heap that merges batches of events from the contract query goroutines. The - // default min heap is sorted by block height. - heap Heap - workflowDonNotifier donNotifier reader ContractReader @@ -171,17 +175,21 @@ func NewWorkflowRegistry( workflowDonNotifier donNotifier, opts ...func(*workflowRegistry), ) *workflowRegistry { - ets := []WorkflowRegistryEventType{ForceUpdateSecretsEvent} + ets := []WorkflowRegistryEventType{ + ForceUpdateSecretsEvent, + WorkflowActivatedEvent, + WorkflowDeletedEvent, + WorkflowPausedEvent, + WorkflowRegisteredEvent, + WorkflowUpdatedEvent, + } wr := &workflowRegistry{ lggr: lggr, newContractReaderFn: newContractReaderFn, workflowRegistryAddress: addr, eventPollerCfg: eventPollerConfig, - heap: newBlockHeightHeap(), stopCh: make(services.StopChan), eventTypes: ets, - eventsCh: make(chan WorkflowRegistryEventResponse), - batchCh: make(chan []WorkflowRegistryEventResponse, len(ets)), handler: handler, initialWorkflowsStateLoader: initialWorkflowsStateLoader, workflowDonNotifier: workflowDonNotifier, @@ -207,26 +215,24 @@ func (w *workflowRegistry) Start(_ context.Context) error { w.lggr.Debugw("Waiting for DON...") don, err := w.workflowDonNotifier.WaitForDon(ctx) if err != nil { - w.lggr.Errorf("failed to wait for don: %v", err) + w.lggr.Errorw("failed to wait for don", "err", err) return } w.lggr.Debugw("Loading initial workflows for DON", "DON", don.ID) loadWorkflowsHead, err := w.initialWorkflowsStateLoader.LoadWorkflows(ctx, don) if err != nil { - w.lggr.Errorf("failed to load workflows: %v", err) + w.lggr.Errorw("failed to load workflows", "err", err) return } - w.syncEventsLoop(ctx, loadWorkflowsHead.Height) - }() - - w.wg.Add(1) - go func() { - defer w.wg.Done() - defer cancel() + reader, err := w.getContractReader(ctx) + if err != nil { + w.lggr.Criticalf("contract reader unavailable : %s", err) + return + } - w.handlerLoop(ctx) + w.readRegistryEvents(ctx, reader, loadWorkflowsHead.Height) }() return nil @@ -253,135 +259,82 @@ func (w *workflowRegistry) Name() string { return name } -// handlerLoop handles the events that are emitted by the contract. -func (w *workflowRegistry) handlerLoop(ctx context.Context) { +// readRegistryEvents polls the contract for events and send them to the events channel. +func (w *workflowRegistry) readRegistryEvents(ctx context.Context, reader ContractReader, lastReadBlockNumber string) { + ticker := w.getTicker() + + var keyQueries = make([]types.ContractKeyFilter, 0, len(w.eventTypes)) + for _, et := range w.eventTypes { + var logData values.Value + keyQueries = append(keyQueries, types.ContractKeyFilter{ + KeyFilter: query.KeyFilter{ + Key: string(et), + Expressions: []query.Expression{ + query.Confidence(primitives.Finalized), + query.Block(lastReadBlockNumber, primitives.Gt), + }, + }, + Contract: types.BoundContract{ + Name: WorkflowRegistryContractName, + Address: w.workflowRegistryAddress, + }, + SequenceDataType: &logData, + }) + } + + cursor := "" for { select { case <-ctx.Done(): return - case resp, open := <-w.eventsCh: - if !open { - return + case <-ticker: + limitAndSort := query.LimitAndSort{ + SortBy: []query.SortBy{query.NewSortByTimestamp(query.Asc)}, + Limit: query.Limit{Count: w.eventPollerCfg.QueryCount}, } - - if resp.Err != nil || resp.Event == nil { - w.lggr.Errorf("failed to handle event: %+v", resp.Err) - continue + if cursor != "" { + limitAndSort.Limit = query.CursorLimit(cursor, query.CursorFollowing, w.eventPollerCfg.QueryCount) } - event := resp.Event - w.lggr.Debugf("handling event: %+v", event) - if err := w.handler.Handle(ctx, *event); err != nil { - w.lggr.Errorf("failed to handle event: %+v", event) + logsIter, err := reader.QueryKeys(ctx, keyQueries, limitAndSort) + if err != nil { + w.lggr.Errorw("failed to query keys", "err", err) continue } - } - } -} -// syncEventsLoop polls the contract for events and passes them to a channel for handling. -func (w *workflowRegistry) syncEventsLoop(ctx context.Context, lastReadBlockNumber string) { - var ( - // sendLog is a helper that sends a WorkflowRegistryEventResponse to the eventsCh in a - // blocking way that will send the response or be canceled. - sendLog = func(resp WorkflowRegistryEventResponse) { - select { - case w.eventsCh <- resp: - case <-ctx.Done(): + var logs []sequenceWithEventType + for eventType, log := range logsIter { + logs = append(logs, sequenceWithEventType{ + Sequence: log, + EventType: WorkflowRegistryEventType(eventType), + }) } - } - - ticker = w.getTicker() - - signals = make(map[WorkflowRegistryEventType]chan struct{}, 0) - ) + w.lggr.Debugw("QueryKeys called", "logs", len(logs), "eventTypes", w.eventTypes, "lastReadBlockNumber", lastReadBlockNumber, "logCursor", cursor) - // critical failure if there is no reader, the loop will exit and the parent context will be - // canceled. - reader, err := w.getContractReader(ctx) - if err != nil { - w.lggr.Criticalf("contract reader unavailable : %s", err) - return - } - - // fan out and query for each event type - for i := 0; i < len(w.eventTypes); i++ { - signal := make(chan struct{}, 1) - signals[w.eventTypes[i]] = signal - w.wg.Add(1) - go func() { - defer w.wg.Done() - - queryEvent( - ctx, - signal, - w.lggr, - reader, - lastReadBlockNumber, - queryEventConfig{ - ContractName: WorkflowRegistryContractName, - ContractAddress: w.workflowRegistryAddress, - WorkflowEventPollerConfig: w.eventPollerCfg, - }, - w.eventTypes[i], - w.batchCh, - ) - }() - } - - // Periodically send a signal to all the queryEvent goroutines to query the contract - for { - select { - case <-ctx.Done(): - return - case <-ticker: - w.lggr.Debugw("Syncing with WorkflowRegistry") - // for each event type, send a signal for it to execute a query and produce a new - // batch of event logs - for i := 0; i < len(w.eventTypes); i++ { - signal := signals[w.eventTypes[i]] - select { - case signal <- struct{}{}: - case <-ctx.Done(): - return - } + // ChainReader QueryKey API provides logs including the cursor value and not + // after the cursor value. If the response only consists of the log corresponding + // to the cursor and no log after it, then we understand that there are no new + // logs + if len(logs) == 1 && logs[0].Sequence.Cursor == cursor { + w.lggr.Infow("No new logs since", "cursor", cursor) + continue } - // block on fan-in until all fetched event logs are sent to the handlers - w.orderAndSend( - ctx, - len(w.eventTypes), - w.batchCh, - sendLog, - ) - } - } -} + var events []WorkflowRegistryEventResponse + for _, log := range logs { + if log.Sequence.Cursor == cursor { + continue + } -// orderAndSend reads n batches from the batch channel, heapifies all the batches then dequeues -// the min heap via the sendLog function. -func (w *workflowRegistry) orderAndSend( - ctx context.Context, - batchCount int, - batchCh <-chan []WorkflowRegistryEventResponse, - sendLog func(WorkflowRegistryEventResponse), -) { - for { - select { - case <-ctx.Done(): - return - case batch := <-batchCh: - for _, response := range batch { - w.heap.Push(response) + events = append(events, toWorkflowRegistryEventResponse(log.Sequence, log.EventType, w.lggr)) + cursor = log.Sequence.Cursor } - batchCount-- - // If we have received responses for all the events, then we can drain the heap. - if batchCount == 0 { - for w.heap.Len() > 0 { - sendLog(w.heap.Pop()) + for _, event := range events { + err := w.handler.Handle(ctx, event.Event) + if err != nil { + w.lggr.Errorw("failed to handle event", "err", err) } - return } } } @@ -417,89 +370,9 @@ func (w *workflowRegistry) getContractReader(ctx context.Context) (ContractReade return w.reader, nil } -type queryEventConfig struct { - ContractName string - ContractAddress string - WorkflowEventPollerConfig -} - -// queryEvent queries the contract for events of the given type on each tick from the ticker. -// Sends a batch of event logs to the batch channel. The batch represents all the -// event logs read since the last query. Loops until the context is canceled. -func queryEvent( - ctx context.Context, - ticker <-chan struct{}, - lggr logger.Logger, - reader ContractReader, - lastReadBlockNumber string, - cfg queryEventConfig, - et WorkflowRegistryEventType, - batchCh chan<- []WorkflowRegistryEventResponse, -) { - // create query - var ( - responseBatch []WorkflowRegistryEventResponse - logData values.Value - cursor = "" - limitAndSort = query.LimitAndSort{ - SortBy: []query.SortBy{query.NewSortByTimestamp(query.Asc)}, - Limit: query.Limit{Count: cfg.QueryCount}, - } - bc = types.BoundContract{ - Name: cfg.ContractName, - Address: cfg.ContractAddress, - } - ) - - // Loop until canceled - for { - select { - case <-ctx.Done(): - return - case <-ticker: - if cursor != "" { - limitAndSort.Limit = query.CursorLimit(cursor, query.CursorFollowing, cfg.QueryCount) - } - - logs, err := reader.QueryKey( - ctx, - bc, - query.KeyFilter{ - Key: string(et), - Expressions: []query.Expression{ - query.Confidence(primitives.Finalized), - query.Block(lastReadBlockNumber, primitives.Gt), - }, - }, - limitAndSort, - &logData, - ) - - if err != nil { - lggr.Errorw("QueryKey failure", "err", err) - continue - } - - // ChainReader QueryKey API provides logs including the cursor value and not - // after the cursor value. If the response only consists of the log corresponding - // to the cursor and no log after it, then we understand that there are no new - // logs - if len(logs) == 1 && logs[0].Cursor == cursor { - lggr.Infow("No new logs since", "cursor", cursor) - continue - } - - for _, log := range logs { - if log.Cursor == cursor { - continue - } - - responseBatch = append(responseBatch, toWorkflowRegistryEventResponse(log, et, lggr)) - cursor = log.Cursor - } - batchCh <- responseBatch - } - } +type sequenceWithEventType struct { + Sequence types.Sequence + EventType WorkflowRegistryEventType } func getWorkflowRegistryEventReader( @@ -511,7 +384,14 @@ func getWorkflowRegistryEventReader( Contracts: map[string]evmtypes.ChainContractReader{ WorkflowRegistryContractName: { ContractPollingFilter: evmtypes.ContractPollingFilter{ - GenericEventNames: []string{string(ForceUpdateSecretsEvent)}, + GenericEventNames: []string{ + string(ForceUpdateSecretsEvent), + string(WorkflowActivatedEvent), + string(WorkflowDeletedEvent), + string(WorkflowPausedEvent), + string(WorkflowRegisteredEvent), + string(WorkflowUpdatedEvent), + }, }, ContractABI: workflow_registry_wrapper.WorkflowRegistryABI, Configs: map[string]*evmtypes.ChainReaderDefinition{ @@ -519,6 +399,26 @@ func getWorkflowRegistryEventReader( ChainSpecificName: string(ForceUpdateSecretsEvent), ReadType: evmtypes.Event, }, + string(WorkflowActivatedEvent): { + ChainSpecificName: string(WorkflowActivatedEvent), + ReadType: evmtypes.Event, + }, + string(WorkflowDeletedEvent): { + ChainSpecificName: string(WorkflowDeletedEvent), + ReadType: evmtypes.Event, + }, + string(WorkflowPausedEvent): { + ChainSpecificName: string(WorkflowPausedEvent), + ReadType: evmtypes.Event, + }, + string(WorkflowRegisteredEvent): { + ChainSpecificName: string(WorkflowRegisteredEvent), + ReadType: evmtypes.Event, + }, + string(WorkflowUpdatedEvent): { + ChainSpecificName: string(WorkflowUpdatedEvent), + ReadType: evmtypes.Event, + }, }, }, }, @@ -539,6 +439,10 @@ func getWorkflowRegistryEventReader( return nil, err } + if err := reader.Start(ctx); err != nil { + return nil, err + } + return reader, nil } @@ -624,13 +528,23 @@ func (l *workflowRegistryContractLoader) LoadWorkflows(ctx context.Context, don var workflows GetWorkflowMetadataListByDONReturnVal headAtLastRead, err = contractReader.GetLatestValueWithHeadData(ctx, readIdentifier, primitives.Finalized, params, &workflows) if err != nil { - return nil, fmt.Errorf("failed to get workflow metadata for don %w", err) + return nil, fmt.Errorf("failed to get lastest value with head data %w", err) } l.lggr.Debugw("Rehydrating existing workflows", "len", len(workflows.WorkflowMetadataList)) for _, workflow := range workflows.WorkflowMetadataList { + toRegisteredEvent := WorkflowRegistryWorkflowRegisteredV1{ + WorkflowID: workflow.WorkflowID, + WorkflowOwner: workflow.Owner, + DonID: workflow.DonID, + Status: workflow.Status, + WorkflowName: workflow.WorkflowName, + BinaryURL: workflow.BinaryURL, + ConfigURL: workflow.ConfigURL, + SecretsURL: workflow.SecretsURL, + } if err = l.handler.Handle(ctx, workflowAsEvent{ - Data: workflow, + Data: toRegisteredEvent, EventType: WorkflowRegisteredEvent, }); err != nil { l.lggr.Errorf("failed to handle workflow registration: %s", err) @@ -682,6 +596,51 @@ func toWorkflowRegistryEventResponse( return resp } resp.Event.Data = data + case WorkflowRegisteredEvent: + var data WorkflowRegistryWorkflowRegisteredV1 + if err := dataAsValuesMap.UnwrapTo(&data); err != nil { + lggr.Errorf("failed to unwrap data: %+v", log.Data) + resp.Event = nil + resp.Err = err + return resp + } + resp.Event.Data = data + case WorkflowUpdatedEvent: + var data WorkflowRegistryWorkflowUpdatedV1 + if err := dataAsValuesMap.UnwrapTo(&data); err != nil { + lggr.Errorf("failed to unwrap data: %+v", log.Data) + resp.Event = nil + resp.Err = err + return resp + } + resp.Event.Data = data + case WorkflowPausedEvent: + var data WorkflowRegistryWorkflowPausedV1 + if err := dataAsValuesMap.UnwrapTo(&data); err != nil { + lggr.Errorf("failed to unwrap data: %+v", log.Data) + resp.Event = nil + resp.Err = err + return resp + } + resp.Event.Data = data + case WorkflowActivatedEvent: + var data WorkflowRegistryWorkflowActivatedV1 + if err := dataAsValuesMap.UnwrapTo(&data); err != nil { + lggr.Errorf("failed to unwrap data: %+v", log.Data) + resp.Event = nil + resp.Err = err + return resp + } + resp.Event.Data = data + case WorkflowDeletedEvent: + var data WorkflowRegistryWorkflowDeletedV1 + if err := dataAsValuesMap.UnwrapTo(&data); err != nil { + lggr.Errorf("failed to unwrap data: %+v", log.Data) + resp.Event = nil + resp.Err = err + return resp + } + resp.Event.Data = data default: lggr.Errorf("unknown event type: %s", evt) resp.Event = nil diff --git a/core/services/workflows/syncer/workflow_registry_test.go b/core/services/workflows/syncer/workflow_registry_test.go deleted file mode 100644 index 8a7c3bb0a7c..00000000000 --- a/core/services/workflows/syncer/workflow_registry_test.go +++ /dev/null @@ -1,138 +0,0 @@ -package syncer - -import ( - "context" - "encoding/hex" - "testing" - "time" - - "github.com/stretchr/testify/mock" - - "github.com/jonboulle/clockwork" - - "github.com/smartcontractkit/chainlink-common/pkg/capabilities" - "github.com/smartcontractkit/chainlink-common/pkg/custmsg" - "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" - types "github.com/smartcontractkit/chainlink-common/pkg/types" - query "github.com/smartcontractkit/chainlink-common/pkg/types/query" - "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" - "github.com/smartcontractkit/chainlink-common/pkg/values" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/workflowkey" - "github.com/smartcontractkit/chainlink/v2/core/utils/crypto" - "github.com/smartcontractkit/chainlink/v2/core/utils/matches" - - "github.com/stretchr/testify/require" -) - -type testDonNotifier struct { - don capabilities.DON - err error -} - -func (t *testDonNotifier) WaitForDon(ctx context.Context) (capabilities.DON, error) { - return t.don, t.err -} - -func Test_Workflow_Registry_Syncer(t *testing.T) { - var ( - giveContents = "contents" - wantContents = "updated contents" - contractAddress = "0xdeadbeef" - giveCfg = WorkflowEventPollerConfig{ - QueryCount: 20, - } - giveURL = "http://example.com" - giveHash, err = crypto.Keccak256([]byte(giveURL)) - - giveLog = types.Sequence{ - Data: map[string]any{ - "SecretsURLHash": giveHash, - "Owner": "0xowneraddr", - }, - Cursor: "cursor", - } - ) - - require.NoError(t, err) - - var ( - lggr = logger.TestLogger(t) - db = pgtest.NewSqlxDB(t) - orm = &orm{ds: db, lggr: lggr} - ctx, cancel = context.WithCancel(testutils.Context(t)) - reader = NewMockContractReader(t) - emitter = custmsg.NewLabeler() - gateway = func(_ context.Context, _ string) ([]byte, error) { - return []byte(wantContents), nil - } - ticker = make(chan time.Time) - - handler = NewEventHandler(lggr, orm, gateway, nil, nil, - emitter, clockwork.NewFakeClock(), workflowkey.Key{}) - loader = NewWorkflowRegistryContractLoader(lggr, contractAddress, func(ctx context.Context, bytes []byte) (ContractReader, error) { - return reader, nil - }, handler) - - worker = NewWorkflowRegistry(lggr, func(ctx context.Context, bytes []byte) (ContractReader, error) { - return reader, nil - }, contractAddress, - WorkflowEventPollerConfig{ - QueryCount: 20, - }, handler, loader, - &testDonNotifier{ - don: capabilities.DON{ - ID: 1, - }, - err: nil, - }, - WithTicker(ticker)) - ) - - // Cleanup the worker - defer cancel() - - // Seed the DB with an original entry - _, err = orm.Create(ctx, giveURL, hex.EncodeToString(giveHash), giveContents) - require.NoError(t, err) - - // Mock out the contract reader query - reader.EXPECT().QueryKey( - matches.AnyContext, - types.BoundContract{ - Name: WorkflowRegistryContractName, - Address: contractAddress, - }, - query.KeyFilter{ - Key: string(ForceUpdateSecretsEvent), - Expressions: []query.Expression{ - query.Confidence(primitives.Finalized), - query.Block("0", primitives.Gt), - }, - }, - query.LimitAndSort{ - SortBy: []query.SortBy{query.NewSortByTimestamp(query.Asc)}, - Limit: query.Limit{Count: giveCfg.QueryCount}, - }, - new(values.Value), - ).Return([]types.Sequence{giveLog}, nil) - reader.EXPECT().GetLatestValueWithHeadData(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(&types.Head{ - Height: "0", - }, nil) - reader.EXPECT().Bind(mock.Anything, mock.Anything).Return(nil) - - // Go run the worker - servicetest.Run(t, worker) - - // Send a tick to start a query - ticker <- time.Now() - - // Require the secrets contents to eventually be updated - require.Eventually(t, func() bool { - secrets, err := orm.GetContents(ctx, giveURL) - require.NoError(t, err) - return secrets == wantContents - }, 5*time.Second, time.Second) -} diff --git a/core/web/assets/index.html b/core/web/assets/index.html index 6e2fd9cf254..ae1aac9ede0 100644 --- a/core/web/assets/index.html +++ b/core/web/assets/index.html @@ -1 +1 @@ -Operator UIChainlink
\ No newline at end of file +Operator UIChainlink
\ No newline at end of file diff --git a/core/web/assets/index.html.gz b/core/web/assets/index.html.gz index 9d9d6b9151f..a65173c97c8 100644 Binary files a/core/web/assets/index.html.gz and b/core/web/assets/index.html.gz differ diff --git a/core/web/assets/main.ec7b7e88c8c965c1e482.js b/core/web/assets/main.008c37495ba29761321d.js similarity index 90% rename from core/web/assets/main.ec7b7e88c8c965c1e482.js rename to core/web/assets/main.008c37495ba29761321d.js index 5640ce7c29e..b9feeec3d83 100644 --- a/core/web/assets/main.ec7b7e88c8c965c1e482.js +++ b/core/web/assets/main.008c37495ba29761321d.js @@ -171,4 +171,4 @@ object-assign */ Object.defineProperty(t,"__esModule",{value:!0}),"undefined"==typeof window||"function"!=typeof MessageChannel){var n,r,i,a,o,s=null,u=null,c=function(){if(null!==s)try{var e=t.unstable_now();s(!0,e),s=null}catch(n){throw setTimeout(c,0),n}},l=Date.now();t.unstable_now=function(){return Date.now()-l},n=function(e){null!==s?setTimeout(n,0,e):(s=e,setTimeout(c,0))},r=function(e,t){u=setTimeout(e,t)},i=function(){clearTimeout(u)},a=function(){return!1},o=t.unstable_forceFrameRate=function(){}}else{var f=window.performance,d=window.Date,h=window.setTimeout,p=window.clearTimeout;if("undefined"!=typeof console){var b=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof b&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")}if("object"==typeof f&&"function"==typeof f.now)t.unstable_now=function(){return f.now()};else{var m=d.now();t.unstable_now=function(){return d.now()-m}}var g=!1,v=null,y=-1,w=5,_=0;a=function(){return t.unstable_now()>=_},o=function(){},t.unstable_forceFrameRate=function(e){0>e||125M(o,n))void 0!==u&&0>M(u,o)?(e[r]=u,e[s]=n,r=s):(e[r]=o,e[a]=n,r=a);else if(void 0!==u&&0>M(u,n))e[r]=u,e[s]=n,r=s;else break a}}return t}return null}function M(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var O=[],A=[],L=1,C=null,I=3,D=!1,N=!1,P=!1;function R(e){for(var t=x(A);null!==t;){if(null===t.callback)T(A);else if(t.startTime<=e)T(A),t.sortIndex=t.expirationTime,k(O,t);else break;t=x(A)}}function j(e){if(P=!1,R(e),!N){if(null!==x(O))N=!0,n(F);else{var t=x(A);null!==t&&r(j,t.startTime-e)}}}function F(e,n){N=!1,P&&(P=!1,i()),D=!0;var o=I;try{for(R(n),C=x(O);null!==C&&(!(C.expirationTime>n)||e&&!a());){var s=C.callback;if(null!==s){C.callback=null,I=C.priorityLevel;var u=s(C.expirationTime<=n);n=t.unstable_now(),"function"==typeof u?C.callback=u:C===x(O)&&T(O),R(n)}else T(O);C=x(O)}if(null!==C)var c=!0;else{var l=x(A);null!==l&&r(j,l.startTime-n),c=!1}return c}finally{C=null,I=o,D=!1}}function Y(e){switch(e){case 1:return -1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var B=o;t.unstable_ImmediatePriority=1,t.unstable_UserBlockingPriority=2,t.unstable_NormalPriority=3,t.unstable_IdlePriority=5,t.unstable_LowPriority=4,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=I;I=e;try{return t()}finally{I=n}},t.unstable_next=function(e){switch(I){case 1:case 2:case 3:var t=3;break;default:t=I}var n=I;I=t;try{return e()}finally{I=n}},t.unstable_scheduleCallback=function(e,a,o){var s=t.unstable_now();if("object"==typeof o&&null!==o){var u=o.delay;u="number"==typeof u&&0s?(e.sortIndex=u,k(A,e),null===x(O)&&e===x(A)&&(P?i():P=!0,r(j,u-s))):(e.sortIndex=o,k(O,e),N||D||(N=!0,n(F))),e},t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_wrapCallback=function(e){var t=I;return function(){var n=I;I=t;try{return e.apply(this,arguments)}finally{I=n}}},t.unstable_getCurrentPriorityLevel=function(){return I},t.unstable_shouldYield=function(){var e=t.unstable_now();R(e);var n=x(O);return n!==C&&null!==C&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function c(e,t,n){var r=t.length-1;if(r=0?(i>0&&(e.lastNeed=i-1),i):--r=0?(i>0&&(e.lastNeed=i-2),i):--r=0?(i>0&&(2===i?i=0:e.lastNeed=i-3),i):0}function l(e,t,n){if((192&t[0])!=128)return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if((192&t[1])!=128)return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&(192&t[2])!=128)return e.lastNeed=2,"�"}}function f(e){var t=this.lastTotal-this.lastNeed,n=l(this,e,t);return void 0!==n?n:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):void(e.copy(this.lastChar,t,0,e.length),this.lastNeed-=e.length)}function d(e,t){var n=c(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=n;var r=e.length-(n-this.lastNeed);return e.copy(this.lastChar,0,r),e.toString("utf8",t,r)}function h(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+"�":t}function p(e,t){if((e.length-t)%2==0){var n=e.toString("utf16le",t);if(n){var r=n.charCodeAt(n.length-1);if(r>=55296&&r<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function b(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,n)}return t}function m(e,t){var n=(e.length-t)%3;return 0===n?e.toString("base64",t):(this.lastNeed=3-n,this.lastTotal=3,1===n?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-n))}function g(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function v(e){return e.toString(this.encoding)}function y(e){return e&&e.length?this.write(e):""}t.s=s,s.prototype.write=function(e){var t,n;if(0===e.length)return"";if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";n=this.lastNeed,this.lastNeed=0}else n=0;return n */ var r=n(48764),i=r.Buffer;function a(e,t){for(var n in e)t[n]=e[n]}function o(e,t,n){return i(e,t,n)}i.from&&i.alloc&&i.allocUnsafe&&i.allocUnsafeSlow?e.exports=r:(a(r,t),t.Buffer=o),o.prototype=Object.create(i.prototype),a(i,o),o.from=function(e,t,n){if("number"==typeof e)throw TypeError("Argument must not be a number");return i(e,t,n)},o.alloc=function(e,t,n){if("number"!=typeof e)throw TypeError("Argument must be a number");var r=i(e);return void 0!==t?"string"==typeof n?r.fill(t,n):r.fill(t):r.fill(0),r},o.allocUnsafe=function(e){if("number"!=typeof e)throw TypeError("Argument must be a number");return i(e)},o.allocUnsafeSlow=function(e){if("number"!=typeof e)throw TypeError("Argument must be a number");return r.SlowBuffer(e)}},93379(e,t,n){"use strict";var r,i,a=function(){return void 0===r&&(r=Boolean(window&&document&&document.all&&!window.atob)),r},o=(i={},function(e){if(void 0===i[e]){var t=document.querySelector(e);if(window.HTMLIFrameElement&&t instanceof window.HTMLIFrameElement)try{t=t.contentDocument.head}catch(n){t=null}i[e]=t}return i[e]}),s=[];function u(e){for(var t=-1,n=0;nAp});var r,i,a,o,s,u,c,l=n(67294),f=n.t(l,2),d=n(39814),h=n(5977),p=n(57209),b=n(32316),m=n(95880),g=n(17051),v=n(71381),y=n(81701),w=n(3022),_=n(60323),E=n(87591),S=n(25649),k=n(28902),x=n(71426),T=n(48884),M=n(94184),O=n.n(M),A=n(37703),L=n(73935),C=function(){if("undefined"!=typeof Map)return Map;function e(e,t){var n=-1;return e.some(function(e,r){return e[0]===t&&(n=r,!0)}),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(t){var n=e(this.__entries__,t),r=this.__entries__[n];return r&&r[1]},t.prototype.set=function(t,n){var r=e(this.__entries__,t);~r?this.__entries__[r][1]=n:this.__entries__.push([t,n])},t.prototype.delete=function(t){var n=this.__entries__,r=e(n,t);~r&&n.splice(r,1)},t.prototype.has=function(t){return!!~e(this.__entries__,t)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(e,t){void 0===t&&(t=null);for(var n=0,r=this.__entries__;n0},e.prototype.connect_=function(){I&&!this.connected_&&(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),Y?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){I&&this.connected_&&(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(e){var t=e.propertyName,n=void 0===t?"":t;F.some(function(e){return!!~n.indexOf(e)})&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),U=function(e,t){for(var n=0,r=Object.keys(t);n0},e}(),er="undefined"!=typeof WeakMap?new WeakMap:new C,ei=function(){function e(t){if(!(this instanceof e))throw TypeError("Cannot call a class as a function.");if(!arguments.length)throw TypeError("1 argument required, but only 0 present.");var n=B.getInstance(),r=new en(t,n,this);er.set(this,r)}return e}();["observe","unobserve","disconnect"].forEach(function(e){ei.prototype[e]=function(){var t;return(t=er.get(this))[e].apply(t,arguments)}});var ea=void 0!==D.ResizeObserver?D.ResizeObserver:ei;let eo=ea;var es=function(e){var t=[],n=null,r=function(){for(var r=arguments.length,i=Array(r),a=0;a=t||n<0||f&&r>=a}function g(){var e=eb();if(m(e))return v(e);s=setTimeout(g,b(e))}function v(e){return(s=void 0,d&&r)?h(e):(r=i=void 0,o)}function y(){void 0!==s&&clearTimeout(s),c=0,r=u=i=s=void 0}function w(){return void 0===s?o:v(eb())}function _(){var e=eb(),n=m(e);if(r=arguments,i=this,u=e,n){if(void 0===s)return p(u);if(f)return clearTimeout(s),s=setTimeout(g,t),h(u)}return void 0===s&&(s=setTimeout(g,t)),o}return t=ez(t)||0,ed(n)&&(l=!!n.leading,a=(f="maxWait"in n)?eW(ez(n.maxWait)||0,t):a,d="trailing"in n?!!n.trailing:d),_.cancel=y,_.flush=w,_}let eq=eV;var eZ="Expected a function";function eX(e,t,n){var r=!0,i=!0;if("function"!=typeof e)throw TypeError(eZ);return ed(n)&&(r="leading"in n?!!n.leading:r,i="trailing"in n?!!n.trailing:i),eq(e,t,{leading:r,maxWait:t,trailing:i})}let eJ=eX;var eQ={debounce:eq,throttle:eJ},e1=function(e){return eQ[e]},e0=function(e){return"function"==typeof e},e2=function(){return"undefined"==typeof window},e3=function(e){return e instanceof Element||e instanceof HTMLDocument};function e4(e){return(e4="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function e6(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}function e5(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&l.createElement(tG.Z,{variant:"indeterminate",classes:r}))};tK.propTypes={fetchCount:el().number.isRequired};let tV=(0,b.withStyles)(tW)(tK);var tq=n(5536);let tZ=n.p+"ba8bbf16ebf8e1d05bef.svg";function tX(){return(tX=Object.assign||function(e){for(var t=1;t120){for(var d=Math.floor(u/80),h=u%80,p=[],b=0;b0},name:{enumerable:!1},nodes:{enumerable:!1},source:{enumerable:!1},positions:{enumerable:!1},originalError:{enumerable:!1}}),null!=s&&s.stack)?(Object.defineProperty(nf(b),"stack",{value:s.stack,writable:!0,configurable:!0}),nl(b)):(Error.captureStackTrace?Error.captureStackTrace(nf(b),n):Object.defineProperty(nf(b),"stack",{value:Error().stack,writable:!0,configurable:!0}),b)}return ns(n,[{key:"toString",value:function(){return nw(this)}},{key:t4.YF,get:function(){return"Object"}}]),n}(nd(Error));function ny(e){return void 0===e||0===e.length?void 0:e}function nw(e){var t=e.message;if(e.nodes)for(var n=0,r=e.nodes;n",EOF:"",BANG:"!",DOLLAR:"$",AMP:"&",PAREN_L:"(",PAREN_R:")",SPREAD:"...",COLON:":",EQUALS:"=",AT:"@",BRACKET_L:"[",BRACKET_R:"]",BRACE_L:"{",PIPE:"|",BRACE_R:"}",NAME:"Name",INT:"Int",FLOAT:"Float",STRING:"String",BLOCK_STRING:"BlockString",COMMENT:"Comment"}),nx=n(10143),nT=Object.freeze({QUERY:"QUERY",MUTATION:"MUTATION",SUBSCRIPTION:"SUBSCRIPTION",FIELD:"FIELD",FRAGMENT_DEFINITION:"FRAGMENT_DEFINITION",FRAGMENT_SPREAD:"FRAGMENT_SPREAD",INLINE_FRAGMENT:"INLINE_FRAGMENT",VARIABLE_DEFINITION:"VARIABLE_DEFINITION",SCHEMA:"SCHEMA",SCALAR:"SCALAR",OBJECT:"OBJECT",FIELD_DEFINITION:"FIELD_DEFINITION",ARGUMENT_DEFINITION:"ARGUMENT_DEFINITION",INTERFACE:"INTERFACE",UNION:"UNION",ENUM:"ENUM",ENUM_VALUE:"ENUM_VALUE",INPUT_OBJECT:"INPUT_OBJECT",INPUT_FIELD_DEFINITION:"INPUT_FIELD_DEFINITION"}),nM=n(87392),nO=function(){function e(e){var t=new nS.WU(nk.SOF,0,0,0,0,null);this.source=e,this.lastToken=t,this.token=t,this.line=1,this.lineStart=0}var t=e.prototype;return t.advance=function(){return this.lastToken=this.token,this.token=this.lookahead()},t.lookahead=function(){var e,t=this.token;if(t.kind!==nk.EOF)do t=null!==(e=t.next)&&void 0!==e?e:t.next=nC(this,t);while(t.kind===nk.COMMENT)return t},e}();function nA(e){return e===nk.BANG||e===nk.DOLLAR||e===nk.AMP||e===nk.PAREN_L||e===nk.PAREN_R||e===nk.SPREAD||e===nk.COLON||e===nk.EQUALS||e===nk.AT||e===nk.BRACKET_L||e===nk.BRACKET_R||e===nk.BRACE_L||e===nk.PIPE||e===nk.BRACE_R}function nL(e){return isNaN(e)?nk.EOF:e<127?JSON.stringify(String.fromCharCode(e)):'"\\u'.concat(("00"+e.toString(16).toUpperCase()).slice(-4),'"')}function nC(e,t){for(var n=e.source,r=n.body,i=r.length,a=t.end;a31||9===a))return new nS.WU(nk.COMMENT,t,s,n,r,i,o.slice(t+1,s))}function nN(e,t,n,r,i,a){var o=e.body,s=n,u=t,c=!1;if(45===s&&(s=o.charCodeAt(++u)),48===s){if((s=o.charCodeAt(++u))>=48&&s<=57)throw n_(e,u,"Invalid number, unexpected digit after 0: ".concat(nL(s),"."))}else u=nP(e,u,s),s=o.charCodeAt(u);if(46===s&&(c=!0,s=o.charCodeAt(++u),u=nP(e,u,s),s=o.charCodeAt(u)),(69===s||101===s)&&(c=!0,(43===(s=o.charCodeAt(++u))||45===s)&&(s=o.charCodeAt(++u)),u=nP(e,u,s),s=o.charCodeAt(u)),46===s||nU(s))throw n_(e,u,"Invalid number, expected digit but got: ".concat(nL(s),"."));return new nS.WU(c?nk.FLOAT:nk.INT,t,u,r,i,a,o.slice(t,u))}function nP(e,t,n){var r=e.body,i=t,a=n;if(a>=48&&a<=57){do a=r.charCodeAt(++i);while(a>=48&&a<=57)return i}throw n_(e,i,"Invalid number, expected digit but got: ".concat(nL(a),"."))}function nR(e,t,n,r,i){for(var a=e.body,o=t+1,s=o,u=0,c="";o=48&&e<=57?e-48:e>=65&&e<=70?e-55:e>=97&&e<=102?e-87:-1}function nB(e,t,n,r,i){for(var a=e.body,o=a.length,s=t+1,u=0;s!==o&&!isNaN(u=a.charCodeAt(s))&&(95===u||u>=48&&u<=57||u>=65&&u<=90||u>=97&&u<=122);)++s;return new nS.WU(nk.NAME,t,s,n,r,i,a.slice(t,s))}function nU(e){return 95===e||e>=65&&e<=90||e>=97&&e<=122}function nH(e,t){return new n$(e,t).parseDocument()}var n$=function(){function e(e,t){var n=(0,nx.T)(e)?e:new nx.H(e);this._lexer=new nO(n),this._options=t}var t=e.prototype;return t.parseName=function(){var e=this.expectToken(nk.NAME);return{kind:nE.h.NAME,value:e.value,loc:this.loc(e)}},t.parseDocument=function(){var e=this._lexer.token;return{kind:nE.h.DOCUMENT,definitions:this.many(nk.SOF,this.parseDefinition,nk.EOF),loc:this.loc(e)}},t.parseDefinition=function(){if(this.peek(nk.NAME))switch(this._lexer.token.value){case"query":case"mutation":case"subscription":return this.parseOperationDefinition();case"fragment":return this.parseFragmentDefinition();case"schema":case"scalar":case"type":case"interface":case"union":case"enum":case"input":case"directive":return this.parseTypeSystemDefinition();case"extend":return this.parseTypeSystemExtension()}else if(this.peek(nk.BRACE_L))return this.parseOperationDefinition();else if(this.peekDescription())return this.parseTypeSystemDefinition();throw this.unexpected()},t.parseOperationDefinition=function(){var e,t=this._lexer.token;if(this.peek(nk.BRACE_L))return{kind:nE.h.OPERATION_DEFINITION,operation:"query",name:void 0,variableDefinitions:[],directives:[],selectionSet:this.parseSelectionSet(),loc:this.loc(t)};var n=this.parseOperationType();return this.peek(nk.NAME)&&(e=this.parseName()),{kind:nE.h.OPERATION_DEFINITION,operation:n,name:e,variableDefinitions:this.parseVariableDefinitions(),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}},t.parseOperationType=function(){var e=this.expectToken(nk.NAME);switch(e.value){case"query":return"query";case"mutation":return"mutation";case"subscription":return"subscription"}throw this.unexpected(e)},t.parseVariableDefinitions=function(){return this.optionalMany(nk.PAREN_L,this.parseVariableDefinition,nk.PAREN_R)},t.parseVariableDefinition=function(){var e=this._lexer.token;return{kind:nE.h.VARIABLE_DEFINITION,variable:this.parseVariable(),type:(this.expectToken(nk.COLON),this.parseTypeReference()),defaultValue:this.expectOptionalToken(nk.EQUALS)?this.parseValueLiteral(!0):void 0,directives:this.parseDirectives(!0),loc:this.loc(e)}},t.parseVariable=function(){var e=this._lexer.token;return this.expectToken(nk.DOLLAR),{kind:nE.h.VARIABLE,name:this.parseName(),loc:this.loc(e)}},t.parseSelectionSet=function(){var e=this._lexer.token;return{kind:nE.h.SELECTION_SET,selections:this.many(nk.BRACE_L,this.parseSelection,nk.BRACE_R),loc:this.loc(e)}},t.parseSelection=function(){return this.peek(nk.SPREAD)?this.parseFragment():this.parseField()},t.parseField=function(){var e,t,n=this._lexer.token,r=this.parseName();return this.expectOptionalToken(nk.COLON)?(e=r,t=this.parseName()):t=r,{kind:nE.h.FIELD,alias:e,name:t,arguments:this.parseArguments(!1),directives:this.parseDirectives(!1),selectionSet:this.peek(nk.BRACE_L)?this.parseSelectionSet():void 0,loc:this.loc(n)}},t.parseArguments=function(e){var t=e?this.parseConstArgument:this.parseArgument;return this.optionalMany(nk.PAREN_L,t,nk.PAREN_R)},t.parseArgument=function(){var e=this._lexer.token,t=this.parseName();return this.expectToken(nk.COLON),{kind:nE.h.ARGUMENT,name:t,value:this.parseValueLiteral(!1),loc:this.loc(e)}},t.parseConstArgument=function(){var e=this._lexer.token;return{kind:nE.h.ARGUMENT,name:this.parseName(),value:(this.expectToken(nk.COLON),this.parseValueLiteral(!0)),loc:this.loc(e)}},t.parseFragment=function(){var e=this._lexer.token;this.expectToken(nk.SPREAD);var t=this.expectOptionalKeyword("on");return!t&&this.peek(nk.NAME)?{kind:nE.h.FRAGMENT_SPREAD,name:this.parseFragmentName(),directives:this.parseDirectives(!1),loc:this.loc(e)}:{kind:nE.h.INLINE_FRAGMENT,typeCondition:t?this.parseNamedType():void 0,directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(e)}},t.parseFragmentDefinition=function(){var e,t=this._lexer.token;return(this.expectKeyword("fragment"),(null===(e=this._options)||void 0===e?void 0:e.experimentalFragmentVariables)===!0)?{kind:nE.h.FRAGMENT_DEFINITION,name:this.parseFragmentName(),variableDefinitions:this.parseVariableDefinitions(),typeCondition:(this.expectKeyword("on"),this.parseNamedType()),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}:{kind:nE.h.FRAGMENT_DEFINITION,name:this.parseFragmentName(),typeCondition:(this.expectKeyword("on"),this.parseNamedType()),directives:this.parseDirectives(!1),selectionSet:this.parseSelectionSet(),loc:this.loc(t)}},t.parseFragmentName=function(){if("on"===this._lexer.token.value)throw this.unexpected();return this.parseName()},t.parseValueLiteral=function(e){var t=this._lexer.token;switch(t.kind){case nk.BRACKET_L:return this.parseList(e);case nk.BRACE_L:return this.parseObject(e);case nk.INT:return this._lexer.advance(),{kind:nE.h.INT,value:t.value,loc:this.loc(t)};case nk.FLOAT:return this._lexer.advance(),{kind:nE.h.FLOAT,value:t.value,loc:this.loc(t)};case nk.STRING:case nk.BLOCK_STRING:return this.parseStringLiteral();case nk.NAME:switch(this._lexer.advance(),t.value){case"true":return{kind:nE.h.BOOLEAN,value:!0,loc:this.loc(t)};case"false":return{kind:nE.h.BOOLEAN,value:!1,loc:this.loc(t)};case"null":return{kind:nE.h.NULL,loc:this.loc(t)};default:return{kind:nE.h.ENUM,value:t.value,loc:this.loc(t)}}case nk.DOLLAR:if(!e)return this.parseVariable()}throw this.unexpected()},t.parseStringLiteral=function(){var e=this._lexer.token;return this._lexer.advance(),{kind:nE.h.STRING,value:e.value,block:e.kind===nk.BLOCK_STRING,loc:this.loc(e)}},t.parseList=function(e){var t=this,n=this._lexer.token,r=function(){return t.parseValueLiteral(e)};return{kind:nE.h.LIST,values:this.any(nk.BRACKET_L,r,nk.BRACKET_R),loc:this.loc(n)}},t.parseObject=function(e){var t=this,n=this._lexer.token,r=function(){return t.parseObjectField(e)};return{kind:nE.h.OBJECT,fields:this.any(nk.BRACE_L,r,nk.BRACE_R),loc:this.loc(n)}},t.parseObjectField=function(e){var t=this._lexer.token,n=this.parseName();return this.expectToken(nk.COLON),{kind:nE.h.OBJECT_FIELD,name:n,value:this.parseValueLiteral(e),loc:this.loc(t)}},t.parseDirectives=function(e){for(var t=[];this.peek(nk.AT);)t.push(this.parseDirective(e));return t},t.parseDirective=function(e){var t=this._lexer.token;return this.expectToken(nk.AT),{kind:nE.h.DIRECTIVE,name:this.parseName(),arguments:this.parseArguments(e),loc:this.loc(t)}},t.parseTypeReference=function(){var e,t=this._lexer.token;return(this.expectOptionalToken(nk.BRACKET_L)?(e=this.parseTypeReference(),this.expectToken(nk.BRACKET_R),e={kind:nE.h.LIST_TYPE,type:e,loc:this.loc(t)}):e=this.parseNamedType(),this.expectOptionalToken(nk.BANG))?{kind:nE.h.NON_NULL_TYPE,type:e,loc:this.loc(t)}:e},t.parseNamedType=function(){var e=this._lexer.token;return{kind:nE.h.NAMED_TYPE,name:this.parseName(),loc:this.loc(e)}},t.parseTypeSystemDefinition=function(){var e=this.peekDescription()?this._lexer.lookahead():this._lexer.token;if(e.kind===nk.NAME)switch(e.value){case"schema":return this.parseSchemaDefinition();case"scalar":return this.parseScalarTypeDefinition();case"type":return this.parseObjectTypeDefinition();case"interface":return this.parseInterfaceTypeDefinition();case"union":return this.parseUnionTypeDefinition();case"enum":return this.parseEnumTypeDefinition();case"input":return this.parseInputObjectTypeDefinition();case"directive":return this.parseDirectiveDefinition()}throw this.unexpected(e)},t.peekDescription=function(){return this.peek(nk.STRING)||this.peek(nk.BLOCK_STRING)},t.parseDescription=function(){if(this.peekDescription())return this.parseStringLiteral()},t.parseSchemaDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("schema");var n=this.parseDirectives(!0),r=this.many(nk.BRACE_L,this.parseOperationTypeDefinition,nk.BRACE_R);return{kind:nE.h.SCHEMA_DEFINITION,description:t,directives:n,operationTypes:r,loc:this.loc(e)}},t.parseOperationTypeDefinition=function(){var e=this._lexer.token,t=this.parseOperationType();this.expectToken(nk.COLON);var n=this.parseNamedType();return{kind:nE.h.OPERATION_TYPE_DEFINITION,operation:t,type:n,loc:this.loc(e)}},t.parseScalarTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("scalar");var n=this.parseName(),r=this.parseDirectives(!0);return{kind:nE.h.SCALAR_TYPE_DEFINITION,description:t,name:n,directives:r,loc:this.loc(e)}},t.parseObjectTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("type");var n=this.parseName(),r=this.parseImplementsInterfaces(),i=this.parseDirectives(!0),a=this.parseFieldsDefinition();return{kind:nE.h.OBJECT_TYPE_DEFINITION,description:t,name:n,interfaces:r,directives:i,fields:a,loc:this.loc(e)}},t.parseImplementsInterfaces=function(){var e;if(!this.expectOptionalKeyword("implements"))return[];if((null===(e=this._options)||void 0===e?void 0:e.allowLegacySDLImplementsInterfaces)===!0){var t=[];this.expectOptionalToken(nk.AMP);do t.push(this.parseNamedType());while(this.expectOptionalToken(nk.AMP)||this.peek(nk.NAME))return t}return this.delimitedMany(nk.AMP,this.parseNamedType)},t.parseFieldsDefinition=function(){var e;return(null===(e=this._options)||void 0===e?void 0:e.allowLegacySDLEmptyFields)===!0&&this.peek(nk.BRACE_L)&&this._lexer.lookahead().kind===nk.BRACE_R?(this._lexer.advance(),this._lexer.advance(),[]):this.optionalMany(nk.BRACE_L,this.parseFieldDefinition,nk.BRACE_R)},t.parseFieldDefinition=function(){var e=this._lexer.token,t=this.parseDescription(),n=this.parseName(),r=this.parseArgumentDefs();this.expectToken(nk.COLON);var i=this.parseTypeReference(),a=this.parseDirectives(!0);return{kind:nE.h.FIELD_DEFINITION,description:t,name:n,arguments:r,type:i,directives:a,loc:this.loc(e)}},t.parseArgumentDefs=function(){return this.optionalMany(nk.PAREN_L,this.parseInputValueDef,nk.PAREN_R)},t.parseInputValueDef=function(){var e,t=this._lexer.token,n=this.parseDescription(),r=this.parseName();this.expectToken(nk.COLON);var i=this.parseTypeReference();this.expectOptionalToken(nk.EQUALS)&&(e=this.parseValueLiteral(!0));var a=this.parseDirectives(!0);return{kind:nE.h.INPUT_VALUE_DEFINITION,description:n,name:r,type:i,defaultValue:e,directives:a,loc:this.loc(t)}},t.parseInterfaceTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("interface");var n=this.parseName(),r=this.parseImplementsInterfaces(),i=this.parseDirectives(!0),a=this.parseFieldsDefinition();return{kind:nE.h.INTERFACE_TYPE_DEFINITION,description:t,name:n,interfaces:r,directives:i,fields:a,loc:this.loc(e)}},t.parseUnionTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("union");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseUnionMemberTypes();return{kind:nE.h.UNION_TYPE_DEFINITION,description:t,name:n,directives:r,types:i,loc:this.loc(e)}},t.parseUnionMemberTypes=function(){return this.expectOptionalToken(nk.EQUALS)?this.delimitedMany(nk.PIPE,this.parseNamedType):[]},t.parseEnumTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("enum");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseEnumValuesDefinition();return{kind:nE.h.ENUM_TYPE_DEFINITION,description:t,name:n,directives:r,values:i,loc:this.loc(e)}},t.parseEnumValuesDefinition=function(){return this.optionalMany(nk.BRACE_L,this.parseEnumValueDefinition,nk.BRACE_R)},t.parseEnumValueDefinition=function(){var e=this._lexer.token,t=this.parseDescription(),n=this.parseName(),r=this.parseDirectives(!0);return{kind:nE.h.ENUM_VALUE_DEFINITION,description:t,name:n,directives:r,loc:this.loc(e)}},t.parseInputObjectTypeDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("input");var n=this.parseName(),r=this.parseDirectives(!0),i=this.parseInputFieldsDefinition();return{kind:nE.h.INPUT_OBJECT_TYPE_DEFINITION,description:t,name:n,directives:r,fields:i,loc:this.loc(e)}},t.parseInputFieldsDefinition=function(){return this.optionalMany(nk.BRACE_L,this.parseInputValueDef,nk.BRACE_R)},t.parseTypeSystemExtension=function(){var e=this._lexer.lookahead();if(e.kind===nk.NAME)switch(e.value){case"schema":return this.parseSchemaExtension();case"scalar":return this.parseScalarTypeExtension();case"type":return this.parseObjectTypeExtension();case"interface":return this.parseInterfaceTypeExtension();case"union":return this.parseUnionTypeExtension();case"enum":return this.parseEnumTypeExtension();case"input":return this.parseInputObjectTypeExtension()}throw this.unexpected(e)},t.parseSchemaExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("schema");var t=this.parseDirectives(!0),n=this.optionalMany(nk.BRACE_L,this.parseOperationTypeDefinition,nk.BRACE_R);if(0===t.length&&0===n.length)throw this.unexpected();return{kind:nE.h.SCHEMA_EXTENSION,directives:t,operationTypes:n,loc:this.loc(e)}},t.parseScalarTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("scalar");var t=this.parseName(),n=this.parseDirectives(!0);if(0===n.length)throw this.unexpected();return{kind:nE.h.SCALAR_TYPE_EXTENSION,name:t,directives:n,loc:this.loc(e)}},t.parseObjectTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("type");var t=this.parseName(),n=this.parseImplementsInterfaces(),r=this.parseDirectives(!0),i=this.parseFieldsDefinition();if(0===n.length&&0===r.length&&0===i.length)throw this.unexpected();return{kind:nE.h.OBJECT_TYPE_EXTENSION,name:t,interfaces:n,directives:r,fields:i,loc:this.loc(e)}},t.parseInterfaceTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("interface");var t=this.parseName(),n=this.parseImplementsInterfaces(),r=this.parseDirectives(!0),i=this.parseFieldsDefinition();if(0===n.length&&0===r.length&&0===i.length)throw this.unexpected();return{kind:nE.h.INTERFACE_TYPE_EXTENSION,name:t,interfaces:n,directives:r,fields:i,loc:this.loc(e)}},t.parseUnionTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("union");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseUnionMemberTypes();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.UNION_TYPE_EXTENSION,name:t,directives:n,types:r,loc:this.loc(e)}},t.parseEnumTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("enum");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseEnumValuesDefinition();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.ENUM_TYPE_EXTENSION,name:t,directives:n,values:r,loc:this.loc(e)}},t.parseInputObjectTypeExtension=function(){var e=this._lexer.token;this.expectKeyword("extend"),this.expectKeyword("input");var t=this.parseName(),n=this.parseDirectives(!0),r=this.parseInputFieldsDefinition();if(0===n.length&&0===r.length)throw this.unexpected();return{kind:nE.h.INPUT_OBJECT_TYPE_EXTENSION,name:t,directives:n,fields:r,loc:this.loc(e)}},t.parseDirectiveDefinition=function(){var e=this._lexer.token,t=this.parseDescription();this.expectKeyword("directive"),this.expectToken(nk.AT);var n=this.parseName(),r=this.parseArgumentDefs(),i=this.expectOptionalKeyword("repeatable");this.expectKeyword("on");var a=this.parseDirectiveLocations();return{kind:nE.h.DIRECTIVE_DEFINITION,description:t,name:n,arguments:r,repeatable:i,locations:a,loc:this.loc(e)}},t.parseDirectiveLocations=function(){return this.delimitedMany(nk.PIPE,this.parseDirectiveLocation)},t.parseDirectiveLocation=function(){var e=this._lexer.token,t=this.parseName();if(void 0!==nT[t.value])return t;throw this.unexpected(e)},t.loc=function(e){var t;if((null===(t=this._options)||void 0===t?void 0:t.noLocation)!==!0)return new nS.Ye(e,this._lexer.lastToken,this._lexer.source)},t.peek=function(e){return this._lexer.token.kind===e},t.expectToken=function(e){var t=this._lexer.token;if(t.kind===e)return this._lexer.advance(),t;throw n_(this._lexer.source,t.start,"Expected ".concat(nG(e),", found ").concat(nz(t),"."))},t.expectOptionalToken=function(e){var t=this._lexer.token;if(t.kind===e)return this._lexer.advance(),t},t.expectKeyword=function(e){var t=this._lexer.token;if(t.kind===nk.NAME&&t.value===e)this._lexer.advance();else throw n_(this._lexer.source,t.start,'Expected "'.concat(e,'", found ').concat(nz(t),"."))},t.expectOptionalKeyword=function(e){var t=this._lexer.token;return t.kind===nk.NAME&&t.value===e&&(this._lexer.advance(),!0)},t.unexpected=function(e){var t=null!=e?e:this._lexer.token;return n_(this._lexer.source,t.start,"Unexpected ".concat(nz(t),"."))},t.any=function(e,t,n){this.expectToken(e);for(var r=[];!this.expectOptionalToken(n);)r.push(t.call(this));return r},t.optionalMany=function(e,t,n){if(this.expectOptionalToken(e)){var r=[];do r.push(t.call(this));while(!this.expectOptionalToken(n))return r}return[]},t.many=function(e,t,n){this.expectToken(e);var r=[];do r.push(t.call(this));while(!this.expectOptionalToken(n))return r},t.delimitedMany=function(e,t){this.expectOptionalToken(e);var n=[];do n.push(t.call(this));while(this.expectOptionalToken(e))return n},e}();function nz(e){var t=e.value;return nG(e.kind)+(null!=t?' "'.concat(t,'"'):"")}function nG(e){return nA(e)?'"'.concat(e,'"'):e}var nW=new Map,nK=new Map,nV=!0,nq=!1;function nZ(e){return e.replace(/[\s,]+/g," ").trim()}function nX(e){return nZ(e.source.body.substring(e.start,e.end))}function nJ(e){var t=new Set,n=[];return e.definitions.forEach(function(e){if("FragmentDefinition"===e.kind){var r=e.name.value,i=nX(e.loc),a=nK.get(r);a&&!a.has(i)?nV&&console.warn("Warning: fragment with name "+r+" already exists.\ngraphql-tag enforces all fragment names across your application to be unique; read more about\nthis in the docs: http://dev.apollodata.com/core/fragments.html#unique-names"):a||nK.set(r,a=new Set),a.add(i),t.has(i)||(t.add(i),n.push(e))}else n.push(e)}),(0,t0.pi)((0,t0.pi)({},e),{definitions:n})}function nQ(e){var t=new Set(e.definitions);t.forEach(function(e){e.loc&&delete e.loc,Object.keys(e).forEach(function(n){var r=e[n];r&&"object"==typeof r&&t.add(r)})});var n=e.loc;return n&&(delete n.startToken,delete n.endToken),e}function n1(e){var t=nZ(e);if(!nW.has(t)){var n=nH(e,{experimentalFragmentVariables:nq,allowLegacyFragmentVariables:nq});if(!n||"Document"!==n.kind)throw Error("Not a valid GraphQL document.");nW.set(t,nQ(nJ(n)))}return nW.get(t)}function n0(e){for(var t=[],n=1;n, or pass an ApolloClient instance in via options.'):(0,n9.kG)(!!n,32),n}var rp=n(10542),rb=n(53712),rm=n(21436),rg=Object.prototype.hasOwnProperty;function rv(e,t){return void 0===t&&(t=Object.create(null)),ry(rh(t.client),e).useQuery(t)}function ry(e,t){var n=(0,l.useRef)();n.current&&e===n.current.client&&t===n.current.query||(n.current=new rw(e,t,n.current));var r=n.current,i=(0,l.useState)(0),a=(i[0],i[1]);return r.forceUpdate=function(){a(function(e){return e+1})},r}var rw=function(){function e(e,t,n){this.client=e,this.query=t,this.ssrDisabledResult=(0,rp.J)({loading:!0,data:void 0,error:void 0,networkStatus:ru.I.loading}),this.skipStandbyResult=(0,rp.J)({loading:!1,data:void 0,error:void 0,networkStatus:ru.I.ready}),this.toQueryResultCache=new(n7.mr?WeakMap:Map),rd(t,r.Query);var i=n&&n.result,a=i&&i.data;a&&(this.previousData=a)}return e.prototype.forceUpdate=function(){__DEV__&&n9.kG.warn("Calling default no-op implementation of InternalState#forceUpdate")},e.prototype.executeQuery=function(e){var t,n=this;e.query&&Object.assign(this,{query:e.query}),this.watchQueryOptions=this.createWatchQueryOptions(this.queryHookOptions=e);var r=this.observable.reobserveAsConcast(this.getObsQueryOptions());return this.previousData=(null===(t=this.result)||void 0===t?void 0:t.data)||this.previousData,this.result=void 0,this.forceUpdate(),new Promise(function(e){var t;r.subscribe({next:function(e){t=e},error:function(){e(n.toQueryResult(n.observable.getCurrentResult()))},complete:function(){e(n.toQueryResult(t))}})})},e.prototype.useQuery=function(e){var t=this;this.renderPromises=(0,l.useContext)((0,ro.K)()).renderPromises,this.useOptions(e);var n=this.useObservableQuery(),r=rt((0,l.useCallback)(function(){if(t.renderPromises)return function(){};var e=function(){var e=t.result,r=n.getCurrentResult();!(e&&e.loading===r.loading&&e.networkStatus===r.networkStatus&&(0,ri.D)(e.data,r.data))&&t.setResult(r)},r=function(a){var o=n.last;i.unsubscribe();try{n.resetLastResults(),i=n.subscribe(e,r)}finally{n.last=o}if(!rg.call(a,"graphQLErrors"))throw a;var s=t.result;(!s||s&&s.loading||!(0,ri.D)(a,s.error))&&t.setResult({data:s&&s.data,error:a,loading:!1,networkStatus:ru.I.error})},i=n.subscribe(e,r);return function(){return setTimeout(function(){return i.unsubscribe()})}},[n,this.renderPromises,this.client.disableNetworkFetches,]),function(){return t.getCurrentResult()},function(){return t.getCurrentResult()});return this.unsafeHandlePartialRefetch(r),this.toQueryResult(r)},e.prototype.useOptions=function(t){var n,r=this.createWatchQueryOptions(this.queryHookOptions=t),i=this.watchQueryOptions;!(0,ri.D)(r,i)&&(this.watchQueryOptions=r,i&&this.observable&&(this.observable.reobserve(this.getObsQueryOptions()),this.previousData=(null===(n=this.result)||void 0===n?void 0:n.data)||this.previousData,this.result=void 0)),this.onCompleted=t.onCompleted||e.prototype.onCompleted,this.onError=t.onError||e.prototype.onError,(this.renderPromises||this.client.disableNetworkFetches)&&!1===this.queryHookOptions.ssr&&!this.queryHookOptions.skip?this.result=this.ssrDisabledResult:this.queryHookOptions.skip||"standby"===this.watchQueryOptions.fetchPolicy?this.result=this.skipStandbyResult:(this.result===this.ssrDisabledResult||this.result===this.skipStandbyResult)&&(this.result=void 0)},e.prototype.getObsQueryOptions=function(){var e=[],t=this.client.defaultOptions.watchQuery;return t&&e.push(t),this.queryHookOptions.defaultOptions&&e.push(this.queryHookOptions.defaultOptions),e.push((0,rb.o)(this.observable&&this.observable.options,this.watchQueryOptions)),e.reduce(ra.J)},e.prototype.createWatchQueryOptions=function(e){void 0===e&&(e={});var t,n=e.skip,r=Object.assign((e.ssr,e.onCompleted,e.onError,e.defaultOptions,(0,t0._T)(e,["skip","ssr","onCompleted","onError","defaultOptions"])),{query:this.query});if(this.renderPromises&&("network-only"===r.fetchPolicy||"cache-and-network"===r.fetchPolicy)&&(r.fetchPolicy="cache-first"),r.variables||(r.variables={}),n){var i=r.fetchPolicy,a=void 0===i?this.getDefaultFetchPolicy():i,o=r.initialFetchPolicy;Object.assign(r,{initialFetchPolicy:void 0===o?a:o,fetchPolicy:"standby"})}else r.fetchPolicy||(r.fetchPolicy=(null===(t=this.observable)||void 0===t?void 0:t.options.initialFetchPolicy)||this.getDefaultFetchPolicy());return r},e.prototype.getDefaultFetchPolicy=function(){var e,t;return(null===(e=this.queryHookOptions.defaultOptions)||void 0===e?void 0:e.fetchPolicy)||(null===(t=this.client.defaultOptions.watchQuery)||void 0===t?void 0:t.fetchPolicy)||"cache-first"},e.prototype.onCompleted=function(e){},e.prototype.onError=function(e){},e.prototype.useObservableQuery=function(){var e=this.observable=this.renderPromises&&this.renderPromises.getSSRObservable(this.watchQueryOptions)||this.observable||this.client.watchQuery(this.getObsQueryOptions());this.obsQueryFields=(0,l.useMemo)(function(){return{refetch:e.refetch.bind(e),reobserve:e.reobserve.bind(e),fetchMore:e.fetchMore.bind(e),updateQuery:e.updateQuery.bind(e),startPolling:e.startPolling.bind(e),stopPolling:e.stopPolling.bind(e),subscribeToMore:e.subscribeToMore.bind(e)}},[e]);var t=!(!1===this.queryHookOptions.ssr||this.queryHookOptions.skip);return this.renderPromises&&t&&(this.renderPromises.registerSSRObservable(e),e.getCurrentResult().loading&&this.renderPromises.addObservableQueryPromise(e)),e},e.prototype.setResult=function(e){var t=this.result;t&&t.data&&(this.previousData=t.data),this.result=e,this.forceUpdate(),this.handleErrorOrCompleted(e)},e.prototype.handleErrorOrCompleted=function(e){var t=this;if(!e.loading){var n=this.toApolloError(e);Promise.resolve().then(function(){n?t.onError(n):e.data&&t.onCompleted(e.data)}).catch(function(e){__DEV__&&n9.kG.warn(e)})}},e.prototype.toApolloError=function(e){return(0,rm.O)(e.errors)?new rs.cA({graphQLErrors:e.errors}):e.error},e.prototype.getCurrentResult=function(){return this.result||this.handleErrorOrCompleted(this.result=this.observable.getCurrentResult()),this.result},e.prototype.toQueryResult=function(e){var t=this.toQueryResultCache.get(e);if(t)return t;var n=e.data,r=(e.partial,(0,t0._T)(e,["data","partial"]));return this.toQueryResultCache.set(e,t=(0,t0.pi)((0,t0.pi)((0,t0.pi)({data:n},r),this.obsQueryFields),{client:this.client,observable:this.observable,variables:this.observable.variables,called:!this.queryHookOptions.skip,previousData:this.previousData})),!t.error&&(0,rm.O)(e.errors)&&(t.error=new rs.cA({graphQLErrors:e.errors})),t},e.prototype.unsafeHandlePartialRefetch=function(e){e.partial&&this.queryHookOptions.partialRefetch&&!e.loading&&(!e.data||0===Object.keys(e.data).length)&&"cache-only"!==this.observable.options.fetchPolicy&&(Object.assign(e,{loading:!0,networkStatus:ru.I.refetch}),this.observable.refetch())},e}();function r_(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]?arguments[0]:{};return rv(iH,e)},iz=function(){var e=ij(),t=parseInt(e.get("page")||"1",10),n=parseInt(e.get("per")||"50",10),r=i$({variables:{offset:(t-1)*n,limit:n},fetchPolicy:"network-only"}),i=r.data,a=r.loading,o=r.error;return a?l.createElement(iR,null):o?l.createElement(iD,{error:o}):i?l.createElement(iI,{chains:i.chains.results,page:t,pageSize:n,total:i.chains.metadata.total}):null},iG=n(67932),iW=n(8126),iK="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function iV(e){if(iq())return Intl.DateTimeFormat.supportedLocalesOf(e)[0]}function iq(){return("undefined"==typeof Intl?"undefined":iK(Intl))==="object"&&"function"==typeof Intl.DateTimeFormat}var iZ="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},iX=function(){function e(e,t){for(var n=0;n=i.length)break;s=i[o++]}else{if((o=i.next()).done)break;s=o.value}var s,u=s;if((void 0===e?"undefined":iZ(e))!=="object")return;e=e[u]}return e}},{key:"put",value:function(){for(var e=arguments.length,t=Array(e),n=0;n=o.length)break;c=o[u++]}else{if((u=o.next()).done)break;c=u.value}var c,l=c;"object"!==iZ(a[l])&&(a[l]={}),a=a[l]}return a[i]=r}}]),e}();let i1=iQ;var i0=new i1;function i2(e,t){if(!iq())return function(e){return e.toString()};var n=i4(e),r=JSON.stringify(t),i=i0.get(String(n),r)||i0.put(String(n),r,new Intl.DateTimeFormat(n,t));return function(e){return i.format(e)}}var i3={};function i4(e){var t=e.toString();return i3[t]?i3[t]:i3[t]=iV(e)}var i6="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function i5(e){return i8(e)?e:new Date(e)}function i8(e){return e instanceof Date||i9(e)}function i9(e){return(void 0===e?"undefined":i6(e))==="object"&&"function"==typeof e.getTime}var i7=n(54087),ae=n.n(i7);function at(e,t){if(0===e.length)return 0;for(var n=0,r=e.length-1,i=void 0;n<=r;){var a=t(e[i=Math.floor((r+n)/2)]);if(0===a)return i;if(a<0){if((n=i+1)>r)return n}else if((r=i-1)=t.nextUpdateTime)aa(t,this.instances);else break}},scheduleNextTick:function(){var e=this;this.scheduledTick=ae()(function(){e.tick(),e.scheduleNextTick()})},start:function(){this.scheduleNextTick()},stop:function(){ae().cancel(this.scheduledTick)}};function ai(e){var t=an(e.getNextValue(),2),n=t[0],r=t[1];e.setValue(n),e.nextUpdateTime=r}function aa(e,t){ai(e),as(t,e),ao(t,e)}function ao(e,t){var n=au(e,t);e.splice(n,0,t)}function as(e,t){var n=e.indexOf(t);e.splice(n,1)}function au(e,t){var n=t.nextUpdateTime;return at(e,function(e){return e.nextUpdateTime===n?0:e.nextUpdateTime>n?1:-1})}var ac=(0,ec.oneOfType)([(0,ec.shape)({minTime:ec.number,formatAs:ec.string.isRequired}),(0,ec.shape)({test:ec.func,formatAs:ec.string.isRequired}),(0,ec.shape)({minTime:ec.number,format:ec.func.isRequired}),(0,ec.shape)({test:ec.func,format:ec.func.isRequired})]),al=(0,ec.oneOfType)([ec.string,(0,ec.shape)({steps:(0,ec.arrayOf)(ac).isRequired,labels:(0,ec.oneOfType)([ec.string,(0,ec.arrayOf)(ec.string)]).isRequired,round:ec.string})]),af=Object.assign||function(e){for(var t=1;t=0)&&Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function ap(e){var t=e.date,n=e.future,r=e.timeStyle,i=e.round,a=e.minTimeLeft,o=e.tooltip,s=e.component,u=e.container,c=e.wrapperComponent,f=e.wrapperProps,d=e.locale,h=e.locales,p=e.formatVerboseDate,b=e.verboseDateFormat,m=e.updateInterval,g=e.tick,v=ah(e,["date","future","timeStyle","round","minTimeLeft","tooltip","component","container","wrapperComponent","wrapperProps","locale","locales","formatVerboseDate","verboseDateFormat","updateInterval","tick"]),y=(0,l.useMemo)(function(){return d&&(h=[d]),h.concat(iW.Z.getDefaultLocale())},[d,h]),w=(0,l.useMemo)(function(){return new iW.Z(y)},[y]);t=(0,l.useMemo)(function(){return i5(t)},[t]);var _=(0,l.useCallback)(function(){var e=Date.now(),o=void 0;if(n&&e>=t.getTime()&&(e=t.getTime(),o=!0),void 0!==a){var s=t.getTime()-1e3*a;e>s&&(e=s,o=!0)}var u=w.format(t,r,{getTimeToNextUpdate:!0,now:e,future:n,round:i}),c=ad(u,2),l=c[0],f=c[1];return f=o?ag:m||f||6e4,[l,e+f]},[t,n,r,m,i,a,w]),E=(0,l.useRef)();E.current=_;var S=(0,l.useMemo)(_,[]),k=ad(S,2),x=k[0],T=k[1],M=(0,l.useState)(x),O=ad(M,2),A=O[0],L=O[1],C=ad((0,l.useState)(),2),I=C[0],D=C[1],N=(0,l.useRef)();(0,l.useEffect)(function(){if(g)return N.current=ar.add({getNextValue:function(){return E.current()},setValue:L,nextUpdateTime:T}),function(){return N.current.stop()}},[g]),(0,l.useEffect)(function(){if(N.current)N.current.forceUpdate();else{var e=_(),t=ad(e,1)[0];L(t)}},[_]),(0,l.useEffect)(function(){D(!0)},[]);var P=(0,l.useMemo)(function(){if("undefined"!=typeof window)return i2(y,b)},[y,b]),R=(0,l.useMemo)(function(){if("undefined"!=typeof window)return p?p(t):P(t)},[t,p,P]),j=l.createElement(s,af({date:t,verboseDate:I?R:void 0,tooltip:o},v),A),F=c||u;return F?l.createElement(F,af({},f,{verboseDate:I?R:void 0}),j):j}ap.propTypes={date:el().oneOfType([el().instanceOf(Date),el().number]).isRequired,locale:el().string,locales:el().arrayOf(el().string),future:el().bool,timeStyle:al,round:el().string,minTimeLeft:el().number,component:el().elementType.isRequired,tooltip:el().bool.isRequired,formatVerboseDate:el().func,verboseDateFormat:el().object,updateInterval:el().oneOfType([el().number,el().arrayOf(el().shape({threshold:el().number,interval:el().number.isRequired}))]),tick:el().bool,wrapperComponent:el().func,wrapperProps:el().object},ap.defaultProps={locales:[],component:av,tooltip:!0,verboseDateFormat:{weekday:"long",day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"2-digit",second:"2-digit"},tick:!0},ap=l.memo(ap);let ab=ap;var am,ag=31536e9;function av(e){var t=e.date,n=e.verboseDate,r=e.tooltip,i=e.children,a=ah(e,["date","verboseDate","tooltip","children"]),o=(0,l.useMemo)(function(){return t.toISOString()},[t]);return l.createElement("time",af({},a,{dateTime:o,title:r?n:void 0}),i)}av.propTypes={date:el().instanceOf(Date).isRequired,verboseDate:el().string,tooltip:el().bool.isRequired,children:el().string.isRequired};var ay=n(30381),aw=n.n(ay),a_=n(31657);function aE(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function aS(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0?new rs.cA({graphQLErrors:i}):void 0;if(u===s.current.mutationId&&!c.ignoreResults){var f={called:!0,loading:!1,data:r,error:l,client:a};s.current.isMounted&&!(0,ri.D)(s.current.result,f)&&o(s.current.result=f)}var d=e.onCompleted||(null===(n=s.current.options)||void 0===n?void 0:n.onCompleted);return null==d||d(t.data,c),t}).catch(function(t){if(u===s.current.mutationId&&s.current.isMounted){var n,r={loading:!1,error:t,data:void 0,called:!0,client:a};(0,ri.D)(s.current.result,r)||o(s.current.result=r)}var i=e.onError||(null===(n=s.current.options)||void 0===n?void 0:n.onError);if(i)return i(t,c),{data:void 0,errors:t};throw t})},[]),c=(0,l.useCallback)(function(){s.current.isMounted&&o({called:!1,loading:!1,client:n})},[]);return(0,l.useEffect)(function(){return s.current.isMounted=!0,function(){s.current.isMounted=!1}},[]),[u,(0,t0.pi)({reset:c},a)]}var os=n(59067),ou=n(28428),oc=n(11186),ol=n(78513);function of(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var od=function(e){return(0,b.createStyles)({paper:{display:"flex",margin:"".concat(2.5*e.spacing.unit,"px 0"),padding:"".concat(3*e.spacing.unit,"px ").concat(3.5*e.spacing.unit,"px")},content:{flex:1,width:"100%"},actions:of({marginTop:-(1.5*e.spacing.unit),marginLeft:-(4*e.spacing.unit)},e.breakpoints.up("sm"),{marginLeft:0,marginRight:-(1.5*e.spacing.unit)}),itemBlock:{border:"1px solid rgba(224, 224, 224, 1)",borderRadius:e.shape.borderRadius,padding:2*e.spacing.unit,marginTop:e.spacing.unit},itemBlockText:{overflowWrap:"anywhere"}})},oh=(0,b.withStyles)(od)(function(e){var t=e.actions,n=e.children,r=e.classes;return l.createElement(ii.default,{className:r.paper},l.createElement("div",{className:r.content},n),t&&l.createElement("div",{className:r.actions},t))}),op=function(e){var t=e.title;return l.createElement(x.default,{variant:"subtitle2",gutterBottom:!0},t)},ob=function(e){var t=e.children,n=e.value;return l.createElement(x.default,{variant:"body1",noWrap:!0},t||n)},om=(0,b.withStyles)(od)(function(e){var t=e.children,n=e.classes,r=e.value;return l.createElement("div",{className:n.itemBlock},l.createElement(x.default,{variant:"body1",className:n.itemBlockText},t||r))});function og(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]-1}let sq=sV;function sZ(e,t){var n=this.__data__,r=sH(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this}let sX=sZ;function sJ(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t-1&&e%1==0&&e-1&&e%1==0&&e<=cC}let cD=cI;var cN="[object Arguments]",cP="[object Array]",cR="[object Boolean]",cj="[object Date]",cF="[object Error]",cY="[object Function]",cB="[object Map]",cU="[object Number]",cH="[object Object]",c$="[object RegExp]",cz="[object Set]",cG="[object String]",cW="[object WeakMap]",cK="[object ArrayBuffer]",cV="[object DataView]",cq="[object Float64Array]",cZ="[object Int8Array]",cX="[object Int16Array]",cJ="[object Int32Array]",cQ="[object Uint8Array]",c1="[object Uint8ClampedArray]",c0="[object Uint16Array]",c2="[object Uint32Array]",c3={};function c4(e){return eD(e)&&cD(e.length)&&!!c3[eC(e)]}c3["[object Float32Array]"]=c3[cq]=c3[cZ]=c3[cX]=c3[cJ]=c3[cQ]=c3[c1]=c3[c0]=c3[c2]=!0,c3[cN]=c3[cP]=c3[cK]=c3[cR]=c3[cV]=c3[cj]=c3[cF]=c3[cY]=c3[cB]=c3[cU]=c3[cH]=c3[c$]=c3[cz]=c3[cG]=c3[cW]=!1;let c6=c4;function c5(e){return function(t){return e(t)}}let c8=c5;var c9=n(79730),c7=c9.Z&&c9.Z.isTypedArray,le=c7?c8(c7):c6;let lt=le;var ln=Object.prototype.hasOwnProperty;function lr(e,t){var n=cx(e),r=!n&&cS(e),i=!n&&!r&&(0,cT.Z)(e),a=!n&&!r&&!i&<(e),o=n||r||i||a,s=o?cb(e.length,String):[],u=s.length;for(var c in e)(t||ln.call(e,c))&&!(o&&("length"==c||i&&("offset"==c||"parent"==c)||a&&("buffer"==c||"byteLength"==c||"byteOffset"==c)||cL(c,u)))&&s.push(c);return s}let li=lr;var la=Object.prototype;function lo(e){var t=e&&e.constructor;return e===("function"==typeof t&&t.prototype||la)}let ls=lo;var lu=sT(Object.keys,Object);let lc=lu;var ll=Object.prototype.hasOwnProperty;function lf(e){if(!ls(e))return lc(e);var t=[];for(var n in Object(e))ll.call(e,n)&&"constructor"!=n&&t.push(n);return t}let ld=lf;function lh(e){return null!=e&&cD(e.length)&&!ur(e)}let lp=lh;function lb(e){return lp(e)?li(e):ld(e)}let lm=lb;function lg(e,t){return e&&ch(t,lm(t),e)}let lv=lg;function ly(e){var t=[];if(null!=e)for(var n in Object(e))t.push(n);return t}let lw=ly;var l_=Object.prototype.hasOwnProperty;function lE(e){if(!ed(e))return lw(e);var t=ls(e),n=[];for(var r in e)"constructor"==r&&(t||!l_.call(e,r))||n.push(r);return n}let lS=lE;function lk(e){return lp(e)?li(e,!0):lS(e)}let lx=lk;function lT(e,t){return e&&ch(t,lx(t),e)}let lM=lT;var lO=n(42896);function lA(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++n=0||(i[n]=e[n]);return i}function hu(e){if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}var hc=function(e){return Array.isArray(e)&&0===e.length},hl=function(e){return"function"==typeof e},hf=function(e){return null!==e&&"object"==typeof e},hd=function(e){return String(Math.floor(Number(e)))===e},hh=function(e){return"[object String]"===Object.prototype.toString.call(e)},hp=function(e){return 0===l.Children.count(e)},hb=function(e){return hf(e)&&hl(e.then)};function hm(e,t,n,r){void 0===r&&(r=0);for(var i=d8(t);e&&r=0?[]:{}}}return(0===a?e:i)[o[a]]===n?e:(void 0===n?delete i[o[a]]:i[o[a]]=n,0===a&&void 0===n&&delete r[o[a]],r)}function hv(e,t,n,r){void 0===n&&(n=new WeakMap),void 0===r&&(r={});for(var i=0,a=Object.keys(e);i0?t.map(function(t){return x(t,hm(e,t))}):[Promise.resolve("DO_NOT_DELETE_YOU_WILL_BE_FIRED")]).then(function(e){return e.reduce(function(e,n,r){return"DO_NOT_DELETE_YOU_WILL_BE_FIRED"===n||n&&(e=hg(e,t[r],n)),e},{})})},[x]),M=(0,l.useCallback)(function(e){return Promise.all([T(e),h.validationSchema?k(e):{},h.validate?S(e):{}]).then(function(e){var t=e[0],n=e[1],r=e[2];return sk.all([t,n,r],{arrayMerge:hL})})},[h.validate,h.validationSchema,T,S,k]),O=hN(function(e){return void 0===e&&(e=_.values),E({type:"SET_ISVALIDATING",payload:!0}),M(e).then(function(e){return v.current&&(E({type:"SET_ISVALIDATING",payload:!1}),sd()(_.errors,e)||E({type:"SET_ERRORS",payload:e})),e})});(0,l.useEffect)(function(){o&&!0===v.current&&sd()(p.current,h.initialValues)&&O(p.current)},[o,O]);var A=(0,l.useCallback)(function(e){var t=e&&e.values?e.values:p.current,n=e&&e.errors?e.errors:b.current?b.current:h.initialErrors||{},r=e&&e.touched?e.touched:m.current?m.current:h.initialTouched||{},i=e&&e.status?e.status:g.current?g.current:h.initialStatus;p.current=t,b.current=n,m.current=r,g.current=i;var a=function(){E({type:"RESET_FORM",payload:{isSubmitting:!!e&&!!e.isSubmitting,errors:n,touched:r,status:i,values:t,isValidating:!!e&&!!e.isValidating,submitCount:e&&e.submitCount&&"number"==typeof e.submitCount?e.submitCount:0}})};if(h.onReset){var o=h.onReset(_.values,V);hb(o)?o.then(a):a()}else a()},[h.initialErrors,h.initialStatus,h.initialTouched]);(0,l.useEffect)(function(){!0===v.current&&!sd()(p.current,h.initialValues)&&(c&&(p.current=h.initialValues,A()),o&&O(p.current))},[c,h.initialValues,A,o,O]),(0,l.useEffect)(function(){c&&!0===v.current&&!sd()(b.current,h.initialErrors)&&(b.current=h.initialErrors||hS,E({type:"SET_ERRORS",payload:h.initialErrors||hS}))},[c,h.initialErrors]),(0,l.useEffect)(function(){c&&!0===v.current&&!sd()(m.current,h.initialTouched)&&(m.current=h.initialTouched||hk,E({type:"SET_TOUCHED",payload:h.initialTouched||hk}))},[c,h.initialTouched]),(0,l.useEffect)(function(){c&&!0===v.current&&!sd()(g.current,h.initialStatus)&&(g.current=h.initialStatus,E({type:"SET_STATUS",payload:h.initialStatus}))},[c,h.initialStatus,h.initialTouched]);var L=hN(function(e){if(y.current[e]&&hl(y.current[e].validate)){var t=hm(_.values,e),n=y.current[e].validate(t);return hb(n)?(E({type:"SET_ISVALIDATING",payload:!0}),n.then(function(e){return e}).then(function(t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t}}),E({type:"SET_ISVALIDATING",payload:!1})})):(E({type:"SET_FIELD_ERROR",payload:{field:e,value:n}}),Promise.resolve(n))}return h.validationSchema?(E({type:"SET_ISVALIDATING",payload:!0}),k(_.values,e).then(function(e){return e}).then(function(t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t[e]}}),E({type:"SET_ISVALIDATING",payload:!1})})):Promise.resolve()}),C=(0,l.useCallback)(function(e,t){var n=t.validate;y.current[e]={validate:n}},[]),I=(0,l.useCallback)(function(e){delete y.current[e]},[]),D=hN(function(e,t){return E({type:"SET_TOUCHED",payload:e}),(void 0===t?i:t)?O(_.values):Promise.resolve()}),N=(0,l.useCallback)(function(e){E({type:"SET_ERRORS",payload:e})},[]),P=hN(function(e,t){var r=hl(e)?e(_.values):e;return E({type:"SET_VALUES",payload:r}),(void 0===t?n:t)?O(r):Promise.resolve()}),R=(0,l.useCallback)(function(e,t){E({type:"SET_FIELD_ERROR",payload:{field:e,value:t}})},[]),j=hN(function(e,t,r){return E({type:"SET_FIELD_VALUE",payload:{field:e,value:t}}),(void 0===r?n:r)?O(hg(_.values,e,t)):Promise.resolve()}),F=(0,l.useCallback)(function(e,t){var n,r=t,i=e;if(!hh(e)){e.persist&&e.persist();var a=e.target?e.target:e.currentTarget,o=a.type,s=a.name,u=a.id,c=a.value,l=a.checked,f=(a.outerHTML,a.options),d=a.multiple;r=t||s||u,i=/number|range/.test(o)?(n=parseFloat(c),isNaN(n)?"":n):/checkbox/.test(o)?hI(hm(_.values,r),l,c):d?hC(f):c}r&&j(r,i)},[j,_.values]),Y=hN(function(e){if(hh(e))return function(t){return F(t,e)};F(e)}),B=hN(function(e,t,n){return void 0===t&&(t=!0),E({type:"SET_FIELD_TOUCHED",payload:{field:e,value:t}}),(void 0===n?i:n)?O(_.values):Promise.resolve()}),U=(0,l.useCallback)(function(e,t){e.persist&&e.persist();var n,r=e.target,i=r.name,a=r.id;r.outerHTML,B(t||i||a,!0)},[B]),H=hN(function(e){if(hh(e))return function(t){return U(t,e)};U(e)}),$=(0,l.useCallback)(function(e){hl(e)?E({type:"SET_FORMIK_STATE",payload:e}):E({type:"SET_FORMIK_STATE",payload:function(){return e}})},[]),z=(0,l.useCallback)(function(e){E({type:"SET_STATUS",payload:e})},[]),G=(0,l.useCallback)(function(e){E({type:"SET_ISSUBMITTING",payload:e})},[]),W=hN(function(){return E({type:"SUBMIT_ATTEMPT"}),O().then(function(e){var t,n=e instanceof Error;if(!n&&0===Object.keys(e).length){try{if(void 0===(t=q()))return}catch(r){throw r}return Promise.resolve(t).then(function(e){return v.current&&E({type:"SUBMIT_SUCCESS"}),e}).catch(function(e){if(v.current)throw E({type:"SUBMIT_FAILURE"}),e})}if(v.current&&(E({type:"SUBMIT_FAILURE"}),n))throw e})}),K=hN(function(e){e&&e.preventDefault&&hl(e.preventDefault)&&e.preventDefault(),e&&e.stopPropagation&&hl(e.stopPropagation)&&e.stopPropagation(),W().catch(function(e){console.warn("Warning: An unhandled error was caught from submitForm()",e)})}),V={resetForm:A,validateForm:O,validateField:L,setErrors:N,setFieldError:R,setFieldTouched:B,setFieldValue:j,setStatus:z,setSubmitting:G,setTouched:D,setValues:P,setFormikState:$,submitForm:W},q=hN(function(){return f(_.values,V)}),Z=hN(function(e){e&&e.preventDefault&&hl(e.preventDefault)&&e.preventDefault(),e&&e.stopPropagation&&hl(e.stopPropagation)&&e.stopPropagation(),A()}),X=(0,l.useCallback)(function(e){return{value:hm(_.values,e),error:hm(_.errors,e),touched:!!hm(_.touched,e),initialValue:hm(p.current,e),initialTouched:!!hm(m.current,e),initialError:hm(b.current,e)}},[_.errors,_.touched,_.values]),J=(0,l.useCallback)(function(e){return{setValue:function(t,n){return j(e,t,n)},setTouched:function(t,n){return B(e,t,n)},setError:function(t){return R(e,t)}}},[j,B,R]),Q=(0,l.useCallback)(function(e){var t=hf(e),n=t?e.name:e,r=hm(_.values,n),i={name:n,value:r,onChange:Y,onBlur:H};if(t){var a=e.type,o=e.value,s=e.as,u=e.multiple;"checkbox"===a?void 0===o?i.checked=!!r:(i.checked=!!(Array.isArray(r)&&~r.indexOf(o)),i.value=o):"radio"===a?(i.checked=r===o,i.value=o):"select"===s&&u&&(i.value=i.value||[],i.multiple=!0)}return i},[H,Y,_.values]),ee=(0,l.useMemo)(function(){return!sd()(p.current,_.values)},[p.current,_.values]),et=(0,l.useMemo)(function(){return void 0!==s?ee?_.errors&&0===Object.keys(_.errors).length:!1!==s&&hl(s)?s(h):s:_.errors&&0===Object.keys(_.errors).length},[s,ee,_.errors,h]);return ha({},_,{initialValues:p.current,initialErrors:b.current,initialTouched:m.current,initialStatus:g.current,handleBlur:H,handleChange:Y,handleReset:Z,handleSubmit:K,resetForm:A,setErrors:N,setFormikState:$,setFieldTouched:B,setFieldValue:j,setFieldError:R,setStatus:z,setSubmitting:G,setTouched:D,setValues:P,submitForm:W,validateForm:O,validateField:L,isValid:et,dirty:ee,unregisterField:I,registerField:C,getFieldProps:Q,getFieldMeta:X,getFieldHelpers:J,validateOnBlur:i,validateOnChange:n,validateOnMount:o})}function hT(e){var t=hx(e),n=e.component,r=e.children,i=e.render,a=e.innerRef;return(0,l.useImperativeHandle)(a,function(){return t}),(0,l.createElement)(hw,{value:t},n?(0,l.createElement)(n,t):i?i(t):r?hl(r)?r(t):hp(r)?null:l.Children.only(r):null)}function hM(e){var t={};if(e.inner){if(0===e.inner.length)return hg(t,e.path,e.message);for(var n=e.inner,r=Array.isArray(n),i=0,n=r?n:n[Symbol.iterator]();;){if(r){if(i>=n.length)break;a=n[i++]}else{if((i=n.next()).done)break;a=i.value}var a,o=a;hm(t,o.path)||(t=hg(t,o.path,o.message))}}return t}function hO(e,t,n,r){void 0===n&&(n=!1),void 0===r&&(r={});var i=hA(e);return t[n?"validateSync":"validate"](i,{abortEarly:!1,context:r})}function hA(e){var t=Array.isArray(e)?[]:{};for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){var r=String(n);!0===Array.isArray(e[r])?t[r]=e[r].map(function(e){return!0===Array.isArray(e)||sR(e)?hA(e):""!==e?e:void 0}):sR(e[r])?t[r]=hA(e[r]):t[r]=""!==e[r]?e[r]:void 0}return t}function hL(e,t,n){var r=e.slice();return t.forEach(function(t,i){if(void 0===r[i]){var a=!1!==n.clone&&n.isMergeableObject(t);r[i]=a?sk(Array.isArray(t)?[]:{},t,n):t}else n.isMergeableObject(t)?r[i]=sk(e[i],t,n):-1===e.indexOf(t)&&r.push(t)}),r}function hC(e){return Array.from(e).filter(function(e){return e.selected}).map(function(e){return e.value})}function hI(e,t,n){if("boolean"==typeof e)return Boolean(t);var r=[],i=!1,a=-1;if(Array.isArray(e))r=e,i=(a=e.indexOf(n))>=0;else if(!n||"true"==n||"false"==n)return Boolean(t);return t&&n&&!i?r.concat(n):i?r.slice(0,a).concat(r.slice(a+1)):r}var hD="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement?l.useLayoutEffect:l.useEffect;function hN(e){var t=(0,l.useRef)(e);return hD(function(){t.current=e}),(0,l.useCallback)(function(){for(var e=arguments.length,n=Array(e),r=0;re?t:e},0);return Array.from(ha({},e,{length:t+1}))};(function(e){function t(t){var n;return(n=e.call(this,t)||this).updateArrayField=function(e,t,r){var i=n.props,a=i.name;(0,i.formik.setFormikState)(function(n){var i="function"==typeof r?r:e,o="function"==typeof t?t:e,s=hg(n.values,a,e(hm(n.values,a))),u=r?i(hm(n.errors,a)):void 0,c=t?o(hm(n.touched,a)):void 0;return hc(u)&&(u=void 0),hc(c)&&(c=void 0),ha({},n,{values:s,errors:r?hg(n.errors,a,u):n.errors,touched:t?hg(n.touched,a,c):n.touched})})},n.push=function(e){return n.updateArrayField(function(t){return[].concat(hU(t),[hi(e)])},!1,!1)},n.handlePush=function(e){return function(){return n.push(e)}},n.swap=function(e,t){return n.updateArrayField(function(n){return hF(n,e,t)},!0,!0)},n.handleSwap=function(e,t){return function(){return n.swap(e,t)}},n.move=function(e,t){return n.updateArrayField(function(n){return hj(n,e,t)},!0,!0)},n.handleMove=function(e,t){return function(){return n.move(e,t)}},n.insert=function(e,t){return n.updateArrayField(function(n){return hY(n,e,t)},function(t){return hY(t,e,null)},function(t){return hY(t,e,null)})},n.handleInsert=function(e,t){return function(){return n.insert(e,t)}},n.replace=function(e,t){return n.updateArrayField(function(n){return hB(n,e,t)},!1,!1)},n.handleReplace=function(e,t){return function(){return n.replace(e,t)}},n.unshift=function(e){var t=-1;return n.updateArrayField(function(n){var r=n?[e].concat(n):[e];return t<0&&(t=r.length),r},function(e){var n=e?[null].concat(e):[null];return t<0&&(t=n.length),n},function(e){var n=e?[null].concat(e):[null];return t<0&&(t=n.length),n}),t},n.handleUnshift=function(e){return function(){return n.unshift(e)}},n.handleRemove=function(e){return function(){return n.remove(e)}},n.handlePop=function(){return function(){return n.pop()}},n.remove=n.remove.bind(hu(n)),n.pop=n.pop.bind(hu(n)),n}ho(t,e);var n=t.prototype;return n.componentDidUpdate=function(e){this.props.validateOnChange&&this.props.formik.validateOnChange&&!sd()(hm(e.formik.values,e.name),hm(this.props.formik.values,this.props.name))&&this.props.formik.validateForm(this.props.formik.values)},n.remove=function(e){var t;return this.updateArrayField(function(n){var r=n?hU(n):[];return t||(t=r[e]),hl(r.splice)&&r.splice(e,1),r},!0,!0),t},n.pop=function(){var e;return this.updateArrayField(function(t){var n=t;return e||(e=n&&n.pop&&n.pop()),n},!0,!0),e},n.render=function(){var e={push:this.push,pop:this.pop,swap:this.swap,move:this.move,insert:this.insert,replace:this.replace,unshift:this.unshift,remove:this.remove,handlePush:this.handlePush,handlePop:this.handlePop,handleSwap:this.handleSwap,handleMove:this.handleMove,handleInsert:this.handleInsert,handleReplace:this.handleReplace,handleUnshift:this.handleUnshift,handleRemove:this.handleRemove},t=this.props,n=t.component,r=t.render,i=t.children,a=t.name,o=hs(t.formik,["validate","validationSchema"]),s=ha({},e,{form:o,name:a});return n?(0,l.createElement)(n,s):r?r(s):i?"function"==typeof i?i(s):hp(i)?null:l.Children.only(i):null},t})(l.Component).defaultProps={validateOnChange:!0},l.Component,l.Component;var hH=n(24802),h$=n(71209),hz=n(91750),hG=n(11970),hW=n(4689),hK=n(67598),hV=function(){return(hV=Object.assign||function(e){for(var t,n=1,r=arguments.length;nt.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,r=Object.getOwnPropertySymbols(e);it.indexOf(r[i])&&(n[r[i]]=e[r[i]]);return n}function hZ(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hq(n,["onBlur"]),a=e.form,o=a.isSubmitting,s=a.touched,u=a.errors,c=e.onBlur,l=e.helperText,f=hq(e,["disabled","field","form","onBlur","helperText"]),d=hm(u,i.name),h=hm(s,i.name)&&!!d;return hV(hV({variant:f.variant,error:h,helperText:h?d:l,disabled:null!=t?t:o,onBlur:null!=c?c:function(e){r(null!=e?e:i.name)}},i),f)}function hX(e){var t=e.children,n=hq(e,["children"]);return(0,l.createElement)(iw.Z,hV({},hZ(n)),t)}function hJ(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hq(n,["onBlur"]),a=e.form.isSubmitting,o=(e.type,e.onBlur),s=hq(e,["disabled","field","form","type","onBlur"]);return hV(hV({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function hQ(e){return(0,l.createElement)(hH.Z,hV({},hJ(e)))}function h1(e){var t,n=e.disabled,r=e.field,i=r.onBlur,a=hq(r,["onBlur"]),o=e.form.isSubmitting,s=(e.type,e.onBlur),u=hq(e,["disabled","field","form","type","onBlur"]);return hV(hV({disabled:null!=n?n:o,indeterminate:!Array.isArray(a.value)&&null==a.value,onBlur:null!=s?s:function(e){i(null!=e?e:a.name)}},a),u)}function h0(e){return(0,l.createElement)(h$.Z,hV({},h1(e)))}function h2(e){var t=e.Label,n=hq(e,["Label"]);return(0,l.createElement)(hz.Z,hV({control:(0,l.createElement)(h$.Z,hV({},h1(n)))},t))}function h3(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hq(n,["onBlur"]),a=e.form.isSubmitting,o=e.onBlur,s=hq(e,["disabled","field","form","onBlur"]);return hV(hV({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function h4(e){return(0,l.createElement)(hG.default,hV({},h3(e)))}function h6(e){var t=e.field,n=t.onBlur,r=hq(t,["onBlur"]),i=(e.form,e.onBlur),a=hq(e,["field","form","onBlur"]);return hV(hV({onBlur:null!=i?i:function(e){n(null!=e?e:r.name)}},r),a)}function h5(e){return(0,l.createElement)(hW.Z,hV({},h6(e)))}function h8(e){var t=e.disabled,n=e.field,r=n.onBlur,i=hq(n,["onBlur"]),a=e.form.isSubmitting,o=e.onBlur,s=hq(e,["disabled","field","form","onBlur"]);return hV(hV({disabled:null!=t?t:a,onBlur:null!=o?o:function(e){r(null!=e?e:i.name)}},i),s)}function h9(e){return(0,l.createElement)(hK.default,hV({},h8(e)))}hX.displayName="FormikMaterialUITextField",hQ.displayName="FormikMaterialUISwitch",h0.displayName="FormikMaterialUICheckbox",h2.displayName="FormikMaterialUICheckboxWithLabel",h4.displayName="FormikMaterialUISelect",h5.displayName="FormikMaterialUIRadioGroup",h9.displayName="FormikMaterialUIInputBase";try{a=Map}catch(h7){}try{o=Set}catch(pe){}function pt(e,t,n){if(!e||"object"!=typeof e||"function"==typeof e)return e;if(e.nodeType&&"cloneNode"in e)return e.cloneNode(!0);if(e instanceof Date)return new Date(e.getTime());if(e instanceof RegExp)return RegExp(e);if(Array.isArray(e))return e.map(pn);if(a&&e instanceof a)return new Map(Array.from(e.entries()));if(o&&e instanceof o)return new Set(Array.from(e.values()));if(e instanceof Object){t.push(e);var r=Object.create(e);for(var i in n.push(r),e){var s=t.findIndex(function(t){return t===e[i]});r[i]=s>-1?n[s]:pt(e[i],t,n)}return r}return e}function pn(e){return pt(e,[],[])}let pr=Object.prototype.toString,pi=Error.prototype.toString,pa=RegExp.prototype.toString,po="undefined"!=typeof Symbol?Symbol.prototype.toString:()=>"",ps=/^Symbol\((.*)\)(.*)$/;function pu(e){if(e!=+e)return"NaN";let t=0===e&&1/e<0;return t?"-0":""+e}function pc(e,t=!1){if(null==e||!0===e||!1===e)return""+e;let n=typeof e;if("number"===n)return pu(e);if("string"===n)return t?`"${e}"`:e;if("function"===n)return"[Function "+(e.name||"anonymous")+"]";if("symbol"===n)return po.call(e).replace(ps,"Symbol($1)");let r=pr.call(e).slice(8,-1);return"Date"===r?isNaN(e.getTime())?""+e:e.toISOString(e):"Error"===r||e instanceof Error?"["+pi.call(e)+"]":"RegExp"===r?pa.call(e):null}function pl(e,t){let n=pc(e,t);return null!==n?n:JSON.stringify(e,function(e,n){let r=pc(this[e],t);return null!==r?r:n},2)}let pf={default:"${path} is invalid",required:"${path} is a required field",oneOf:"${path} must be one of the following values: ${values}",notOneOf:"${path} must not be one of the following values: ${values}",notType({path:e,type:t,value:n,originalValue:r}){let i=null!=r&&r!==n,a=`${e} must be a \`${t}\` type, but the final value was: \`${pl(n,!0)}\``+(i?` (cast from the value \`${pl(r,!0)}\`).`:".");return null===n&&(a+='\n If "null" is intended as an empty value be sure to mark the schema as `.nullable()`'),a},defined:"${path} must be defined"},pd={length:"${path} must be exactly ${length} characters",min:"${path} must be at least ${min} characters",max:"${path} must be at most ${max} characters",matches:'${path} must match the following: "${regex}"',email:"${path} must be a valid email",url:"${path} must be a valid URL",uuid:"${path} must be a valid UUID",trim:"${path} must be a trimmed string",lowercase:"${path} must be a lowercase string",uppercase:"${path} must be a upper case string"},ph={min:"${path} must be greater than or equal to ${min}",max:"${path} must be less than or equal to ${max}",lessThan:"${path} must be less than ${less}",moreThan:"${path} must be greater than ${more}",positive:"${path} must be a positive number",negative:"${path} must be a negative number",integer:"${path} must be an integer"},pp={min:"${path} field must be later than ${min}",max:"${path} field must be at earlier than ${max}"},pb={isValue:"${path} field must be ${value}"},pm={noUnknown:"${path} field has unspecified keys: ${unknown}"},pg={min:"${path} field must have at least ${min} items",max:"${path} field must have less than or equal to ${max} items",length:"${path} must be have ${length} items"};Object.assign(Object.create(null),{mixed:pf,string:pd,number:ph,date:pp,object:pm,array:pg,boolean:pb});var pv=n(18721),py=n.n(pv);let pw=e=>e&&e.__isYupSchema__;class p_{constructor(e,t){if(this.refs=e,this.refs=e,"function"==typeof t){this.fn=t;return}if(!py()(t,"is"))throw TypeError("`is:` is required for `when()` conditions");if(!t.then&&!t.otherwise)throw TypeError("either `then:` or `otherwise:` is required for `when()` conditions");let{is:n,then:r,otherwise:i}=t,a="function"==typeof n?n:(...e)=>e.every(e=>e===n);this.fn=function(...e){let t=e.pop(),n=e.pop(),o=a(...e)?r:i;if(o)return"function"==typeof o?o(n):n.concat(o.resolve(t))}}resolve(e,t){let n=this.refs.map(e=>e.getValue(null==t?void 0:t.value,null==t?void 0:t.parent,null==t?void 0:t.context)),r=this.fn.apply(e,n.concat(e,t));if(void 0===r||r===e)return e;if(!pw(r))throw TypeError("conditions must return a schema object");return r.resolve(t)}}let pE=p_;function pS(e){return null==e?[]:[].concat(e)}function pk(){return(pk=Object.assign||function(e){for(var t=1;tpl(t[n])):"function"==typeof e?e(t):e}static isError(e){return e&&"ValidationError"===e.name}constructor(e,t,n,r){super(),this.name="ValidationError",this.value=t,this.path=n,this.type=r,this.errors=[],this.inner=[],pS(e).forEach(e=>{pT.isError(e)?(this.errors.push(...e.errors),this.inner=this.inner.concat(e.inner.length?e.inner:e)):this.errors.push(e)}),this.message=this.errors.length>1?`${this.errors.length} errors occurred`:this.errors[0],Error.captureStackTrace&&Error.captureStackTrace(this,pT)}}let pM=e=>{let t=!1;return(...n)=>{t||(t=!0,e(...n))}};function pO(e,t){let{endEarly:n,tests:r,args:i,value:a,errors:o,sort:s,path:u}=e,c=pM(t),l=r.length,f=[];if(o=o||[],!l)return o.length?c(new pT(o,a,u)):c(null,a);for(let d=0;d=0||(i[n]=e[n]);return i}function pR(e){function t(t,n){let{value:r,path:i="",label:a,options:o,originalValue:s,sync:u}=t,c=pP(t,["value","path","label","options","originalValue","sync"]),{name:l,test:f,params:d,message:h}=e,{parent:p,context:b}=o;function m(e){return pD.isRef(e)?e.getValue(r,p,b):e}function g(e={}){let t=pL()(pN({value:r,originalValue:s,label:a,path:e.path||i},d,e.params),m),n=new pT(pT.formatError(e.message||h,t),r,t.path,e.type||l);return n.params=t,n}let v=pN({path:i,parent:p,type:l,createError:g,resolve:m,options:o,originalValue:s},c);if(!u){try{Promise.resolve(f.call(v,r,v)).then(e=>{pT.isError(e)?n(e):e?n(null,e):n(g())})}catch(y){n(y)}return}let w;try{var _;if(w=f.call(v,r,v),"function"==typeof(null==(_=w)?void 0:_.then))throw Error(`Validation test of type: "${v.type}" returned a Promise during a synchronous validate. This test will finish after the validate call has returned`)}catch(E){n(E);return}pT.isError(w)?n(w):w?n(null,w):n(g())}return t.OPTIONS=e,t}pD.prototype.__isYupRef=!0;let pj=e=>e.substr(0,e.length-1).substr(1);function pF(e,t,n,r=n){let i,a,o;return t?((0,pC.forEach)(t,(s,u,c)=>{let l=u?pj(s):s;if((e=e.resolve({context:r,parent:i,value:n})).innerType){let f=c?parseInt(l,10):0;if(n&&f>=n.length)throw Error(`Yup.reach cannot resolve an array item at index: ${s}, in the path: ${t}. because there is no value at that index. `);i=n,n=n&&n[f],e=e.innerType}if(!c){if(!e.fields||!e.fields[l])throw Error(`The schema does not contain the path: ${t}. (failed at: ${o} which is a type: "${e._type}")`);i=n,n=n&&n[l],e=e.fields[l]}a=l,o=u?"["+s+"]":"."+s}),{schema:e,parent:i,parentPath:a}):{parent:i,parentPath:t,schema:e}}class pY{constructor(){this.list=new Set,this.refs=new Map}get size(){return this.list.size+this.refs.size}describe(){let e=[];for(let t of this.list)e.push(t);for(let[,n]of this.refs)e.push(n.describe());return e}toArray(){return Array.from(this.list).concat(Array.from(this.refs.values()))}add(e){pD.isRef(e)?this.refs.set(e.key,e):this.list.add(e)}delete(e){pD.isRef(e)?this.refs.delete(e.key):this.list.delete(e)}has(e,t){if(this.list.has(e))return!0;let n,r=this.refs.values();for(;!(n=r.next()).done;)if(t(n.value)===e)return!0;return!1}clone(){let e=new pY;return e.list=new Set(this.list),e.refs=new Map(this.refs),e}merge(e,t){let n=this.clone();return e.list.forEach(e=>n.add(e)),e.refs.forEach(e=>n.add(e)),t.list.forEach(e=>n.delete(e)),t.refs.forEach(e=>n.delete(e)),n}}function pB(){return(pB=Object.assign||function(e){for(var t=1;t{this.typeError(pf.notType)}),this.type=(null==e?void 0:e.type)||"mixed",this.spec=pB({strip:!1,strict:!1,abortEarly:!0,recursive:!0,nullable:!1,presence:"optional"},null==e?void 0:e.spec)}get _type(){return this.type}_typeCheck(e){return!0}clone(e){if(this._mutate)return e&&Object.assign(this.spec,e),this;let t=Object.create(Object.getPrototypeOf(this));return t.type=this.type,t._typeError=this._typeError,t._whitelistError=this._whitelistError,t._blacklistError=this._blacklistError,t._whitelist=this._whitelist.clone(),t._blacklist=this._blacklist.clone(),t.exclusiveTests=pB({},this.exclusiveTests),t.deps=[...this.deps],t.conditions=[...this.conditions],t.tests=[...this.tests],t.transforms=[...this.transforms],t.spec=pn(pB({},this.spec,e)),t}label(e){var t=this.clone();return t.spec.label=e,t}meta(...e){if(0===e.length)return this.spec.meta;let t=this.clone();return t.spec.meta=Object.assign(t.spec.meta||{},e[0]),t}withMutation(e){let t=this._mutate;this._mutate=!0;let n=e(this);return this._mutate=t,n}concat(e){if(!e||e===this)return this;if(e.type!==this.type&&"mixed"!==this.type)throw TypeError(`You cannot \`concat()\` schema's of different types: ${this.type} and ${e.type}`);let t=this,n=e.clone(),r=pB({},t.spec,n.spec);return n.spec=r,n._typeError||(n._typeError=t._typeError),n._whitelistError||(n._whitelistError=t._whitelistError),n._blacklistError||(n._blacklistError=t._blacklistError),n._whitelist=t._whitelist.merge(e._whitelist,e._blacklist),n._blacklist=t._blacklist.merge(e._blacklist,e._whitelist),n.tests=t.tests,n.exclusiveTests=t.exclusiveTests,n.withMutation(t=>{e.tests.forEach(e=>{t.test(e.OPTIONS)})}),n}isType(e){return!!this.spec.nullable&&null===e||this._typeCheck(e)}resolve(e){let t=this;if(t.conditions.length){let n=t.conditions;(t=t.clone()).conditions=[],t=(t=n.reduce((t,n)=>n.resolve(t,e),t)).resolve(e)}return t}cast(e,t={}){let n=this.resolve(pB({value:e},t)),r=n._cast(e,t);if(void 0!==e&&!1!==t.assert&&!0!==n.isType(r)){let i=pl(e),a=pl(r);throw TypeError(`The value of ${t.path||"field"} could not be cast to a value that satisfies the schema type: "${n._type}". attempted value: ${i} -`+(a!==i?`result of cast: ${a}`:""))}return r}_cast(e,t){let n=void 0===e?e:this.transforms.reduce((t,n)=>n.call(this,t,e,this),e);return void 0===n&&(n=this.getDefault()),n}_validate(e,t={},n){let{sync:r,path:i,from:a=[],originalValue:o=e,strict:s=this.spec.strict,abortEarly:u=this.spec.abortEarly}=t,c=e;s||(c=this._cast(c,pB({assert:!1},t)));let l={value:c,path:i,options:t,originalValue:o,schema:this,label:this.spec.label,sync:r,from:a},f=[];this._typeError&&f.push(this._typeError),this._whitelistError&&f.push(this._whitelistError),this._blacklistError&&f.push(this._blacklistError),pO({args:l,value:c,path:i,sync:r,tests:f,endEarly:u},e=>{if(e)return void n(e,c);pO({tests:this.tests,args:l,path:i,sync:r,value:c,endEarly:u},n)})}validate(e,t,n){let r=this.resolve(pB({},t,{value:e}));return"function"==typeof n?r._validate(e,t,n):new Promise((n,i)=>r._validate(e,t,(e,t)=>{e?i(e):n(t)}))}validateSync(e,t){let n;return this.resolve(pB({},t,{value:e}))._validate(e,pB({},t,{sync:!0}),(e,t)=>{if(e)throw e;n=t}),n}isValid(e,t){return this.validate(e,t).then(()=>!0,e=>{if(pT.isError(e))return!1;throw e})}isValidSync(e,t){try{return this.validateSync(e,t),!0}catch(n){if(pT.isError(n))return!1;throw n}}_getDefault(){let e=this.spec.default;return null==e?e:"function"==typeof e?e.call(this):pn(e)}getDefault(e){return this.resolve(e||{})._getDefault()}default(e){return 0===arguments.length?this._getDefault():this.clone({default:e})}strict(e=!0){var t=this.clone();return t.spec.strict=e,t}_isPresent(e){return null!=e}defined(e=pf.defined){return this.test({message:e,name:"defined",exclusive:!0,test:e=>void 0!==e})}required(e=pf.required){return this.clone({presence:"required"}).withMutation(t=>t.test({message:e,name:"required",exclusive:!0,test(e){return this.schema._isPresent(e)}}))}notRequired(){var e=this.clone({presence:"optional"});return e.tests=e.tests.filter(e=>"required"!==e.OPTIONS.name),e}nullable(e=!0){return this.clone({nullable:!1!==e})}transform(e){var t=this.clone();return t.transforms.push(e),t}test(...e){let t;if(void 0===(t=1===e.length?"function"==typeof e[0]?{test:e[0]}:e[0]:2===e.length?{name:e[0],test:e[1]}:{name:e[0],message:e[1],test:e[2]}).message&&(t.message=pf.default),"function"!=typeof t.test)throw TypeError("`test` is a required parameters");let n=this.clone(),r=pR(t),i=t.exclusive||t.name&&!0===n.exclusiveTests[t.name];if(t.exclusive&&!t.name)throw TypeError("Exclusive tests must provide a unique `name` identifying the test");return t.name&&(n.exclusiveTests[t.name]=!!t.exclusive),n.tests=n.tests.filter(e=>e.OPTIONS.name!==t.name||!i&&e.OPTIONS.test!==r.OPTIONS.test),n.tests.push(r),n}when(e,t){Array.isArray(e)||"string"==typeof e||(t=e,e=".");let n=this.clone(),r=pS(e).map(e=>new pD(e));return r.forEach(e=>{e.isSibling&&n.deps.push(e.key)}),n.conditions.push(new pE(r,t)),n}typeError(e){var t=this.clone();return t._typeError=pR({message:e,name:"typeError",test(e){return!!(void 0===e||this.schema.isType(e))||this.createError({params:{type:this.schema._type}})}}),t}oneOf(e,t=pf.oneOf){var n=this.clone();return e.forEach(e=>{n._whitelist.add(e),n._blacklist.delete(e)}),n._whitelistError=pR({message:t,name:"oneOf",test(e){if(void 0===e)return!0;let t=this.schema._whitelist;return!!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}notOneOf(e,t=pf.notOneOf){var n=this.clone();return e.forEach(e=>{n._blacklist.add(e),n._whitelist.delete(e)}),n._blacklistError=pR({message:t,name:"notOneOf",test(e){let t=this.schema._blacklist;return!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}strip(e=!0){let t=this.clone();return t.spec.strip=e,t}describe(){let e=this.clone(),{label:t,meta:n}=e.spec,r={meta:n,label:t,type:e.type,oneOf:e._whitelist.describe(),notOneOf:e._blacklist.describe(),tests:e.tests.map(e=>({name:e.OPTIONS.name,params:e.OPTIONS.params})).filter((e,t,n)=>n.findIndex(t=>t.name===e.name)===t)};return r}}for(let pH of(pU.prototype.__isYupSchema__=!0,["validate","validateSync"]))pU.prototype[`${pH}At`]=function(e,t,n={}){let{parent:r,parentPath:i,schema:a}=pF(this,e,t,n.context);return a[pH](r&&r[i],pB({},n,{parent:r,path:e}))};for(let p$ of["equals","is"])pU.prototype[p$]=pU.prototype.oneOf;for(let pz of["not","nope"])pU.prototype[pz]=pU.prototype.notOneOf;pU.prototype.optional=pU.prototype.notRequired;let pG=pU;function pW(){return new pG}pW.prototype=pG.prototype;let pK=e=>null==e;function pV(){return new pq}class pq extends pU{constructor(){super({type:"boolean"}),this.withMutation(()=>{this.transform(function(e){if(!this.isType(e)){if(/^(true|1)$/i.test(String(e)))return!0;if(/^(false|0)$/i.test(String(e)))return!1}return e})})}_typeCheck(e){return e instanceof Boolean&&(e=e.valueOf()),"boolean"==typeof e}isTrue(e=pb.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"true"},test:e=>pK(e)||!0===e})}isFalse(e=pb.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"false"},test:e=>pK(e)||!1===e})}}pV.prototype=pq.prototype;let pZ=/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,pX=/^((https?|ftp):)?\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,pJ=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i,pQ=e=>pK(e)||e===e.trim(),p1=({}).toString();function p0(){return new p2}class p2 extends pU{constructor(){super({type:"string"}),this.withMutation(()=>{this.transform(function(e){if(this.isType(e)||Array.isArray(e))return e;let t=null!=e&&e.toString?e.toString():e;return t===p1?e:t})})}_typeCheck(e){return e instanceof String&&(e=e.valueOf()),"string"==typeof e}_isPresent(e){return super._isPresent(e)&&!!e.length}length(e,t=pd.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pK(t)||t.length===this.resolve(e)}})}min(e,t=pd.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t.length>=this.resolve(e)}})}max(e,t=pd.max){return this.test({name:"max",exclusive:!0,message:t,params:{max:e},test(t){return pK(t)||t.length<=this.resolve(e)}})}matches(e,t){let n=!1,r,i;return t&&("object"==typeof t?{excludeEmptyString:n=!1,message:r,name:i}=t:r=t),this.test({name:i||"matches",message:r||pd.matches,params:{regex:e},test:t=>pK(t)||""===t&&n||-1!==t.search(e)})}email(e=pd.email){return this.matches(pZ,{name:"email",message:e,excludeEmptyString:!0})}url(e=pd.url){return this.matches(pX,{name:"url",message:e,excludeEmptyString:!0})}uuid(e=pd.uuid){return this.matches(pJ,{name:"uuid",message:e,excludeEmptyString:!1})}ensure(){return this.default("").transform(e=>null===e?"":e)}trim(e=pd.trim){return this.transform(e=>null!=e?e.trim():e).test({message:e,name:"trim",test:pQ})}lowercase(e=pd.lowercase){return this.transform(e=>pK(e)?e:e.toLowerCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pK(e)||e===e.toLowerCase()})}uppercase(e=pd.uppercase){return this.transform(e=>pK(e)?e:e.toUpperCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pK(e)||e===e.toUpperCase()})}}p0.prototype=p2.prototype;let p3=e=>e!=+e;function p4(){return new p6}class p6 extends pU{constructor(){super({type:"number"}),this.withMutation(()=>{this.transform(function(e){let t=e;if("string"==typeof t){if(""===(t=t.replace(/\s/g,"")))return NaN;t=+t}return this.isType(t)?t:parseFloat(t)})})}_typeCheck(e){return e instanceof Number&&(e=e.valueOf()),"number"==typeof e&&!p3(e)}min(e,t=ph.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t>=this.resolve(e)}})}max(e,t=ph.max){return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pK(t)||t<=this.resolve(e)}})}lessThan(e,t=ph.lessThan){return this.test({message:t,name:"max",exclusive:!0,params:{less:e},test(t){return pK(t)||tthis.resolve(e)}})}positive(e=ph.positive){return this.moreThan(0,e)}negative(e=ph.negative){return this.lessThan(0,e)}integer(e=ph.integer){return this.test({name:"integer",message:e,test:e=>pK(e)||Number.isInteger(e)})}truncate(){return this.transform(e=>pK(e)?e:0|e)}round(e){var t,n=["ceil","floor","round","trunc"];if("trunc"===(e=(null==(t=e)?void 0:t.toLowerCase())||"round"))return this.truncate();if(-1===n.indexOf(e.toLowerCase()))throw TypeError("Only valid options for round() are: "+n.join(", "));return this.transform(t=>pK(t)?t:Math[e](t))}}p4.prototype=p6.prototype;var p5=/^(\d{4}|[+\-]\d{6})(?:-?(\d{2})(?:-?(\d{2}))?)?(?:[ T]?(\d{2}):?(\d{2})(?::?(\d{2})(?:[,\.](\d{1,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?)?)?$/;function p8(e){var t,n,r=[1,4,5,6,7,10,11],i=0;if(n=p5.exec(e)){for(var a,o=0;a=r[o];++o)n[a]=+n[a]||0;n[2]=(+n[2]||1)-1,n[3]=+n[3]||1,n[7]=n[7]?String(n[7]).substr(0,3):0,(void 0===n[8]||""===n[8])&&(void 0===n[9]||""===n[9])?t=+new Date(n[1],n[2],n[3],n[4],n[5],n[6],n[7]):("Z"!==n[8]&&void 0!==n[9]&&(i=60*n[10]+n[11],"+"===n[9]&&(i=0-i)),t=Date.UTC(n[1],n[2],n[3],n[4],n[5]+i,n[6],n[7]))}else t=Date.parse?Date.parse(e):NaN;return t}let p9=new Date(""),p7=e=>"[object Date]"===Object.prototype.toString.call(e);function be(){return new bt}class bt extends pU{constructor(){super({type:"date"}),this.withMutation(()=>{this.transform(function(e){return this.isType(e)?e:(e=p8(e),isNaN(e)?p9:new Date(e))})})}_typeCheck(e){return p7(e)&&!isNaN(e.getTime())}prepareParam(e,t){let n;if(pD.isRef(e))n=e;else{let r=this.cast(e);if(!this._typeCheck(r))throw TypeError(`\`${t}\` must be a Date or a value that can be \`cast()\` to a Date`);n=r}return n}min(e,t=pp.min){let n=this.prepareParam(e,"min");return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(e){return pK(e)||e>=this.resolve(n)}})}max(e,t=pp.max){var n=this.prepareParam(e,"max");return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(e){return pK(e)||e<=this.resolve(n)}})}}bt.INVALID_DATE=p9,be.prototype=bt.prototype,be.INVALID_DATE=p9;var bn=n(11865),br=n.n(bn),bi=n(68929),ba=n.n(bi),bo=n(67523),bs=n.n(bo),bu=n(94633),bc=n.n(bu);function bl(e,t=[]){let n=[],r=[];function i(e,i){var a=(0,pC.split)(e)[0];~r.indexOf(a)||r.push(a),~t.indexOf(`${i}-${a}`)||n.push([i,a])}for(let a in e)if(py()(e,a)){let o=e[a];~r.indexOf(a)||r.push(a),pD.isRef(o)&&o.isSibling?i(o.path,a):pw(o)&&"deps"in o&&o.deps.forEach(e=>i(e,a))}return bc().array(r,n).reverse()}function bf(e,t){let n=1/0;return e.some((e,r)=>{var i;if((null==(i=t.path)?void 0:i.indexOf(e))!==-1)return n=r,!0}),n}function bd(e){return(t,n)=>bf(e,t)-bf(e,n)}function bh(){return(bh=Object.assign||function(e){for(var t=1;t"[object Object]"===Object.prototype.toString.call(e);function bb(e,t){let n=Object.keys(e.fields);return Object.keys(t).filter(e=>-1===n.indexOf(e))}let bm=bd([]);class bg extends pU{constructor(e){super({type:"object"}),this.fields=Object.create(null),this._sortErrors=bm,this._nodes=[],this._excludedEdges=[],this.withMutation(()=>{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null}),e&&this.shape(e)})}_typeCheck(e){return bp(e)||"function"==typeof e}_cast(e,t={}){var n;let r=super._cast(e,t);if(void 0===r)return this.getDefault();if(!this._typeCheck(r))return r;let i=this.fields,a=null!=(n=t.stripUnknown)?n:this.spec.noUnknown,o=this._nodes.concat(Object.keys(r).filter(e=>-1===this._nodes.indexOf(e))),s={},u=bh({},t,{parent:s,__validating:t.__validating||!1}),c=!1;for(let l of o){let f=i[l],d=py()(r,l);if(f){let h,p=r[l];u.path=(t.path?`${t.path}.`:"")+l;let b="spec"in(f=f.resolve({value:p,context:t.context,parent:s}))?f.spec:void 0,m=null==b?void 0:b.strict;if(null==b?void 0:b.strip){c=c||l in r;continue}void 0!==(h=t.__validating&&m?r[l]:f.cast(r[l],u))&&(s[l]=h)}else d&&!a&&(s[l]=r[l]);s[l]!==r[l]&&(c=!0)}return c?s:r}_validate(e,t={},n){let r=[],{sync:i,from:a=[],originalValue:o=e,abortEarly:s=this.spec.abortEarly,recursive:u=this.spec.recursive}=t;a=[{schema:this,value:o},...a],t.__validating=!0,t.originalValue=o,t.from=a,super._validate(e,t,(e,c)=>{if(e){if(!pT.isError(e)||s)return void n(e,c);r.push(e)}if(!u||!bp(c)){n(r[0]||null,c);return}o=o||c;let l=this._nodes.map(e=>(n,r)=>{let i=-1===e.indexOf(".")?(t.path?`${t.path}.`:"")+e:`${t.path||""}["${e}"]`,s=this.fields[e];if(s&&"validate"in s){s.validate(c[e],bh({},t,{path:i,from:a,strict:!0,parent:c,originalValue:o[e]}),r);return}r(null)});pO({sync:i,tests:l,value:c,errors:r,endEarly:s,sort:this._sortErrors,path:t.path},n)})}clone(e){let t=super.clone(e);return t.fields=bh({},this.fields),t._nodes=this._nodes,t._excludedEdges=this._excludedEdges,t._sortErrors=this._sortErrors,t}concat(e){let t=super.concat(e),n=t.fields;for(let[r,i]of Object.entries(this.fields)){let a=n[r];void 0===a?n[r]=i:a instanceof pU&&i instanceof pU&&(n[r]=i.concat(a))}return t.withMutation(()=>t.shape(n))}getDefaultFromShape(){let e={};return this._nodes.forEach(t=>{let n=this.fields[t];e[t]="default"in n?n.getDefault():void 0}),e}_getDefault(){return"default"in this.spec?super._getDefault():this._nodes.length?this.getDefaultFromShape():void 0}shape(e,t=[]){let n=this.clone(),r=Object.assign(n.fields,e);if(n.fields=r,n._sortErrors=bd(Object.keys(r)),t.length){Array.isArray(t[0])||(t=[t]);let i=t.map(([e,t])=>`${e}-${t}`);n._excludedEdges=n._excludedEdges.concat(i)}return n._nodes=bl(r,n._excludedEdges),n}pick(e){let t={};for(let n of e)this.fields[n]&&(t[n]=this.fields[n]);return this.clone().withMutation(e=>(e.fields={},e.shape(t)))}omit(e){let t=this.clone(),n=t.fields;for(let r of(t.fields={},e))delete n[r];return t.withMutation(()=>t.shape(n))}from(e,t,n){let r=(0,pC.getter)(e,!0);return this.transform(i=>{if(null==i)return i;let a=i;return py()(i,e)&&(a=bh({},i),n||delete a[e],a[t]=r(i)),a})}noUnknown(e=!0,t=pm.noUnknown){"string"==typeof e&&(t=e,e=!0);let n=this.test({name:"noUnknown",exclusive:!0,message:t,test(t){if(null==t)return!0;let n=bb(this.schema,t);return!e||0===n.length||this.createError({params:{unknown:n.join(", ")}})}});return n.spec.noUnknown=e,n}unknown(e=!0,t=pm.noUnknown){return this.noUnknown(!e,t)}transformKeys(e){return this.transform(t=>t&&bs()(t,(t,n)=>e(n)))}camelCase(){return this.transformKeys(ba())}snakeCase(){return this.transformKeys(br())}constantCase(){return this.transformKeys(e=>br()(e).toUpperCase())}describe(){let e=super.describe();return e.fields=pL()(this.fields,e=>e.describe()),e}}function bv(e){return new bg(e)}function by(){return(by=Object.assign||function(e){for(var t=1;t{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null})})}_typeCheck(e){return Array.isArray(e)}get _subType(){return this.innerType}_cast(e,t){let n=super._cast(e,t);if(!this._typeCheck(n)||!this.innerType)return n;let r=!1,i=n.map((e,n)=>{let i=this.innerType.cast(e,by({},t,{path:`${t.path||""}[${n}]`}));return i!==e&&(r=!0),i});return r?i:n}_validate(e,t={},n){var r,i;let a=[],o=t.sync,s=t.path,u=this.innerType,c=null!=(r=t.abortEarly)?r:this.spec.abortEarly,l=null!=(i=t.recursive)?i:this.spec.recursive,f=null!=t.originalValue?t.originalValue:e;super._validate(e,t,(e,r)=>{if(e){if(!pT.isError(e)||c)return void n(e,r);a.push(e)}if(!l||!u||!this._typeCheck(r)){n(a[0]||null,r);return}f=f||r;let i=Array(r.length);for(let d=0;du.validate(h,b,t)}pO({sync:o,path:s,value:r,errors:a,endEarly:c,tests:i},n)})}clone(e){let t=super.clone(e);return t.innerType=this.innerType,t}concat(e){let t=super.concat(e);return t.innerType=this.innerType,e.innerType&&(t.innerType=t.innerType?t.innerType.concat(e.innerType):e.innerType),t}of(e){let t=this.clone();if(!pw(e))throw TypeError("`array.of()` sub-schema must be a valid yup schema not: "+pl(e));return t.innerType=e,t}length(e,t=pg.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pK(t)||t.length===this.resolve(e)}})}min(e,t){return t=t||pg.min,this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t.length>=this.resolve(e)}})}max(e,t){return t=t||pg.max,this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pK(t)||t.length<=this.resolve(e)}})}ensure(){return this.default(()=>[]).transform((e,t)=>this._typeCheck(e)?e:null==t?[]:[].concat(t))}compact(e){let t=e?(t,n,r)=>!e(t,n,r):e=>!!e;return this.transform(e=>null!=e?e.filter(t):e)}describe(){let e=super.describe();return this.innerType&&(e.innerType=this.innerType.describe()),e}nullable(e=!0){return super.nullable(e)}defined(){return super.defined()}required(e){return super.required(e)}}bw.prototype=b_.prototype;var bE=bv().shape({name:p0().required("Required"),url:p0().required("Required")}),bS=function(e){var t=e.initialValues,n=e.onSubmit,r=e.submitButtonText,i=e.nameDisabled,a=void 0!==i&&i;return l.createElement(hT,{initialValues:t,validationSchema:bE,onSubmit:n},function(e){var t=e.isSubmitting;return l.createElement(l.Fragment,null,l.createElement(hR,{"data-testid":"bridge-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hP,{component:hX,id:"name",name:"name",label:"Name",disabled:a,required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hP,{component:hX,id:"url",name:"url",label:"Bridge URL",placeholder:"https://",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"url-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:7},l.createElement(hP,{component:hX,id:"minimumContractPayment",name:"minimumContractPayment",label:"Minimum Contract Payment",placeholder:"0",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"minimumContractPayment-helper-text"}})),l.createElement(d.Z,{item:!0,xs:7},l.createElement(hP,{component:hX,id:"confirmations",name:"confirmations",label:"Confirmations",placeholder:"0",type:"number",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"confirmations-helper-text"}})))),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},r)))))})},bk=function(e){var t=e.bridge,n=e.onSubmit,r={name:t.name,url:t.url,minimumContractPayment:t.minimumContractPayment,confirmations:t.confirmations};return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:40},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Edit Bridge",action:l.createElement(aA.Z,{component:tz,href:"/bridges/".concat(t.id)},"Cancel")}),l.createElement(aW.Z,null,l.createElement(bS,{nameDisabled:!0,initialValues:r,onSubmit:n,submitButtonText:"Save Bridge"}))))))};function bx(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]&&arguments[0],t=e?function(){return l.createElement(x.default,{variant:"body1"},"Loading...")}:function(){return null};return{isLoading:e,LoadingPlaceholder:t}},mc=n(76023);function ml(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function mB(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=4?[e[0],e[1],e[2],e[3],"".concat(e[0],".").concat(e[1]),"".concat(e[0],".").concat(e[2]),"".concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[0]),"".concat(e[1],".").concat(e[2]),"".concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[1]),"".concat(e[2],".").concat(e[3]),"".concat(e[3],".").concat(e[0]),"".concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[0]),"".concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[1],".").concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[2],".").concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[3],".").concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[2],".").concat(e[1],".").concat(e[0])]:void 0}var mZ={};function mX(e){if(0===e.length||1===e.length)return e;var t=e.join(".");return mZ[t]||(mZ[t]=mq(e)),mZ[t]}function mJ(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0;return mX(e.filter(function(e){return"token"!==e})).reduce(function(e,t){return mK({},e,n[t])},t)}function mQ(e){return e.join(" ")}function m1(e,t){var n=0;return function(r){return n+=1,r.map(function(r,i){return m0({node:r,stylesheet:e,useInlineStyles:t,key:"code-segment-".concat(n,"-").concat(i)})})}}function m0(e){var t=e.node,n=e.stylesheet,r=e.style,i=void 0===r?{}:r,a=e.useInlineStyles,o=e.key,s=t.properties,u=t.type,c=t.tagName,f=t.value;if("text"===u)return f;if(c){var d,h=m1(n,a);if(a){var p=Object.keys(n).reduce(function(e,t){return t.split(".").forEach(function(t){e.includes(t)||e.push(t)}),e},[]),b=s.className&&s.className.includes("token")?["token"]:[],m=s.className&&b.concat(s.className.filter(function(e){return!p.includes(e)}));d=mK({},s,{className:mQ(m)||void 0,style:mJ(s.className,Object.assign({},s.style,i),n)})}else d=mK({},s,{className:mQ(s.className)});var g=h(t.children);return l.createElement(c,(0,mV.Z)({key:o},d),g)}}let m2=function(e,t){return -1!==e.listLanguages().indexOf(t)};var m3=/\n/g;function m4(e){return e.match(m3)}function m6(e){var t=e.lines,n=e.startingLineNumber,r=e.style;return t.map(function(e,t){var i=t+n;return l.createElement("span",{key:"line-".concat(t),className:"react-syntax-highlighter-line-number",style:"function"==typeof r?r(i):r},"".concat(i,"\n"))})}function m5(e){var t=e.codeString,n=e.codeStyle,r=e.containerStyle,i=void 0===r?{float:"left",paddingRight:"10px"}:r,a=e.numberStyle,o=void 0===a?{}:a,s=e.startingLineNumber;return l.createElement("code",{style:Object.assign({},n,i)},m6({lines:t.replace(/\n$/,"").split("\n"),style:o,startingLineNumber:s}))}function m8(e){return"".concat(e.toString().length,".25em")}function m9(e,t){return{type:"element",tagName:"span",properties:{key:"line-number--".concat(e),className:["comment","linenumber","react-syntax-highlighter-line-number"],style:t},children:[{type:"text",value:e}]}}function m7(e,t,n){var r,i={display:"inline-block",minWidth:m8(n),paddingRight:"1em",textAlign:"right",userSelect:"none"};return mK({},i,"function"==typeof e?e(t):e)}function ge(e){var t=e.children,n=e.lineNumber,r=e.lineNumberStyle,i=e.largestLineNumber,a=e.showInlineLineNumbers,o=e.lineProps,s=void 0===o?{}:o,u=e.className,c=void 0===u?[]:u,l=e.showLineNumbers,f=e.wrapLongLines,d="function"==typeof s?s(n):s;if(d.className=c,n&&a){var h=m7(r,n,i);t.unshift(m9(n,h))}return f&l&&(d.style=mK({},d.style,{display:"flex"})),{type:"element",tagName:"span",properties:d,children:t}}function gt(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],r=0;r2&&void 0!==arguments[2]?arguments[2]:[];return ge({children:e,lineNumber:t,lineNumberStyle:s,largestLineNumber:o,showInlineLineNumbers:i,lineProps:n,className:a,showLineNumbers:r,wrapLongLines:u})}function b(e,t){if(r&&t&&i){var n=m7(s,t,o);e.unshift(m9(t,n))}return e}function m(e,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return t||r.length>0?p(e,n,r):b(e,n)}for(var g=function(){var e=l[h],t=e.children[0].value;if(m4(t)){var n=t.split("\n");n.forEach(function(t,i){var o=r&&f.length+a,s={type:"text",value:"".concat(t,"\n")};if(0===i){var u=l.slice(d+1,h).concat(ge({children:[s],className:e.properties.className})),c=m(u,o);f.push(c)}else if(i===n.length-1){if(l[h+1]&&l[h+1].children&&l[h+1].children[0]){var p={type:"text",value:"".concat(t)},b=ge({children:[p],className:e.properties.className});l.splice(h+1,0,b)}else{var g=[s],v=m(g,o,e.properties.className);f.push(v)}}else{var y=[s],w=m(y,o,e.properties.className);f.push(w)}}),d=h}h++};h code[class*="language-"]':{background:"#f5f2f0",padding:".1em",borderRadius:".3em",whiteSpace:"normal"},comment:{color:"slategray"},prolog:{color:"slategray"},doctype:{color:"slategray"},cdata:{color:"slategray"},punctuation:{color:"#999"},namespace:{Opacity:".7"},property:{color:"#905"},tag:{color:"#905"},boolean:{color:"#905"},number:{color:"#905"},constant:{color:"#905"},symbol:{color:"#905"},deleted:{color:"#905"},selector:{color:"#690"},"attr-name":{color:"#690"},string:{color:"#690"},char:{color:"#690"},builtin:{color:"#690"},inserted:{color:"#690"},operator:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},entity:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)",cursor:"help"},url:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".language-css .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".style .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},atrule:{color:"#07a"},"attr-value":{color:"#07a"},keyword:{color:"#07a"},function:{color:"#DD4A68"},"class-name":{color:"#DD4A68"},regex:{color:"#e90"},important:{color:"#e90",fontWeight:"bold"},variable:{color:"#e90"},bold:{fontWeight:"bold"},italic:{fontStyle:"italic"}};var gu=n(98695),gc=n.n(gu);let gl=["abap","abnf","actionscript","ada","agda","al","antlr4","apacheconf","apl","applescript","aql","arduino","arff","asciidoc","asm6502","aspnet","autohotkey","autoit","bash","basic","batch","bbcode","birb","bison","bnf","brainfuck","brightscript","bro","bsl","c","cil","clike","clojure","cmake","coffeescript","concurnas","cpp","crystal","csharp","csp","css-extras","css","cypher","d","dart","dax","dhall","diff","django","dns-zone-file","docker","ebnf","editorconfig","eiffel","ejs","elixir","elm","erb","erlang","etlua","excel-formula","factor","firestore-security-rules","flow","fortran","fsharp","ftl","gcode","gdscript","gedcom","gherkin","git","glsl","gml","go","graphql","groovy","haml","handlebars","haskell","haxe","hcl","hlsl","hpkp","hsts","http","ichigojam","icon","iecst","ignore","inform7","ini","io","j","java","javadoc","javadoclike","javascript","javastacktrace","jolie","jq","js-extras","js-templates","jsdoc","json","json5","jsonp","jsstacktrace","jsx","julia","keyman","kotlin","latex","latte","less","lilypond","liquid","lisp","livescript","llvm","lolcode","lua","makefile","markdown","markup-templating","markup","matlab","mel","mizar","mongodb","monkey","moonscript","n1ql","n4js","nand2tetris-hdl","naniscript","nasm","neon","nginx","nim","nix","nsis","objectivec","ocaml","opencl","oz","parigp","parser","pascal","pascaligo","pcaxis","peoplecode","perl","php-extras","php","phpdoc","plsql","powerquery","powershell","processing","prolog","properties","protobuf","pug","puppet","pure","purebasic","purescript","python","q","qml","qore","r","racket","reason","regex","renpy","rest","rip","roboconf","robotframework","ruby","rust","sas","sass","scala","scheme","scss","shell-session","smali","smalltalk","smarty","sml","solidity","solution-file","soy","sparql","splunk-spl","sqf","sql","stan","stylus","swift","t4-cs","t4-templating","t4-vb","tap","tcl","textile","toml","tsx","tt2","turtle","twig","typescript","typoscript","unrealscript","vala","vbnet","velocity","verilog","vhdl","vim","visual-basic","warpscript","wasm","wiki","xeora","xml-doc","xojo","xquery","yaml","yang","zig"];var gf=go(gc(),gs);gf.supportedLanguages=gl;let gd=gf;var gh=n(64566);function gp(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function gb(){var e=gp(["\n query FetchConfigV2 {\n configv2 {\n user\n effective\n }\n }\n"]);return gb=function(){return e},e}var gm=n0(gb()),gg=function(e){var t=e.children;return l.createElement(ir.Z,null,l.createElement(r7.default,{component:"th",scope:"row",colSpan:3},t))},gv=function(){return l.createElement(gg,null,"...")},gy=function(e){var t=e.children;return l.createElement(gg,null,t)},gw=function(e){var t=e.loading,n=e.toml,r=e.error,i=void 0===r?"":r,a=e.title,o=e.expanded;if(i)return l.createElement(gy,null,i);if(t)return l.createElement(gv,null);a||(a="TOML");var s={display:"block"};return l.createElement(x.default,null,l.createElement(mP.Z,{defaultExpanded:o},l.createElement(mR.Z,{expandIcon:l.createElement(gh.Z,null)},a),l.createElement(mj.Z,{style:s},l.createElement(gd,{language:"toml",style:gs},n))))},g_=function(){var e=rv(gm,{fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return(null==t?void 0:t.configv2.effective)=="N/A"?l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"TOML Configuration"}),l.createElement(gw,{title:"V2 config dump:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0})))):l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"TOML Configuration"}),l.createElement(gw,{title:"User specified:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0,expanded:!0}),l.createElement(gw,{title:"Effective (with defaults):",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.effective,showHead:!0})))))},gE=n(34823),gS=function(e){return(0,b.createStyles)({cell:{paddingTop:1.5*e.spacing.unit,paddingBottom:1.5*e.spacing.unit}})},gk=(0,b.withStyles)(gS)(function(e){var t=e.classes,n=(0,A.I0)();(0,l.useEffect)(function(){n((0,ty.DQ)())});var r=(0,A.v9)(gE.N,A.wU);return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Node"}),l.createElement(r8.Z,null,l.createElement(r9.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,{className:t.cell},l.createElement(x.default,null,"Version"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.version))),l.createElement(ir.Z,null,l.createElement(r7.default,{className:t.cell},l.createElement(x.default,null,"SHA"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.commitSHA))))))}),gx=function(){return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,sm:12,md:8},l.createElement(d.Z,{container:!0},l.createElement(g_,null))),l.createElement(d.Z,{item:!0,sm:12,md:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gk,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mN,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mE,null))))))},gT=function(){return l.createElement(gx,null)},gM=function(){return l.createElement(gT,null)},gO=n(44431),gA=1e18,gL=function(e){return new gO.BigNumber(e).dividedBy(gA).toFixed(8)},gC=function(e){var t=e.keys,n=e.chainID,r=e.hideHeaderTitle;return l.createElement(l.Fragment,null,l.createElement(sl.Z,{title:!r&&"Account Balances",subheader:"Chain ID "+n}),l.createElement(aW.Z,null,l.createElement(w.default,{dense:!1,disablePadding:!0},t&&t.map(function(e,r){return l.createElement(l.Fragment,null,l.createElement(_.default,{disableGutters:!0,key:["acc-balance",n.toString(),r.toString()].join("-")},l.createElement(E.Z,{primary:l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(op,{title:"Address"}),l.createElement(ob,{value:e.address})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(op,{title:"Native Token Balance"}),l.createElement(ob,{value:e.ethBalance||"--"})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(op,{title:"LINK Balance"}),l.createElement(ob,{value:e.linkBalance?gL(e.linkBalance):"--"}))))})),r+1s&&l.createElement(gB.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,{className:r.footer},l.createElement(aA.Z,{href:"/runs",component:tz},"View More"))))))});function vt(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vn(){var e=vt(["\n ","\n query FetchRecentJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...RecentJobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return vn=function(){return e},e}var vr=5,vi=n0(vn(),g9),va=function(){var e=rv(vi,{variables:{offset:0,limit:vr},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(ve,{data:t,errorMsg:null==r?void 0:r.message,loading:n,maxRunsSize:vr})},vo=function(e){return(0,b.createStyles)({style:{textAlign:"center",padding:2.5*e.spacing.unit,position:"fixed",left:"0",bottom:"0",width:"100%",borderRadius:0},bareAnchor:{color:e.palette.common.black,textDecoration:"none"}})},vs=(0,b.withStyles)(vo)(function(e){var t=e.classes,n=(0,A.v9)(gE.N,A.wU),r=(0,A.I0)();return(0,l.useEffect)(function(){r((0,ty.DQ)())}),l.createElement(ii.default,{className:t.style},l.createElement(x.default,null,"Chainlink Node ",n.version," at commit"," ",l.createElement("a",{target:"_blank",rel:"noopener noreferrer",href:"https://github.com/smartcontractkit/chainlink/commit/".concat(n.commitSHA),className:t.bareAnchor},n.commitSHA)))}),vu=function(e){return(0,b.createStyles)({cell:{borderColor:e.palette.divider,borderTop:"1px solid",borderBottom:"none",paddingTop:2*e.spacing.unit,paddingBottom:2*e.spacing.unit,paddingLeft:2*e.spacing.unit},block:{display:"block"},overflowEllipsis:{textOverflow:"ellipsis",overflow:"hidden"}})},vc=(0,b.withStyles)(vu)(function(e){var t=e.classes,n=e.job;return l.createElement(ir.Z,null,l.createElement(r7.default,{scope:"row",className:t.cell},l.createElement(d.Z,{container:!0,spacing:0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(ih,{href:"/jobs/".concat(n.id),classes:{linkContent:t.block}},l.createElement(x.default,{className:t.overflowEllipsis,variant:"body1",component:"span",color:"primary"},n.name||n.id))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,{variant:"body1",color:"textSecondary"},"Created ",l.createElement(aO,{tooltip:!0},n.createdAt))))))});function vl(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vf(){var e=vl(["\n fragment RecentJobsPayload_ResultsFields on Job {\n id\n name\n createdAt\n }\n"]);return vf=function(){return e},e}var vd=n0(vf()),vh=function(){return(0,b.createStyles)({cardHeader:{borderBottom:0},table:{tableLayout:"fixed"}})},vp=(0,b.withStyles)(vh)(function(e){var t,n,r=e.classes,i=e.data,a=e.errorMsg,o=e.loading;return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Recent Jobs",className:r.cardHeader}),l.createElement(r8.Z,{className:r.table},l.createElement(r9.Z,null,l.createElement(g$,{visible:o}),l.createElement(gz,{visible:(null===(t=null==i?void 0:i.jobs.results)||void 0===t?void 0:t.length)===0},"No recently created jobs"),l.createElement(gU,{msg:a}),null===(n=null==i?void 0:i.jobs.results)||void 0===n?void 0:n.map(function(e,t){return l.createElement(vc,{job:e,key:t})}))))});function vb(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vm(){var e=vb(["\n ","\n query FetchRecentJobs($offset: Int, $limit: Int) {\n jobs(offset: $offset, limit: $limit) {\n results {\n ...RecentJobsPayload_ResultsFields\n }\n }\n }\n"]);return vm=function(){return e},e}var vg=5,vv=n0(vm(),vd),vy=function(){var e=rv(vv,{variables:{offset:0,limit:vg},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(vp,{data:t,errorMsg:null==r?void 0:r.message,loading:n})},vw=function(){return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:8},l.createElement(va,null)),l.createElement(d.Z,{item:!0,xs:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gY,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(vy,null))))),l.createElement(vs,null))},v_=function(){return l.createElement(vw,null)},vE=function(){return l.createElement(v_,null)},vS=n(87239),vk=function(e){switch(e){case"DirectRequestSpec":return"Direct Request";case"FluxMonitorSpec":return"Flux Monitor";default:return e.replace(/Spec$/,"")}},vx=n(5022),vT=n(78718),vM=n.n(vT);function vO(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1?t-1:0),r=1;r1?t-1:0),r=1;re.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&n.map(function(e){return l.createElement(ir.Z,{key:e.id,style:{cursor:"pointer"},onClick:function(){return r.push("/runs/".concat(e.id))}},l.createElement(r7.default,{className:t.idCell,scope:"row"},l.createElement("div",{className:t.runDetails},l.createElement(x.default,{variant:"h5",color:"primary",component:"span"},e.id))),l.createElement(r7.default,{className:t.stampCell},l.createElement(x.default,{variant:"body1",color:"textSecondary",className:t.stamp},"Created ",l.createElement(aO,{tooltip:!0},e.createdAt))),l.createElement(r7.default,{className:t.statusCell,scope:"row"},l.createElement(x.default,{variant:"body1",className:O()(t.status,yh(t,e.status))},e.status.toLowerCase())))})))}),yb=n(16839),ym=n.n(yb);function yg(e){var t=e.replace(/\w+\s*=\s*<([^>]|[\r\n])*>/g,""),n=ym().read(t),r=n.edges();return n.nodes().map(function(e){var t={id:e,parentIds:r.filter(function(t){return t.w===e}).map(function(e){return e.v})};return Object.keys(n.node(e)).length>0&&(t.attributes=n.node(e)),t})}var yv=n(94164),yy=function(e){var t=e.data,n=[];return(null==t?void 0:t.attributes)&&Object.keys(t.attributes).forEach(function(e){var r;n.push(l.createElement("div",{key:e},l.createElement(x.default,{variant:"body1",color:"textSecondary",component:"div"},l.createElement("b",null,e,":")," ",null===(r=t.attributes)||void 0===r?void 0:r[e])))}),l.createElement("div",null,t&&l.createElement(x.default,{variant:"body1",color:"textPrimary"},l.createElement("b",null,t.id)),n)},yw=n(73343),y_=n(3379),yE=n.n(y_);function yS(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nwindow.innerWidth?u-r.getBoundingClientRect().width-a:u+a,n=c+r.getBoundingClientRect().height+i>window.innerHeight?c-r.getBoundingClientRect().height-a:c+a,r.style.opacity=String(1),r.style.top="".concat(n,"px"),r.style.left="".concat(t,"px"),r.style.zIndex=String(1)}},h=function(e){var t=document.getElementById("tooltip-d3-chart-".concat(e));t&&(t.style.opacity=String(0),t.style.zIndex=String(-1))};return l.createElement("div",{style:{fontFamily:"sans-serif",fontWeight:"normal"}},l.createElement(yv.kJ,{id:"task-list-graph-d3",data:i,config:s,onMouseOverNode:d,onMouseOutNode:h},"D3 chart"),n.map(function(e){return l.createElement("div",{key:"d3-tooltip-key-".concat(e.id),id:"tooltip-d3-chart-".concat(e.id),style:{position:"absolute",opacity:"0",border:"1px solid rgba(0, 0, 0, 0.1)",padding:yw.r.spacing.unit,background:"white",borderRadius:5,zIndex:-1,inlineSize:"min-content"}},l.createElement(yy,{data:e}))}))};function yL(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nyY&&l.createElement("div",{className:t.runDetails},l.createElement(aA.Z,{href:"/jobs/".concat(n.id,"/runs"),component:tz},"View more")))),l.createElement(d.Z,{item:!0,xs:12,sm:6},l.createElement(yF,{observationSource:n.observationSource})))});function yH(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]?arguments[0]:"";try{return vx.parse(e),!0}catch(t){return!1}})}),wW=function(e){var t=e.initialValues,n=e.onSubmit,r=e.onTOMLChange;return l.createElement(hT,{initialValues:t,validationSchema:wG,onSubmit:n},function(e){var t=e.isSubmitting,n=e.values;return r&&r(n.toml),l.createElement(hR,{"data-testid":"job-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"toml",name:"toml",label:"Job Spec (TOML)",required:!0,fullWidth:!0,multiline:!0,rows:10,rowsMax:25,variant:"outlined",autoComplete:"off",FormHelperTextProps:{"data-testid":"toml-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},"Create Job"))))})},wK=n(50109),wV="persistSpec";function wq(e){var t=e.query,n=new URLSearchParams(t).get("definition");return n?(wK.t8(wV,n),{toml:n}):{toml:wK.U2(wV)||""}}var wZ=function(e){var t=e.onSubmit,n=e.onTOMLChange,r=wq({query:(0,h.TH)().search}),i=function(e){var t=e.replace(/[\u200B-\u200D\uFEFF]/g,"");wK.t8("".concat(wV),t),n&&n(t)};return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"New Job"}),l.createElement(aW.Z,null,l.createElement(wW,{initialValues:r,onSubmit:t,onTOMLChange:i})))};function wX(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n1&&void 0!==arguments[1]?arguments[1]:{},n=t.start,r=void 0===n?6:n,i=t.end,a=void 0===i?4:i;return e.substring(0,r)+"..."+e.substring(e.length-a)}function _M(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(_W,e)},_V=function(){var e=_K({fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error,i=e.refetch;return l.createElement(_U,{loading:n,data:t,errorMsg:null==r?void 0:r.message,refetch:i})},_q=function(e){var t=e.csaKey;return l.createElement(ir.Z,{hover:!0},l.createElement(r7.default,null,l.createElement(x.default,{variant:"body1"},t.publicKey," ",l.createElement(_x,{data:t.publicKey}))))};function _Z(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function _X(){var e=_Z(["\n fragment CSAKeysPayload_ResultsFields on CSAKey {\n id\n publicKey\n }\n"]);return _X=function(){return e},e}var _J=n0(_X()),_Q=function(e){var t,n,r,i=e.data,a=e.errorMsg,o=e.loading,s=e.onCreate;return l.createElement(r5.Z,null,l.createElement(sl.Z,{action:(null===(t=null==i?void 0:i.csaKeys.results)||void 0===t?void 0:t.length)===0&&l.createElement(ok.default,{variant:"outlined",color:"primary",onClick:s},"New CSA Key"),title:"CSA Key",subheader:"Manage your CSA Key"}),l.createElement(r8.Z,null,l.createElement(ie.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,null,"Public Key"))),l.createElement(r9.Z,null,l.createElement(g$,{visible:o}),l.createElement(gz,{visible:(null===(n=null==i?void 0:i.csaKeys.results)||void 0===n?void 0:n.length)===0}),l.createElement(gU,{msg:a}),null===(r=null==i?void 0:i.csaKeys.results)||void 0===r?void 0:r.map(function(e,t){return l.createElement(_q,{csaKey:e,key:t})}))))};function _1(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(EM,e)};function EA(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(EJ,e)},E3=function(){return oo(EQ)},E4=function(){return oo(E1)},E6=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return rv(E0,e)};function E5(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(SK,e)};function Sq(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function kV(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}var kq=function(e){var t=e.run,n=l.useMemo(function(){var e=t.inputs,n=t.outputs,r=t.taskRuns,i=kK(t,["inputs","outputs","taskRuns"]),a={};try{a=JSON.parse(e)}catch(o){a={}}return kW(kz({},i),{inputs:a,outputs:n,taskRuns:r})},[t]);return l.createElement(r5.Z,null,l.createElement(aW.Z,null,l.createElement(kH,{object:n})))};function kZ(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function kX(e){for(var t=1;t0&&l.createElement(kr,{errors:t.allErrors})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(h.rs,null,l.createElement(h.AW,{path:"".concat(n,"/json")},l.createElement(kq,{run:t})),l.createElement(h.AW,{path:n},t.taskRuns.length>0&&l.createElement(kN,{taskRuns:t.taskRuns,observationSource:t.job.observationSource}))))))))};function k5(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function k8(){var e=k5(["\n ","\n query FetchJobRun($id: ID!) {\n jobRun(id: $id) {\n __typename\n ... on JobRun {\n ...JobRunPayload_Fields\n }\n ... on NotFoundError {\n message\n }\n }\n }\n"]);return k8=function(){return e},e}var k9=n0(k8(),k4),k7=function(){var e=rv(k9,{variables:{id:(0,h.UO)().id}}),t=e.data,n=e.loading,r=e.error;if(n)return l.createElement(iR,null);if(r)return l.createElement(iD,{error:r});var i=null==t?void 0:t.jobRun;switch(null==i?void 0:i.__typename){case"JobRun":return l.createElement(k6,{run:i});case"NotFoundError":return l.createElement(oa,null);default:return null}};function xe(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xt(){var e=xe(["\n fragment JobRunsPayload_ResultsFields on JobRun {\n id\n allErrors\n createdAt\n finishedAt\n status\n job {\n id\n }\n }\n"]);return xt=function(){return e},e}var xn=n0(xt()),xr=function(e){var t=e.loading,n=e.data,r=e.page,i=e.pageSize,a=(0,h.k6)(),o=l.useMemo(function(){return null==n?void 0:n.jobRuns.results.map(function(e){var t,n=e.allErrors,r=e.id,i=e.createdAt;return{id:r,createdAt:i,errors:n,finishedAt:e.finishedAt,status:e.status}})},[n]);return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(iy,null,"Job Runs")),t&&l.createElement(iR,null),n&&o&&l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(yp,{runs:o}),l.createElement(it.Z,{component:"div",count:n.jobRuns.metadata.total,rowsPerPage:i,rowsPerPageOptions:[i],page:r-1,onChangePage:function(e,t){a.push("/runs?page=".concat(t+1,"&per=").concat(i))},onChangeRowsPerPage:function(){},backIconButtonProps:{"aria-label":"prev-page"},nextIconButtonProps:{"aria-label":"next-page"}})))))};function xi(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xa(){var e=xi(["\n ","\n query FetchJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...JobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return xa=function(){return e},e}var xo=n0(xa(),xn),xs=function(){var e=ij(),t=parseInt(e.get("page")||"1",10),n=parseInt(e.get("per")||"25",10),r=rv(xo,{variables:{offset:(t-1)*n,limit:n},fetchPolicy:"cache-and-network"}),i=r.data,a=r.loading,o=r.error;return o?l.createElement(iD,{error:o}):l.createElement(xr,{loading:a,data:i,page:t,pageSize:n})},xu=function(){var e=(0,h.$B)().path;return l.createElement(h.rs,null,l.createElement(h.AW,{exact:!0,path:e},l.createElement(xs,null)),l.createElement(h.AW,{path:"".concat(e,"/:id")},l.createElement(k7,null)))};function xc(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xl(){var e=xc(["\n fragment FetchFeedsManagersPayload_ResultsFields on FeedsManager {\n __typename\n id\n name\n uri\n publicKey\n isConnectionActive\n createdAt\n disabledAt\n }\n query FetchFeedsManagers {\n feedsManagers {\n results {\n ...FetchFeedsManagersPayload_ResultsFields\n }\n }\n }\n"]);return xl=function(){return e},e}var xf=n0(xl()),xd=function(e){return rv(xf,e)},xh=n(47559),xp=n(83165),xb=n(47298),xm=n(81395),xg=function(){return(0,b.createStyles)({root:{display:"flex"},activeIcon:{color:xh.default[500]},inactiveIcon:{color:xp.default[500]},text:{marginLeft:4}})},xv=(0,b.withStyles)(xg)(function(e){var t=e.isActive,n=e.activeText,r=e.inactiveText,i=e.classes;return l.createElement("div",{className:i.root},t?l.createElement(xm.Z,{fontSize:"small",className:i.activeIcon}):l.createElement(xb.Z,{fontSize:"small",className:i.inactiveIcon}),l.createElement(x.default,{variant:"body1",inline:!0,className:i.text},t?n:r))}),xy=(0,b.withStyles)(iu)(function(e){var t=e.jobDistributor,n=e.classes;return l.createElement(ir.Z,{className:n.row,hover:!0},l.createElement(r7.default,{className:n.cell,component:"th",scope:"row"},l.createElement(ih,{className:n.link,href:"/job_distributors/".concat(t.id)},t.name)),l.createElement(r7.default,null,l.createElement(xv,{isActive:t.isConnectionActive,activeText:"Connected",inactiveText:"Disconnected"})),l.createElement(r7.default,null,l.createElement(xv,{isActive:!t.disabledAt,activeText:"Enabled",inactiveText:"Disabled"})),l.createElement(r7.default,null,_T(t.publicKey,{start:6,end:6}),l.createElement(_x,{data:t.publicKey})),l.createElement(r7.default,null,t.uri))}),xw=function(e){var t=e.jobDistributors;return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:9},l.createElement(iy,null,"Job Distributors")),l.createElement(d.Z,{item:!0,xs:3},l.createElement(d.Z,{container:!0,justify:"flex-end"},l.createElement(d.Z,{item:!0},l.createElement(aA.Z,{variant:"secondary",component:tz,href:"/job_distributors/new"},"New Job Distributor")))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(r8.Z,null,l.createElement(ie.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,null,"Name"),l.createElement(r7.default,null,"Connection Status"),l.createElement(r7.default,null,"Status"),l.createElement(r7.default,null,"CSA Public Key"),l.createElement(r7.default,null,"RPC URL"))),l.createElement(r9.Z,null,0===t.length&&l.createElement(ir.Z,null,l.createElement(r7.default,{component:"th",scope:"row",colSpan:3},"Job Distributors have not been registered")),t.map(function(e){return l.createElement(xy,{key:e.id,jobDistributor:e})})))))))},x_=function(){var e,t=xd({fetchPolicy:"cache-and-network"}),n=t.data,r=t.loading,i=t.error;return r?l.createElement(iR,null):i?l.createElement(iD,{error:i}):l.createElement(xw,{jobDistributors:null!==(e=null==n?void 0:n.feedsManagers.results)&&void 0!==e?e:[]})},xE=bv().shape({name:p0().required("Required"),uri:p0().required("Required"),publicKey:p0().required("Required")}),xS=function(e){var t=e.initialValues,n=e.onSubmit;return l.createElement(hT,{initialValues:t,validationSchema:xE,onSubmit:n},function(e){var t=e.isSubmitting,n=e.submitForm;return l.createElement(hR,{"data-testid":"feeds-manager-form"},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"name",name:"name",label:"Name",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:!1,md:6}),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"uri",name:"uri",label:"URI",required:!0,fullWidth:!0,helperText:"Provided by the Job Distributor operator",FormHelperTextProps:{"data-testid":"uri-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"publicKey",name:"publicKey",label:"Public Key",required:!0,fullWidth:!0,helperText:"Provided by the Job Distributor operator",FormHelperTextProps:{"data-testid":"publicKey-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(ok.default,{variant:"contained",color:"primary",disabled:t,onClick:n},"Submit"))))})},xk=function(e){var t=e.data,n=e.onSubmit,r={name:t.name,uri:t.uri,publicKey:t.publicKey};return l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Edit Job Distributor"}),l.createElement(aW.Z,null,l.createElement(xS,{initialValues:r,onSubmit:n})))))};function xx(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(xZ,e)},xJ=function(){return(0,b.createStyles)({root:{fontSize:24}})},xQ=(0,b.withStyles)(xJ)(function(e){var t=e.children,n=e.classes;return l.createElement(x.default,{variant:"h2",className:n.root},t)}),x1=n(9290),x0=n(74923);function x2(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function TT(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}function TM(e,t){return Tv(e)||TE(e,t)||TA(e,t)||TS()}function TO(e){return Ty(e)||T_(e)||TA(e)||Tk()}function TA(e,t){if(e){if("string"==typeof e)return Tg(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Tg(e,t)}}var TL=function(e){return"SN_MAIN"===e||"SN_SEPOLIA"===e},TC=bv().shape({chainID:p0().required("Required"),chainType:p0().required("Required"),accountAddr:p0().required("Required"),accountAddrPubKey:p0().nullable(),adminAddr:p0(),ocr1Multiaddr:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&t},then:p0().required("Required").nullable()}).nullable(),ocr1P2PPeerID:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr1KeyBundleID:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2Multiaddr:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&t},then:p0().required("Required").nullable()}).nullable(),ocr2P2PPeerID:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2KeyBundleID:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2CommitPluginEnabled:pV().required("Required"),ocr2ExecutePluginEnabled:pV().required("Required"),ocr2MedianPluginEnabled:pV().required("Required"),ocr2MercuryPluginEnabled:pV().required("Required"),ocr2ForwarderAddress:p0().nullable()}),TI=function(e){return(0,b.createStyles)({supportedJobOptionsPaper:{padding:2*e.spacing.unit}})},TD=function(e){var t=e.addresses,n=Tx(e,["addresses"]),r=h_(),i=r.values,a=i.chainID,o=i.accountAddr,s=r.setFieldValue,u=TM(l.useState(!1),2),c=u[0],f=u[1],d=l.useRef();l.useEffect(function(){d.current=a},[a]),l.useEffect(function(){a!==d.current&&(s(n.name,""),f(!1))},[a,s,n.name]);var h=function(e){var t=e.target.value;"custom"===t?(f(!0),s(n.name,"")):(f(!1),s(n.name,t))};return l.createElement(l.Fragment,null,!TL(a)&&l.createElement(hP,Tw({},n,{select:!0,value:c?"custom":o,onChange:h}),t.map(function(e){return l.createElement(tE.default,{key:e,value:e},e)})),TL(a)&&l.createElement(hP,{component:hX,id:"accountAddr",name:"accountAddr",label:"Enter your account address",inputProps:{"data-testid":"customAccountAddr-input"},helperText:"The account address used for this chain",required:!0,fullWidth:!0}),TL(a)&&l.createElement("div",null,l.createElement(hP,{component:hX,id:"accountAddrPubKey",name:"accountAddrPubKey",label:"Account Address Public Key",required:!0,fullWidth:!0,helperText:"The public key for your account address",FormHelperTextProps:{"data-testid":"accountAddrPubKey-helper-text"}})))},TN=(0,b.withStyles)(TI)(function(e){var t=e.classes,n=e.editing,r=void 0!==n&&n,i=e.innerRef,a=e.initialValues,o=e.onSubmit,s=e.chains,u=void 0===s?[]:s,c=e.accountsEVM,f=void 0===c?[]:c,h=e.accountsNonEvm,p=e.p2pKeys,b=void 0===p?[]:p,m=e.ocrKeys,g=void 0===m?[]:m,v=e.ocr2Keys,y=void 0===v?[]:v,w=e.showSubmit,_=void 0!==w&&w,E=TO(y).sort(function(e,t){var n,r,i;return e.chainType===t.chainType?e.id.localeCompare(t.id):null!==(i=null===(n=e.chainType)||void 0===n?void 0:n.localeCompare(null!==(r=t.chainType)&&void 0!==r?r:""))&&void 0!==i?i:0});return l.createElement(hT,{innerRef:i,initialValues:a,validationSchema:TC,onSubmit:o},function(e){var n,i,a=e.values,o=[];switch(a.chainType){case Tm.EVM:o=f.filter(function(e){return e.chain.id==a.chainID&&!e.isDisabled}).map(function(e){return e.address});break;case Tm.APTOS:o=null!==(n=null==h?void 0:h.aptosKeys.results.map(function(e){return e.account}))&&void 0!==n?n:[];break;case Tm.SOLANA:o=null!==(i=null==h?void 0:h.solanaKeys.results.map(function(e){return e.id}))&&void 0!==i?i:[];break;default:o=[]}var s=u.filter(function(e){return e.network.toUpperCase()===a.chainType});return l.createElement(hR,{"data-testid":"feeds-manager-form",id:"chain-configuration-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"chainType",name:"chainType",label:"Chain Type",select:!0,required:!0,fullWidth:!0,disabled:r},l.createElement(tE.default,{key:Tm.EVM,value:Tm.EVM},"EVM"),l.createElement(tE.default,{key:Tm.APTOS,value:Tm.APTOS},"APTOS"),l.createElement(tE.default,{key:Tm.SOLANA,value:Tm.SOLANA},"SOLANA"))),l.createElement(d.Z,{item:!0,xs:12,md:6},s.length>0&&!r?l.createElement(hP,{component:hX,id:"chainID",name:"chainID",label:"Chain ID",required:!0,fullWidth:!0,select:!0,disabled:r,inputProps:{"data-testid":"chainID-input"},FormHelperTextProps:{"data-testid":"chainID-helper-text"}},s.map(function(e){return l.createElement(tE.default,{key:e.id,value:e.id},e.id)})):l.createElement(hP,{component:hX,id:"chainID",name:"chainID",label:"Chain ID",required:!0,fullWidth:!0,disabled:r,inputProps:{"data-testid":"chainID-manual-input"},FormHelperTextProps:{"data-testid":"chainID-helper-manual-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},o.length>0?l.createElement(TD,{component:hX,id:"accountAddr",name:"accountAddr",label:"Account Address",inputProps:{"data-testid":"accountAddr-input"},required:!0,fullWidth:!0,select:!0,helperText:"The account address used for this chain",addresses:o,FormHelperTextProps:{"data-testid":"accountAddr-helper-text"}}):l.createElement(hP,{component:hX,id:"accountAddr",name:"accountAddr",label:"Account Address",inputProps:{"data-testid":"accountAddr-manual-input"},required:!0,fullWidth:!0,helperText:"The account address used for this chain",FormHelperTextProps:{"data-testid":"accountAddr-helper-manual-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"adminAddr",name:"adminAddr",label:"Admin Address",fullWidth:!0,helperText:"The address used for LINK payments",FormHelperTextProps:{"data-testid":"adminAddr-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,null,"Supported Job Types")),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"fluxMonitorEnabled",type:"checkbox",Label:{label:"Flux Monitor"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr1Enabled",type:"checkbox",Label:{label:"OCR"}}),a.ocr1Enabled&&l.createElement(ii.default,{className:t.supportedJobOptionsPaper},l.createElement(d.Z,{container:!0,spacing:8},l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr1IsBootstrap",type:"checkbox",Label:{label:"Is this node running as a bootstrap peer?"}})),a.ocr1IsBootstrap?l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"ocr1Multiaddr",name:"ocr1Multiaddr",label:"Multiaddr",required:!0,fullWidth:!0,helperText:"The OCR Multiaddr which oracles use to query for network information",FormHelperTextProps:{"data-testid":"ocr1Multiaddr-helper-text"}})):l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr1P2PPeerID",name:"ocr1P2PPeerID",label:"Peer ID",select:!0,required:!0,fullWidth:!0,helperText:"The Peer ID used for this chain",FormHelperTextProps:{"data-testid":"ocr1P2PPeerID-helper-text"}},b.map(function(e){return l.createElement(tE.default,{key:e.peerID,value:e.peerID},e.peerID)}))),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr1KeyBundleID",name:"ocr1KeyBundleID",label:"Key Bundle ID",select:!0,required:!0,fullWidth:!0,helperText:"The OCR Key Bundle ID used for this chain",FormHelperTextProps:{"data-testid":"ocr1KeyBundleID-helper-text"}},g.map(function(e){return l.createElement(tE.default,{key:e.id,value:e.id},e.id)})))))))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr2Enabled",type:"checkbox",Label:{label:"OCR2"}}),a.ocr2Enabled&&l.createElement(ii.default,{className:t.supportedJobOptionsPaper},l.createElement(d.Z,{container:!0,spacing:8},l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr2IsBootstrap",type:"checkbox",Label:{label:"Is this node running as a bootstrap peer?"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr2P2PPeerID",name:"ocr2P2PPeerID",label:"Peer ID",select:!0,required:!a.ocr2IsBootstrap,fullWidth:!0,helperText:"The Peer ID used for this chain",FormHelperTextProps:{"data-testid":"ocr2P2PPeerID-helper-text"}},b.map(function(e){return l.createElement(tE.default,{key:e.peerID,value:e.peerID},e.peerID)}))),a.ocr2IsBootstrap?l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"ocr2Multiaddr",name:"ocr2Multiaddr",label:"Multiaddr",required:!0,fullWidth:!0,helperText:"The OCR2 Multiaddr which oracles use to query for network information",FormHelperTextProps:{"data-testid":"ocr2Multiaddr-helper-text"}})):l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr2KeyBundleID",name:"ocr2KeyBundleID",label:"Key Bundle ID",select:!0,required:!0,fullWidth:!0,helperText:"The OCR2 Key Bundle ID used for this chain",FormHelperTextProps:{"data-testid":"ocr2KeyBundleID-helper-text"}},E.map(function(e){return l.createElement(tE.default,{key:e.id,value:e.id},e.id," (",e.chainType,")")}))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,null,"Supported Plugins")),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2CommitPluginEnabled",type:"checkbox",Label:{label:"Commit"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2ExecutePluginEnabled",type:"checkbox",Label:{label:"Execute"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2RebalancerPluginEnabled",type:"checkbox",Label:{label:"Rebalancer"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2MedianPluginEnabled",type:"checkbox",Label:{label:"Median"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2MercuryPluginEnabled",type:"checkbox",Label:{label:"Mercury"}})),l.createElement(d.Z,{item:!0,xs:12,md:12},l.createElement(hP,{component:hX,id:"ocr2ForwarderAddress",name:"ocr2ForwarderAddress",label:"Forwarder Address (optional)",fullWidth:!0,helperText:"The forwarder address from the Operator Forwarder Contract",FormHelperTextProps:{"data-testid":"ocr2ForwarderAddress-helper-text"}}))))))),_&&l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",size:"large"},"Submit"))))})});function TP(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function TR(){var e=TP(["\n fragment AptosKeysPayload_ResultsFields on AptosKey {\n account\n id\n }\n"]);return TR=function(){return e},e}function Tj(){var e=TP(["\n fragment SolanaKeysPayload_ResultsFields on SolanaKey {\n id\n }\n"]);return Tj=function(){return e},e}function TF(){var e=TP(["\n ","\n ","\n query FetchNonEvmKeys {\n aptosKeys {\n results {\n ...AptosKeysPayload_ResultsFields\n }\n }\n solanaKeys {\n results {\n ...SolanaKeysPayload_ResultsFields\n }\n }\n }\n"]);return TF=function(){return e},e}var TY=n0(TR()),TB=n0(Tj()),TU=n0(TF(),TY,TB),TH=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return rv(TU,e)},T$=function(e){var t=e.onClose,n=e.open,r=e.onSubmit,i=l.useRef(),a=i$({fetchPolicy:"network-only"}).data,o=_K({fetchPolicy:"cache-and-network"}).data,s=TH({fetchPolicy:"cache-and-network"}).data,u=SV({fetchPolicy:"cache-and-network"}).data,c=EO({fetchPolicy:"cache-and-network"}).data,f=E2({fetchPolicy:"cache-and-network"}).data,d={chainID:"",chainType:Tm.EVM,accountAddr:"",adminAddr:"",accountAddrPubKey:"",fluxMonitorEnabled:!1,ocr1Enabled:!1,ocr1IsBootstrap:!1,ocr1Multiaddr:"",ocr1P2PPeerID:"",ocr1KeyBundleID:"",ocr2Enabled:!1,ocr2IsBootstrap:!1,ocr2Multiaddr:"",ocr2P2PPeerID:"",ocr2KeyBundleID:"",ocr2CommitPluginEnabled:!1,ocr2ExecutePluginEnabled:!1,ocr2MedianPluginEnabled:!1,ocr2MercuryPluginEnabled:!1,ocr2RebalancerPluginEnabled:!1,ocr2ForwarderAddress:""},h=a?a.chains.results:[],p=o?o.ethKeys.results:[],b=u?u.p2pKeys.results:[],m=c?c.ocrKeyBundles.results:[],g=f?f.ocr2KeyBundles.results:[];return l.createElement(aD.Z,{onClose:t,open:n,disableBackdropClick:!0},l.createElement(oO.Z,{disableTypography:!0},l.createElement(x.default,{variant:"body2"},"New Supported Chain")),l.createElement(oT.Z,null,l.createElement(TN,{innerRef:i,initialValues:d,onSubmit:r,chains:h,accountsEVM:p,accountsNonEvm:s,p2pKeys:b,ocrKeys:m,ocr2Keys:g})),l.createElement(ox.Z,null,l.createElement(ok.default,{onClick:t},"Cancel"),l.createElement(ok.default,{color:"primary",type:"submit",form:"chain-configuration-form",variant:"contained"},"Submit")))},Tz=function(e){var t=e.cfg,n=e.onClose,r=e.open,i=e.onSubmit,a=l.useRef(),o=i$({fetchPolicy:"network-only"}).data,s=_K({fetchPolicy:"cache-and-network"}).data,u=TH({fetchPolicy:"cache-and-network"}).data,c=SV({fetchPolicy:"cache-and-network"}).data,f=EO({fetchPolicy:"cache-and-network"}).data,d=E2({fetchPolicy:"cache-and-network"}).data;if(!t)return null;var h={chainID:t.chainID,chainType:t.chainType,accountAddr:t.accountAddr,adminAddr:t.adminAddr,accountAddrPubKey:t.accountAddrPubKey,fluxMonitorEnabled:t.fluxMonitorJobConfig.enabled,ocr1Enabled:t.ocr1JobConfig.enabled,ocr1IsBootstrap:t.ocr1JobConfig.isBootstrap,ocr1Multiaddr:t.ocr1JobConfig.multiaddr,ocr1P2PPeerID:t.ocr1JobConfig.p2pPeerID,ocr1KeyBundleID:t.ocr1JobConfig.keyBundleID,ocr2Enabled:t.ocr2JobConfig.enabled,ocr2IsBootstrap:t.ocr2JobConfig.isBootstrap,ocr2Multiaddr:t.ocr2JobConfig.multiaddr,ocr2P2PPeerID:t.ocr2JobConfig.p2pPeerID,ocr2KeyBundleID:t.ocr2JobConfig.keyBundleID,ocr2CommitPluginEnabled:t.ocr2JobConfig.plugins.commit,ocr2ExecutePluginEnabled:t.ocr2JobConfig.plugins.execute,ocr2MedianPluginEnabled:t.ocr2JobConfig.plugins.median,ocr2MercuryPluginEnabled:t.ocr2JobConfig.plugins.mercury,ocr2RebalancerPluginEnabled:t.ocr2JobConfig.plugins.rebalancer,ocr2ForwarderAddress:t.ocr2JobConfig.forwarderAddress},p=o?o.chains.results:[],b=s?s.ethKeys.results:[],m=c?c.p2pKeys.results:[],g=f?f.ocrKeyBundles.results:[],v=d?d.ocr2KeyBundles.results:[];return l.createElement(aD.Z,{onClose:n,open:r,disableBackdropClick:!0},l.createElement(oO.Z,{disableTypography:!0},l.createElement(x.default,{variant:"body2"},"Edit Supported Chain")),l.createElement(oT.Z,null,l.createElement(TN,{innerRef:a,initialValues:h,onSubmit:i,chains:p,accountsEVM:b,accountsNonEvm:u,p2pKeys:m,ocrKeys:g,ocr2Keys:v,editing:!0})),l.createElement(ox.Z,null,l.createElement(ok.default,{onClick:n},"Cancel"),l.createElement(ok.default,{color:"primary",type:"submit",form:"chain-configuration-form",variant:"contained"},"Submit")))};function TG(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);nt.version?e:t})},[o]),g=l.useMemo(function(){return M1(o).sort(function(e,t){return t.version-e.version})},[o]),v=function(e,t,n){switch(e){case"PENDING":return l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"text",color:"secondary",onClick:function(){return b("reject",t)}},"Reject"),m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status&&l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve"),m.id===t&&"DELETED"===n.status&&n.pendingUpdate&&l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("cancel",t)}},"Cancel"),l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs")));case"APPROVED":return l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"contained",onClick:function(){return b("cancel",t)}},"Cancel"),"DELETED"===n.status&&n.pendingUpdate&&l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs"));case"CANCELLED":if(m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status)return l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve");return null;default:return null}};return l.createElement("div",null,g.map(function(e,n){return l.createElement(mP.Z,{defaultExpanded:0===n,key:n},l.createElement(mR.Z,{expandIcon:l.createElement(gh.Z,null)},l.createElement(x.default,{className:t.versionText},"Version ",e.version),l.createElement(Es.Z,{label:e.status,color:"APPROVED"===e.status?"primary":"default",variant:"REJECTED"===e.status||"CANCELLED"===e.status?"outlined":"default"}),l.createElement("div",{className:t.proposedAtContainer},l.createElement(x.default,null,"Proposed ",l.createElement(aO,{tooltip:!0},e.createdAt)))),l.createElement(mj.Z,{className:t.expansionPanelDetails},l.createElement("div",{className:t.actions},l.createElement("div",{className:t.editContainer},0===n&&("PENDING"===e.status||"CANCELLED"===e.status)&&"DELETED"!==s.status&&"REVOKED"!==s.status&&l.createElement(ok.default,{variant:"contained",onClick:function(){return p(!0)}},"Edit")),l.createElement("div",{className:t.actionsContainer},v(e.status,e.id,s))),l.createElement(gd,{language:"toml",style:gs,"data-testid":"codeblock"},e.definition)))}),l.createElement(oC,{open:null!=c,title:c?M6[c.action].title:"",body:c?M6[c.action].body:"",onConfirm:function(){if(c){switch(c.action){case"approve":n(c.id);break;case"cancel":r(c.id);break;case"reject":i(c.id)}f(null)}},cancelButtonText:"Cancel",onCancel:function(){return f(null)}}),l.createElement(Mz,{open:h,onClose:function(){return p(!1)},initialValues:{definition:m.definition,id:m.id},onSubmit:a}))});function M8(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function M9(){var e=M8(["\n ","\n fragment JobProposalPayloadFields on JobProposal {\n id\n externalJobID\n remoteUUID\n jobID\n specs {\n ...JobProposal_SpecsFields\n }\n status\n pendingUpdate\n }\n"]);return M9=function(){return e},e}var M7=n0(M9(),M3),Oe=function(e){var t=e.onApprove,n=e.onCancel,r=e.onReject,i=e.onUpdateSpec,a=e.proposal;return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(iy,null,"Job Proposal #",a.id))),l.createElement(MF,{proposal:a}),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(xQ,null,"Specs"))),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(M5,{proposal:a,specs:a.specs,onReject:r,onApprove:t,onCancel:n,onUpdateSpec:i}))))};function Ot(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);nU,tA:()=>$,KL:()=>H,Iw:()=>V,DQ:()=>W,cB:()=>T,LO:()=>M,t5:()=>k,qt:()=>x,Jc:()=>C,L7:()=>Y,EO:()=>B});var r,i,a=n(66289),o=n(41800),s=n.n(o),u=n(67932);(i=r||(r={})).IN_PROGRESS="in_progress",i.PENDING_INCOMING_CONFIRMATIONS="pending_incoming_confirmations",i.PENDING_CONNECTION="pending_connection",i.PENDING_BRIDGE="pending_bridge",i.PENDING_SLEEP="pending_sleep",i.ERRORED="errored",i.COMPLETED="completed";var c=n(87013),l=n(19084),f=n(34823);function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]j,v2:()=>F});var r=n(66289);function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var a="/sessions",o="/sessions",s=function e(t){var n=this;i(this,e),this.api=t,this.createSession=function(e){return n.create(e)},this.destroySession=function(){return n.destroy()},this.create=this.api.createResource(a),this.destroy=this.api.deleteResource(o)};function u(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var c="/v2/bulk_delete_runs",l=function e(t){var n=this;u(this,e),this.api=t,this.bulkDeleteJobRuns=function(e){return n.destroy(e)},this.destroy=this.api.deleteResource(c)};function f(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var d="/v2/chains/evm",h="".concat(d,"/:id"),p=function e(t){var n=this;f(this,e),this.api=t,this.getChains=function(){return n.index()},this.createChain=function(e){return n.create(e)},this.destroyChain=function(e){return n.destroy(void 0,{id:e})},this.updateChain=function(e,t){return n.update(t,{id:e})},this.index=this.api.fetchResource(d),this.create=this.api.createResource(d),this.destroy=this.api.deleteResource(h),this.update=this.api.updateResource(h)};function b(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var m="/v2/keys/evm/chain",g=function e(t){var n=this;b(this,e),this.api=t,this.chain=function(e){var t=new URLSearchParams;t.append("address",e.address),t.append("evmChainID",e.evmChainID),null!==e.abandon&&t.append("abandon",String(e.abandon)),null!==e.enabled&&t.append("enabled",String(e.enabled));var r=m+"?"+t.toString();return n.api.createResource(r)()}};function v(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var y="/v2/jobs",w="".concat(y,"/:specId/runs"),_=function e(t){var n=this;v(this,e),this.api=t,this.createJobRunV2=function(e,t){return n.post(t,{specId:e})},this.post=this.api.createResource(w,!0)};function E(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var S="/v2/log",k=function e(t){var n=this;E(this,e),this.api=t,this.getLogConfig=function(){return n.show()},this.updateLogConfig=function(e){return n.update(e)},this.show=this.api.fetchResource(S),this.update=this.api.updateResource(S)};function x(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var T="/v2/nodes",M=function e(t){var n=this;x(this,e),this.api=t,this.getNodes=function(){return n.index()},this.createNode=function(e){return n.create(e)},this.index=this.api.fetchResource(T),this.create=this.api.createResource(T)};function O(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var A="/v2/enroll_webauthn",L=function e(t){var n=this;O(this,e),this.api=t,this.beginKeyRegistration=function(e){return n.create(e)},this.finishKeyRegistration=function(e){return n.put(e)},this.create=this.api.fetchResource(A),this.put=this.api.createResource(A)};function C(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var I="/v2/build_info",D=function e(t){var n=this;C(this,e),this.api=t,this.show=function(){return n.api.GET(I)()}};function N(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var P=function e(t){N(this,e),this.api=t,this.buildInfo=new D(this.api),this.bulkDeleteRuns=new l(this.api),this.chains=new p(this.api),this.logConfig=new k(this.api),this.nodes=new M(this.api),this.jobs=new _(this.api),this.webauthn=new L(this.api),this.evmKeys=new g(this.api)},R=new r.V0({base:void 0}),j=new s(R),F=new P(R)},1398(e,t,n){"use strict";n.d(t,{Z:()=>d});var r=n(67294),i=n(32316),a=n(83638),o=n(94184),s=n.n(o);function u(){return(u=Object.assign||function(e){for(var t=1;tc});var r=n(67294),i=n(32316);function a(){return(a=Object.assign||function(e){for(var t=1;tx,jK:()=>v});var r=n(67294),i=n(37703),a=n(45697),o=n.n(a),s=n(82204),u=n(71426),c=n(94184),l=n.n(c),f=n(32316),d=function(e){var t=e.palette.success||{},n=e.palette.warning||{};return{base:{paddingLeft:5*e.spacing.unit,paddingRight:5*e.spacing.unit},success:{backgroundColor:t.main,color:t.contrastText},error:{backgroundColor:e.palette.error.dark,color:e.palette.error.contrastText},warning:{backgroundColor:n.contrastText,color:n.main}}},h=function(e){var t,n=e.success,r=e.error,i=e.warning,a=e.classes,o=e.className;return n?t=a.success:r?t=a.error:i&&(t=a.warning),l()(a.base,o,t)},p=function(e){return r.createElement(s.Z,{className:h(e),square:!0},r.createElement(u.default,{variant:"body2",color:"inherit",component:"div"},e.children))};p.defaultProps={success:!1,error:!1,warning:!1},p.propTypes={success:o().bool,error:o().bool,warning:o().bool};let b=(0,f.withStyles)(d)(p);var m=function(){return r.createElement(r.Fragment,null,"Unhandled error. Please help us by opening a"," ",r.createElement("a",{href:"https://github.com/smartcontractkit/chainlink/issues/new"},"bug report"))};let g=m;function v(e){return"string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null)}function y(e,t){var n;return n="string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null),r.createElement("p",{key:t},n)}var w=function(e){var t=e.notifications;return r.createElement(b,{error:!0},t.map(y))},_=function(e){var t=e.notifications;return r.createElement(b,{success:!0},t.map(y))},E=function(e){var t=e.errors,n=e.successes;return r.createElement("div",null,(null==t?void 0:t.length)>0&&r.createElement(w,{notifications:t}),n.length>0&&r.createElement(_,{notifications:n}))},S=function(e){return{errors:e.notifications.errors,successes:e.notifications.successes}},k=(0,i.$j)(S)(E);let x=k},9409(e,t,n){"use strict";n.d(t,{ZP:()=>j});var r=n(67294),i=n(37703),a=n(5977),o=n(32316),s=n(1398),u=n(82204),c=n(30060),l=n(71426),f=n(60520),d=n(39814),h=n(57209),p=n(26842),b=n(3950),m=n(5536),g=n(45697),v=n.n(g);let y=n.p+"9f6d832ef97e8493764e.svg";function w(){return(w=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&_.map(function(e,t){return r.createElement(d.Z,{item:!0,xs:12,key:t},r.createElement(u.Z,{raised:!1,className:v.error},r.createElement(c.Z,null,r.createElement(l.default,{variant:"body1",className:v.errorText},(0,b.jK)(e)))))}),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"email",label:"Email",margin:"normal",value:n,onChange:m("email"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"password",label:"Password",type:"password",autoComplete:"password",margin:"normal",value:h,onChange:m("password"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(d.Z,{container:!0,spacing:0,justify:"center"},r.createElement(d.Z,{item:!0},r.createElement(s.Z,{type:"submit",variant:"primary"},"Access Account")))),y&&r.createElement(l.default,{variant:"body1",color:"textSecondary"},"Signing in...")))))))},P=function(e){return{fetching:e.authentication.fetching,authenticated:e.authentication.allowed,errors:e.notifications.errors}},R=(0,i.$j)(P,x({submitSignIn:p.L7}))(N);let j=(0,h.wU)(e)((0,o.withStyles)(D)(R))},16353(e,t,n){"use strict";n.d(t,{ZP:()=>H,rH:()=>U});var r,i=n(37703),a=n(97779),o=n(9541),s=n(19084);function u(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:h,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.Mk.RECEIVE_SIGNOUT_SUCCESS:case s.Mk.RECEIVE_SIGNIN_SUCCESS:var n={allowed:t.authenticated};return o.Ks(n),f(c({},e,n),{errors:[]});case s.Mk.RECEIVE_SIGNIN_FAIL:var r={allowed:!1};return o.Ks(r),f(c({},e,r),{errors:[]});case s.Mk.RECEIVE_SIGNIN_ERROR:case s.Mk.RECEIVE_SIGNOUT_ERROR:var i={allowed:!1};return o.Ks(i),f(c({},e,i),{errors:t.errors||[]});default:return e}};let b=p;function m(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function g(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:_,t=arguments.length>1?arguments[1]:void 0;return t.type?t.type.startsWith(r.REQUEST)?y(g({},e),{count:e.count+1}):t.type.startsWith(r.RECEIVE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type.startsWith(r.RESPONSE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type===s.di.REDIRECT?y(g({},e),{count:0}):e:e};let S=E;function k(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function x(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:O,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.MATCH_ROUTE:return M(x({},O),{currentUrl:t.pathname});case s.Ih.NOTIFY_SUCCESS:var n={component:t.component,props:t.props};return M(x({},e),{successes:[n],errors:[]});case s.Ih.NOTIFY_SUCCESS_MSG:return M(x({},e),{successes:[t.msg],errors:[]});case s.Ih.NOTIFY_ERROR:var r=t.error.errors,i=null==r?void 0:r.map(function(e){return L(t,e)});return M(x({},e),{successes:[],errors:i});case s.Ih.NOTIFY_ERROR_MSG:return M(x({},e),{successes:[],errors:[t.msg]});case s.Mk.RECEIVE_SIGNIN_FAIL:return M(x({},e),{successes:[],errors:["Your email or password is incorrect. Please try again"]});default:return e}};function L(e,t){return{component:e.component,props:{msg:t.detail}}}let C=A;function I(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function D(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:R,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.REDIRECT:return P(D({},e),{to:t.to});case s.di.MATCH_ROUTE:return P(D({},e),{to:void 0});default:return e}};let F=j;var Y=n(87013),B=(0,a.UY)({authentication:b,fetching:S,notifications:C,redirect:F,buildInfo:Y.Z});B(void 0,{type:"INITIAL_STATE"});var U=i.v9;let H=B},19084(e,t,n){"use strict";var r,i,a,o,s,u,c,l,f,d;n.d(t,{Ih:()=>i,Mk:()=>a,Y0:()=>s,di:()=>r,jp:()=>o}),n(67294),(u=r||(r={})).REDIRECT="REDIRECT",u.MATCH_ROUTE="MATCH_ROUTE",(c=i||(i={})).NOTIFY_SUCCESS="NOTIFY_SUCCESS",c.NOTIFY_SUCCESS_MSG="NOTIFY_SUCCESS_MSG",c.NOTIFY_ERROR="NOTIFY_ERROR",c.NOTIFY_ERROR_MSG="NOTIFY_ERROR_MSG",(l=a||(a={})).REQUEST_SIGNIN="REQUEST_SIGNIN",l.RECEIVE_SIGNIN_SUCCESS="RECEIVE_SIGNIN_SUCCESS",l.RECEIVE_SIGNIN_FAIL="RECEIVE_SIGNIN_FAIL",l.RECEIVE_SIGNIN_ERROR="RECEIVE_SIGNIN_ERROR",l.RECEIVE_SIGNOUT_SUCCESS="RECEIVE_SIGNOUT_SUCCESS",l.RECEIVE_SIGNOUT_ERROR="RECEIVE_SIGNOUT_ERROR",(f=o||(o={})).RECEIVE_CREATE_ERROR="RECEIVE_CREATE_ERROR",f.RECEIVE_CREATE_SUCCESS="RECEIVE_CREATE_SUCCESS",f.RECEIVE_DELETE_ERROR="RECEIVE_DELETE_ERROR",f.RECEIVE_DELETE_SUCCESS="RECEIVE_DELETE_SUCCESS",f.RECEIVE_UPDATE_ERROR="RECEIVE_UPDATE_ERROR",f.RECEIVE_UPDATE_SUCCESS="RECEIVE_UPDATE_SUCCESS",f.REQUEST_CREATE="REQUEST_CREATE",f.REQUEST_DELETE="REQUEST_DELETE",f.REQUEST_UPDATE="REQUEST_UPDATE",f.UPSERT_CONFIGURATION="UPSERT_CONFIGURATION",f.UPSERT_JOB_RUN="UPSERT_JOB_RUN",f.UPSERT_JOB_RUNS="UPSERT_JOB_RUNS",f.UPSERT_TRANSACTION="UPSERT_TRANSACTION",f.UPSERT_TRANSACTIONS="UPSERT_TRANSACTIONS",f.UPSERT_BUILD_INFO="UPSERT_BUILD_INFO",(d=s||(s={})).FETCH_BUILD_INFO_REQUESTED="FETCH_BUILD_INFO_REQUESTED",d.FETCH_BUILD_INFO_SUCCEEDED="FETCH_BUILD_INFO_SUCCEEDED",d.FETCH_BUILD_INFO_FAILED="FETCH_BUILD_INFO_FAILED"},87013(e,t,n){"use strict";n.d(t,{Y:()=>o,Z:()=>u});var r=n(19084);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:o,t=arguments.length>1?arguments[1]:void 0;return t.type===r.Y0.FETCH_BUILD_INFO_SUCCEEDED?a({},t.buildInfo):e};let u=s},34823(e,t,n){"use strict";n.d(t,{N:()=>r});var r=function(e){return e.buildInfo}},73343(e,t,n){"use strict";n.d(t,{r:()=>u});var r=n(19350),i=n(32316),a=n(59114),o=n(5324),s={props:{MuiGrid:{spacing:3*o.default.unit},MuiCardHeader:{titleTypographyProps:{color:"secondary"}}},palette:{action:{hoverOpacity:.3},primary:{light:"#E5F1FF",main:"#3c40c6",contrastText:"#fff"},secondary:{main:"#3d5170"},success:{light:"#e8faf1",main:r.ek.A700,dark:r.ek[700],contrastText:r.y0.white},warning:{light:"#FFFBF1",main:"#fff6b6",contrastText:"#fad27a"},error:{light:"#ffdada",main:"#f44336",dark:"#d32f2f",contrastText:"#fff"},background:{default:"#f5f6f8",appBar:"#3c40c6"},text:{primary:(0,a.darken)(r.BA.A700,.7),secondary:"#818ea3"},listPendingStatus:{background:"#fef7e5",color:"#fecb4c"},listCompletedStatus:{background:"#e9faf2",color:"#4ed495"}},shape:{borderRadius:o.default.unit},overrides:{MuiButton:{root:{borderRadius:o.default.unit/2,textTransform:"none"},sizeLarge:{padding:void 0,fontSize:void 0,paddingTop:o.default.unit,paddingBottom:o.default.unit,paddingLeft:5*o.default.unit,paddingRight:5*o.default.unit}},MuiTableCell:{body:{fontSize:"1rem"},head:{fontSize:"1rem",fontWeight:400}},MuiCardHeader:{root:{borderBottom:"1px solid rgba(0, 0, 0, 0.12)"},action:{marginTop:-2,marginRight:0,"& >*":{marginLeft:2*o.default.unit}},subheader:{marginTop:.5*o.default.unit}}},typography:{useNextVariants:!0,fontFamily:"-apple-system,BlinkMacSystemFont,Roboto,Helvetica,Arial,sans-serif",button:{textTransform:"none",fontSize:"1.2em"},body1:{fontSize:"1.0rem",fontWeight:400,lineHeight:"1.46429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body2:{fontSize:"1.0rem",fontWeight:500,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body1Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"1rem",lineHeight:1.5,letterSpacing:-.4},body2Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"0.875rem",lineHeight:1.5,letterSpacing:-.4},display1:{color:"#818ea3",fontSize:"2.125rem",fontWeight:400,lineHeight:"1.20588em",letterSpacing:-.4},display2:{color:"#818ea3",fontSize:"2.8125rem",fontWeight:400,lineHeight:"1.13333em",marginLeft:"-.02em",letterSpacing:-.4},display3:{color:"#818ea3",fontSize:"3.5rem",fontWeight:400,lineHeight:"1.30357em",marginLeft:"-.02em",letterSpacing:-.4},display4:{fontSize:14,fontWeightLight:300,fontWeightMedium:500,fontWeightRegular:400,letterSpacing:-.4},h1:{color:"rgb(29, 29, 29)",fontSize:"6rem",fontWeight:300,lineHeight:1},h2:{color:"rgb(29, 29, 29)",fontSize:"3.75rem",fontWeight:300,lineHeight:1},h3:{color:"rgb(29, 29, 29)",fontSize:"3rem",fontWeight:400,lineHeight:1.04},h4:{color:"rgb(29, 29, 29)",fontSize:"2.125rem",fontWeight:400,lineHeight:1.17},h5:{color:"rgb(29, 29, 29)",fontSize:"1.5rem",fontWeight:400,lineHeight:1.33,letterSpacing:-.4},h6:{fontSize:"0.8rem",fontWeight:450,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},subheading:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:"1.5em",letterSpacing:-.4},subtitle1:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:1.75,letterSpacing:-.4},subtitle2:{color:"rgb(29, 29, 29)",fontSize:"0.875rem",fontWeight:500,lineHeight:1.57,letterSpacing:-.4}},shadows:["none","0px 1px 3px 0px rgba(0, 0, 0, 0.1),0px 1px 1px 0px rgba(0, 0, 0, 0.04),0px 2px 1px -1px rgba(0, 0, 0, 0.02)","0px 1px 5px 0px rgba(0, 0, 0, 0.1),0px 2px 2px 0px rgba(0, 0, 0, 0.04),0px 3px 1px -2px rgba(0, 0, 0, 0.02)","0px 1px 8px 0px rgba(0, 0, 0, 0.1),0px 3px 4px 0px rgba(0, 0, 0, 0.04),0px 3px 3px -2px rgba(0, 0, 0, 0.02)","0px 2px 4px -1px rgba(0, 0, 0, 0.1),0px 4px 5px 0px rgba(0, 0, 0, 0.04),0px 1px 10px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 5px 8px 0px rgba(0, 0, 0, 0.04),0px 1px 14px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 6px 10px 0px rgba(0, 0, 0, 0.04),0px 1px 18px 0px rgba(0, 0, 0, 0.02)","0px 4px 5px -2px rgba(0, 0, 0, 0.1),0px 7px 10px 1px rgba(0, 0, 0, 0.04),0px 2px 16px 1px rgba(0, 0, 0, 0.02)","0px 5px 5px -3px rgba(0, 0, 0, 0.1),0px 8px 10px 1px rgba(0, 0, 0, 0.04),0px 3px 14px 2px rgba(0, 0, 0, 0.02)","0px 5px 6px -3px rgba(0, 0, 0, 0.1),0px 9px 12px 1px rgba(0, 0, 0, 0.04),0px 3px 16px 2px rgba(0, 0, 0, 0.02)","0px 6px 6px -3px rgba(0, 0, 0, 0.1),0px 10px 14px 1px rgba(0, 0, 0, 0.04),0px 4px 18px 3px rgba(0, 0, 0, 0.02)","0px 6px 7px -4px rgba(0, 0, 0, 0.1),0px 11px 15px 1px rgba(0, 0, 0, 0.04),0px 4px 20px 3px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 12px 17px 2px rgba(0, 0, 0, 0.04),0px 5px 22px 4px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 13px 19px 2px rgba(0, 0, 0, 0.04),0px 5px 24px 4px rgba(0, 0, 0, 0.02)","0px 7px 9px -4px rgba(0, 0, 0, 0.1),0px 14px 21px 2px rgba(0, 0, 0, 0.04),0px 5px 26px 4px rgba(0, 0, 0, 0.02)","0px 8px 9px -5px rgba(0, 0, 0, 0.1),0px 15px 22px 2px rgba(0, 0, 0, 0.04),0px 6px 28px 5px rgba(0, 0, 0, 0.02)","0px 8px 10px -5px rgba(0, 0, 0, 0.1),0px 16px 24px 2px rgba(0, 0, 0, 0.04),0px 6px 30px 5px rgba(0, 0, 0, 0.02)","0px 8px 11px -5px rgba(0, 0, 0, 0.1),0px 17px 26px 2px rgba(0, 0, 0, 0.04),0px 6px 32px 5px rgba(0, 0, 0, 0.02)","0px 9px 11px -5px rgba(0, 0, 0, 0.1),0px 18px 28px 2px rgba(0, 0, 0, 0.04),0px 7px 34px 6px rgba(0, 0, 0, 0.02)","0px 9px 12px -6px rgba(0, 0, 0, 0.1),0px 19px 29px 2px rgba(0, 0, 0, 0.04),0px 7px 36px 6px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 20px 31px 3px rgba(0, 0, 0, 0.04),0px 8px 38px 7px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 21px 33px 3px rgba(0, 0, 0, 0.04),0px 8px 40px 7px rgba(0, 0, 0, 0.02)","0px 10px 14px -6px rgba(0, 0, 0, 0.1),0px 22px 35px 3px rgba(0, 0, 0, 0.04),0px 8px 42px 7px rgba(0, 0, 0, 0.02)","0px 11px 14px -7px rgba(0, 0, 0, 0.1),0px 23px 36px 3px rgba(0, 0, 0, 0.04),0px 9px 44px 8px rgba(0, 0, 0, 0.02)","0px 11px 15px -7px rgba(0, 0, 0, 0.1),0px 24px 38px 3px rgba(0, 0, 0, 0.04),0px 9px 46px 8px rgba(0, 0, 0, 0.02)",]},u=(0,i.createMuiTheme)(s)},66289(e,t,n){"use strict";function r(e){if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}function a(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}}function o(e,t,n){return(o=a()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var i=new(Function.bind.apply(e,r));return n&&f(i,n.prototype),i}).apply(null,arguments)}function s(e){return(s=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function u(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&f(e,t)}function c(e){return -1!==Function.toString.call(e).indexOf("[native code]")}function l(e,t){return t&&("object"===p(t)||"function"==typeof t)?t:r(e)}function f(e,t){return(f=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}n.d(t,{V0:()=>B,_7:()=>v});var d,h,p=function(e){return e&&"undefined"!=typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};function b(e){var t="function"==typeof Map?new Map:void 0;return(b=function(e){if(null===e||!c(e))return e;if("function"!=typeof e)throw TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return o(e,arguments,s(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),f(n,e)})(e)}function m(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(e){return!1}}function g(e){var t=m();return function(){var n,r=s(e);if(t){var i=s(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return l(this,n)}}var v=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"AuthenticationError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e},],r}return n}(b(Error)),y=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"BadRequestError")).errors=a,r}return n}(b(Error)),w=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnprocessableEntityError")).errors=e,r}return n}(b(Error)),_=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"ServerError")).errors=e,r}return n}(b(Error)),E=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"ConflictError")).errors=a,r}return n}(b(Error)),S=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnknownResponseError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e.statusText},],r}return n}(b(Error));function k(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:2e4;return Promise.race([fetch(e,t),new Promise(function(e,t){return setTimeout(function(){return t(Error("timeout"))},n)}),])}function x(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=200&&e.status<300))return[3,2];return[2,e.json()];case 2:if(400!==e.status)return[3,3];return[2,e.json().then(function(e){throw new y(e)})];case 3:if(401!==e.status)return[3,4];throw new v(e);case 4:if(422!==e.status)return[3,6];return[4,$(e)];case 5:throw n=i.sent(),new w(n);case 6:if(409!==e.status)return[3,7];return[2,e.json().then(function(e){throw new E(e)})];case 7:if(!(e.status>=500))return[3,9];return[4,$(e)];case 8:throw r=i.sent(),new _(r);case 9:throw new S(e);case 10:return[2]}})})).apply(this,arguments)}function $(e){return z.apply(this,arguments)}function z(){return(z=j(function(e){return Y(this,function(t){return[2,e.json().then(function(t){return t.errors?t.errors.map(function(t){return{status:e.status,detail:t.detail}}):G(e)}).catch(function(){return G(e)})]})})).apply(this,arguments)}function G(e){return[{status:e.status,detail:e.statusText},]}},50109(e,t,n){"use strict";n.d(t,{LK:()=>o,U2:()=>i,eT:()=>s,t8:()=>a});var r=n(12795);function i(e){return r.ZP.getItem("chainlink.".concat(e))}function a(e,t){r.ZP.setItem("chainlink.".concat(e),t)}function o(e){var t=i(e),n={};if(t)try{return JSON.parse(t)}catch(r){}return n}function s(e,t){a(e,JSON.stringify(t))}},9541(e,t,n){"use strict";n.d(t,{Ks:()=>u,Tp:()=>a,iR:()=>o,pm:()=>s});var r=n(50109),i="persistURL";function a(){return r.U2(i)||""}function o(e){r.t8(i,e)}function s(){return r.LK("authentication")}function u(e){r.eT("authentication",e)}},67121(e,t,n){"use strict";function r(e){var t,n=e.Symbol;return"function"==typeof n?n.observable?t=n.observable:(t=n("observable"),n.observable=t):t="@@observable",t}n.r(t),n.d(t,{default:()=>o}),e=n.hmd(e),i="undefined"!=typeof self?self:"undefined"!=typeof window?window:void 0!==n.g?n.g:e;var i,a=r(i);let o=a},2177(e,t,n){"use strict";n.d(t,{Z:()=>o});var r=!0,i="Invariant failed";function a(e,t){if(!e){if(r)throw Error(i);throw Error(i+": "+(t||""))}}let o=a},11742(e){e.exports=function(){var e=document.getSelection();if(!e.rangeCount)return function(){};for(var t=document.activeElement,n=[],r=0;ru,ZT:()=>i,_T:()=>o,ev:()=>c,mG:()=>s,pi:()=>a});var r=function(e,t){return(r=Object.setPrototypeOf||({__proto__:[]})instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,t)};function i(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return(a=Object.assign||function(e){for(var t,n=1,r=arguments.length;nt.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,r=Object.getOwnPropertySymbols(e);it.indexOf(r[i])&&Object.prototype.propertyIsEnumerable.call(e,r[i])&&(n[r[i]]=e[r[i]]);return n}function s(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,a){function o(e){try{u(r.next(e))}catch(t){a(t)}}function s(e){try{u(r.throw(e))}catch(t){a(t)}}function u(e){e.done?n(e.value):i(e.value).then(o,s)}u((r=r.apply(e,t||[])).next())})}function u(e,t){var n,r,i,a,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(e){return function(t){return u([e,t])}}function u(a){if(n)throw TypeError("Generator is already executing.");for(;o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!(i=(i=o.trys).length>0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]r})},94927(e,t,n){function r(e,t){if(i("noDeprecation"))return e;var n=!1;function r(){if(!n){if(i("throwDeprecation"))throw Error(t);i("traceDeprecation")?console.trace(t):console.warn(t),n=!0}return e.apply(this,arguments)}return r}function i(e){try{if(!n.g.localStorage)return!1}catch(t){return!1}var r=n.g.localStorage[e];return null!=r&&"true"===String(r).toLowerCase()}e.exports=r},42473(e){"use strict";var t=function(){};e.exports=t},84763(e){e.exports=Worker},47529(e){e.exports=n;var t=Object.prototype.hasOwnProperty;function n(){for(var e={},n=0;ne.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}e.exports=i,e.exports.__esModule=!0,e.exports.default=e.exports},7071(e){function t(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},94993(e,t,n){var r=n(18698).default,i=n(66115);function a(e,t){if(t&&("object"===r(t)||"function"==typeof t))return t;if(void 0!==t)throw TypeError("Derived constructors may only return object or undefined");return i(e)}e.exports=a,e.exports.__esModule=!0,e.exports.default=e.exports},6015(e){function t(n,r){return e.exports=t=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},e.exports.__esModule=!0,e.exports.default=e.exports,t(n,r)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},861(e,t,n){var r=n(63405),i=n(79498),a=n(86116),o=n(42281);function s(e){return r(e)||i(e)||a(e)||o()}e.exports=s,e.exports.__esModule=!0,e.exports.default=e.exports},18698(e){function t(n){return e.exports=t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e.exports.__esModule=!0,e.exports.default=e.exports,t(n)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},86116(e,t,n){var r=n(73897);function i(e,t){if(e){if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return r(e,t)}}e.exports=i,e.exports.__esModule=!0,e.exports.default=e.exports},1644(e,t,n){"use strict";var r,i;function a(e){return!!e&&e<7}n.d(t,{I:()=>r,O:()=>a}),(i=r||(r={}))[i.loading=1]="loading",i[i.setVariables=2]="setVariables",i[i.fetchMore=3]="fetchMore",i[i.refetch=4]="refetch",i[i.poll=6]="poll",i[i.ready=7]="ready",i[i.error=8]="error"},30990(e,t,n){"use strict";n.d(t,{MS:()=>s,YG:()=>a,cA:()=>c,ls:()=>o});var r=n(70655);n(83952);var i=n(13154),a=Symbol();function o(e){return!!e.extensions&&Array.isArray(e.extensions[a])}function s(e){return e.hasOwnProperty("graphQLErrors")}var u=function(e){var t=(0,r.ev)((0,r.ev)((0,r.ev)([],e.graphQLErrors,!0),e.clientErrors,!0),e.protocolErrors,!0);return e.networkError&&t.push(e.networkError),t.map(function(e){return(0,i.s)(e)&&e.message||"Error message not found."}).join("\n")},c=function(e){function t(n){var r=n.graphQLErrors,i=n.protocolErrors,a=n.clientErrors,o=n.networkError,s=n.errorMessage,c=n.extraInfo,l=e.call(this,s)||this;return l.name="ApolloError",l.graphQLErrors=r||[],l.protocolErrors=i||[],l.clientErrors=a||[],l.networkError=o||null,l.message=s||u(l),l.extraInfo=c,l.__proto__=t.prototype,l}return(0,r.ZT)(t,e),t}(Error)},85317(e,t,n){"use strict";n.d(t,{K:()=>a});var r=n(67294),i=n(30320).aS?Symbol.for("__APOLLO_CONTEXT__"):"__APOLLO_CONTEXT__";function a(){var e=r.createContext[i];return e||(Object.defineProperty(r.createContext,i,{value:e=r.createContext({}),enumerable:!1,writable:!1,configurable:!0}),e.displayName="ApolloContext"),e}},21436(e,t,n){"use strict";n.d(t,{O:()=>i,k:()=>r});var r=Array.isArray;function i(e){return Array.isArray(e)&&e.length>0}},30320(e,t,n){"use strict";n.d(t,{DN:()=>s,JC:()=>l,aS:()=>o,mr:()=>i,sy:()=>a});var r=n(83952),i="function"==typeof WeakMap&&"ReactNative"!==(0,r.wY)(function(){return navigator.product}),a="function"==typeof WeakSet,o="function"==typeof Symbol&&"function"==typeof Symbol.for,s=o&&Symbol.asyncIterator,u="function"==typeof(0,r.wY)(function(){return window.document.createElement}),c=(0,r.wY)(function(){return navigator.userAgent.indexOf("jsdom")>=0})||!1,l=u&&!c},53712(e,t,n){"use strict";function r(){for(var e=[],t=0;tr})},10542(e,t,n){"use strict";n.d(t,{J:()=>o}),n(83952);var r=n(13154);function i(e){var t=new Set([e]);return t.forEach(function(e){(0,r.s)(e)&&a(e)===e&&Object.getOwnPropertyNames(e).forEach(function(n){(0,r.s)(e[n])&&t.add(e[n])})}),e}function a(e){if(__DEV__&&!Object.isFrozen(e))try{Object.freeze(e)}catch(t){if(t instanceof TypeError)return null;throw t}return e}function o(e){return __DEV__&&i(e),e}},14012(e,t,n){"use strict";n.d(t,{J:()=>a});var r=n(70655),i=n(53712);function a(e,t){return(0,i.o)(e,t,t.variables&&{variables:(0,r.pi)((0,r.pi)({},e&&e.variables),t.variables)})}},13154(e,t,n){"use strict";function r(e){return null!==e&&"object"==typeof e}n.d(t,{s:()=>r})},83952(e,t,n){"use strict";n.d(t,{ej:()=>u,kG:()=>c,wY:()=>h});var r,i=n(70655),a="Invariant Violation",o=Object.setPrototypeOf,s=void 0===o?function(e,t){return e.__proto__=t,e}:o,u=function(e){function t(n){void 0===n&&(n=a);var r=e.call(this,"number"==typeof n?a+": "+n+" (see https://github.com/apollographql/invariant-packages)":n)||this;return r.framesToPop=1,r.name=a,s(r,t.prototype),r}return(0,i.ZT)(t,e),t}(Error);function c(e,t){if(!e)throw new u(t)}var l=["debug","log","warn","error","silent"],f=l.indexOf("log");function d(e){return function(){if(l.indexOf(e)>=f)return(console[e]||console.log).apply(console,arguments)}}function h(e){try{return e()}catch(t){}}(r=c||(c={})).debug=d("debug"),r.log=d("log"),r.warn=d("warn"),r.error=d("error");let p=h(function(){return globalThis})||h(function(){return window})||h(function(){return self})||h(function(){return global})||h(function(){return h.constructor("return this")()});var b="__",m=[b,b].join("DEV");function g(){try{return Boolean(__DEV__)}catch(e){return Object.defineProperty(p,m,{value:"production"!==h(function(){return"production"}),enumerable:!1,configurable:!0,writable:!0}),p[m]}}let v=g();function y(e){try{return e()}catch(t){}}var w=y(function(){return globalThis})||y(function(){return window})||y(function(){return self})||y(function(){return global})||y(function(){return y.constructor("return this")()}),_=!1;function E(){!w||y(function(){return"production"})||y(function(){return process})||(Object.defineProperty(w,"process",{value:{env:{NODE_ENV:"production"}},configurable:!0,enumerable:!1,writable:!0}),_=!0)}function S(){_&&(delete w.process,_=!1)}E();var k=n(10143);function x(){return k.H,S()}function T(){__DEV__?c("boolean"==typeof v,v):c("boolean"==typeof v,39)}x(),T()},4942(e,t,n){"use strict";function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}n.d(t,{Z:()=>r})},87462(e,t,n){"use strict";function r(){return(r=Object.assign?Object.assign.bind():function(e){for(var t=1;tr})},51721(e,t,n){"use strict";function r(e,t){return(r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e})(e,t)}function i(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{Z:()=>i})},63366(e,t,n){"use strict";function r(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}n.d(t,{Z:()=>r})},25821(e,t,n){"use strict";n.d(t,{Z:()=>s});var r=n(45695);function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var a=10,o=2;function s(e){return u(e,[])}function u(e,t){switch(i(e)){case"string":return JSON.stringify(e);case"function":return e.name?"[function ".concat(e.name,"]"):"[function]";case"object":if(null===e)return"null";return c(e,t);default:return String(e)}}function c(e,t){if(-1!==t.indexOf(e))return"[Circular]";var n=[].concat(t,[e]),r=d(e);if(void 0!==r){var i=r.call(e);if(i!==e)return"string"==typeof i?i:u(i,n)}else if(Array.isArray(e))return f(e,n);return l(e,n)}function l(e,t){var n=Object.keys(e);return 0===n.length?"{}":t.length>o?"["+h(e)+"]":"{ "+n.map(function(n){var r=u(e[n],t);return n+": "+r}).join(", ")+" }"}function f(e,t){if(0===e.length)return"[]";if(t.length>o)return"[Array]";for(var n=Math.min(a,e.length),r=e.length-n,i=[],s=0;s1&&i.push("... ".concat(r," more items")),"["+i.join(", ")+"]"}function d(e){var t=e[String(r.Z)];return"function"==typeof t?t:"function"==typeof e.inspect?e.inspect:void 0}function h(e){var t=Object.prototype.toString.call(e).replace(/^\[object /,"").replace(/]$/,"");if("Object"===t&&"function"==typeof e.constructor){var n=e.constructor.name;if("string"==typeof n&&""!==n)return n}return t}},45695(e,t,n){"use strict";n.d(t,{Z:()=>i});var r="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):void 0;let i=r},25217(e,t,n){"use strict";function r(e,t){if(!Boolean(e))throw Error(null!=t?t:"Unexpected invariant triggered.")}n.d(t,{Ye:()=>o,WU:()=>s,UG:()=>u});var i=n(45695);function a(e){var t=e.prototype.toJSON;"function"==typeof t||r(0),e.prototype.inspect=t,i.Z&&(e.prototype[i.Z]=t)}var o=function(){function e(e,t,n){this.start=e.start,this.end=t.end,this.startToken=e,this.endToken=t,this.source=n}return e.prototype.toJSON=function(){return{start:this.start,end:this.end}},e}();a(o);var s=function(){function e(e,t,n,r,i,a,o){this.kind=e,this.start=t,this.end=n,this.line=r,this.column=i,this.value=o,this.prev=a,this.next=null}return e.prototype.toJSON=function(){return{kind:this.kind,value:this.value,line:this.line,column:this.column}},e}();function u(e){return null!=e&&"string"==typeof e.kind}a(s)},87392(e,t,n){"use strict";function r(e){var t=e.split(/\r\n|[\n\r]/g),n=a(e);if(0!==n)for(var r=1;ro&&i(t[s-1]);)--s;return t.slice(o,s).join("\n")}function i(e){for(var t=0;t1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=-1===e.indexOf("\n"),i=" "===e[0]||" "===e[0],a='"'===e[e.length-1],o="\\"===e[e.length-1],s=!r||a||o||n,u="";return s&&!(r&&i)&&(u+="\n"+t),u+=t?e.replace(/\n/g,"\n"+t):e,s&&(u+="\n"),'"""'+u.replace(/"""/g,'\\"""')+'"""'}n.d(t,{LZ:()=>o,W7:()=>r})},97359(e,t,n){"use strict";n.d(t,{h:()=>r});var r=Object.freeze({NAME:"Name",DOCUMENT:"Document",OPERATION_DEFINITION:"OperationDefinition",VARIABLE_DEFINITION:"VariableDefinition",SELECTION_SET:"SelectionSet",FIELD:"Field",ARGUMENT:"Argument",FRAGMENT_SPREAD:"FragmentSpread",INLINE_FRAGMENT:"InlineFragment",FRAGMENT_DEFINITION:"FragmentDefinition",VARIABLE:"Variable",INT:"IntValue",FLOAT:"FloatValue",STRING:"StringValue",BOOLEAN:"BooleanValue",NULL:"NullValue",ENUM:"EnumValue",LIST:"ListValue",OBJECT:"ObjectValue",OBJECT_FIELD:"ObjectField",DIRECTIVE:"Directive",NAMED_TYPE:"NamedType",LIST_TYPE:"ListType",NON_NULL_TYPE:"NonNullType",SCHEMA_DEFINITION:"SchemaDefinition",OPERATION_TYPE_DEFINITION:"OperationTypeDefinition",SCALAR_TYPE_DEFINITION:"ScalarTypeDefinition",OBJECT_TYPE_DEFINITION:"ObjectTypeDefinition",FIELD_DEFINITION:"FieldDefinition",INPUT_VALUE_DEFINITION:"InputValueDefinition",INTERFACE_TYPE_DEFINITION:"InterfaceTypeDefinition",UNION_TYPE_DEFINITION:"UnionTypeDefinition",ENUM_TYPE_DEFINITION:"EnumTypeDefinition",ENUM_VALUE_DEFINITION:"EnumValueDefinition",INPUT_OBJECT_TYPE_DEFINITION:"InputObjectTypeDefinition",DIRECTIVE_DEFINITION:"DirectiveDefinition",SCHEMA_EXTENSION:"SchemaExtension",SCALAR_TYPE_EXTENSION:"ScalarTypeExtension",OBJECT_TYPE_EXTENSION:"ObjectTypeExtension",INTERFACE_TYPE_EXTENSION:"InterfaceTypeExtension",UNION_TYPE_EXTENSION:"UnionTypeExtension",ENUM_TYPE_EXTENSION:"EnumTypeExtension",INPUT_OBJECT_TYPE_EXTENSION:"InputObjectTypeExtension"})},10143(e,t,n){"use strict";n.d(t,{H:()=>c,T:()=>l});var r=n(99763),i=n(25821);function a(e,t){if(!Boolean(e))throw Error(t)}let o=function(e,t){return e instanceof t};function s(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:"GraphQL request",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{line:1,column:1};"string"==typeof e||a(0,"Body must be a string. Received: ".concat((0,i.Z)(e),".")),this.body=e,this.name=t,this.locationOffset=n,this.locationOffset.line>0||a(0,"line in locationOffset is 1-indexed and must be positive."),this.locationOffset.column>0||a(0,"column in locationOffset is 1-indexed and must be positive.")}return u(e,[{key:r.YF,get:function(){return"Source"}}]),e}();function l(e){return o(e,c)}},99763(e,t,n){"use strict";n.d(t,{YF:()=>r});var r="function"==typeof Symbol&&null!=Symbol.toStringTag?Symbol.toStringTag:"@@toStringTag"},37452(e){"use strict";e.exports=JSON.parse('{"AElig":"\xc6","AMP":"&","Aacute":"\xc1","Acirc":"\xc2","Agrave":"\xc0","Aring":"\xc5","Atilde":"\xc3","Auml":"\xc4","COPY":"\xa9","Ccedil":"\xc7","ETH":"\xd0","Eacute":"\xc9","Ecirc":"\xca","Egrave":"\xc8","Euml":"\xcb","GT":">","Iacute":"\xcd","Icirc":"\xce","Igrave":"\xcc","Iuml":"\xcf","LT":"<","Ntilde":"\xd1","Oacute":"\xd3","Ocirc":"\xd4","Ograve":"\xd2","Oslash":"\xd8","Otilde":"\xd5","Ouml":"\xd6","QUOT":"\\"","REG":"\xae","THORN":"\xde","Uacute":"\xda","Ucirc":"\xdb","Ugrave":"\xd9","Uuml":"\xdc","Yacute":"\xdd","aacute":"\xe1","acirc":"\xe2","acute":"\xb4","aelig":"\xe6","agrave":"\xe0","amp":"&","aring":"\xe5","atilde":"\xe3","auml":"\xe4","brvbar":"\xa6","ccedil":"\xe7","cedil":"\xb8","cent":"\xa2","copy":"\xa9","curren":"\xa4","deg":"\xb0","divide":"\xf7","eacute":"\xe9","ecirc":"\xea","egrave":"\xe8","eth":"\xf0","euml":"\xeb","frac12":"\xbd","frac14":"\xbc","frac34":"\xbe","gt":">","iacute":"\xed","icirc":"\xee","iexcl":"\xa1","igrave":"\xec","iquest":"\xbf","iuml":"\xef","laquo":"\xab","lt":"<","macr":"\xaf","micro":"\xb5","middot":"\xb7","nbsp":"\xa0","not":"\xac","ntilde":"\xf1","oacute":"\xf3","ocirc":"\xf4","ograve":"\xf2","ordf":"\xaa","ordm":"\xba","oslash":"\xf8","otilde":"\xf5","ouml":"\xf6","para":"\xb6","plusmn":"\xb1","pound":"\xa3","quot":"\\"","raquo":"\xbb","reg":"\xae","sect":"\xa7","shy":"\xad","sup1":"\xb9","sup2":"\xb2","sup3":"\xb3","szlig":"\xdf","thorn":"\xfe","times":"\xd7","uacute":"\xfa","ucirc":"\xfb","ugrave":"\xf9","uml":"\xa8","uuml":"\xfc","yacute":"\xfd","yen":"\xa5","yuml":"\xff"}')},93580(e){"use strict";e.exports=JSON.parse('{"0":"�","128":"€","130":"‚","131":"ƒ","132":"„","133":"…","134":"†","135":"‡","136":"ˆ","137":"‰","138":"Š","139":"‹","140":"Œ","142":"Ž","145":"‘","146":"’","147":"“","148":"”","149":"•","150":"–","151":"—","152":"˜","153":"™","154":"š","155":"›","156":"œ","158":"ž","159":"Ÿ"}')},67946(e){"use strict";e.exports=JSON.parse('{"locale":"en","long":{"year":{"previous":"last year","current":"this year","next":"next year","past":{"one":"{0} year ago","other":"{0} years ago"},"future":{"one":"in {0} year","other":"in {0} years"}},"quarter":{"previous":"last quarter","current":"this quarter","next":"next quarter","past":{"one":"{0} quarter ago","other":"{0} quarters ago"},"future":{"one":"in {0} quarter","other":"in {0} quarters"}},"month":{"previous":"last month","current":"this month","next":"next month","past":{"one":"{0} month ago","other":"{0} months ago"},"future":{"one":"in {0} month","other":"in {0} months"}},"week":{"previous":"last week","current":"this week","next":"next week","past":{"one":"{0} week ago","other":"{0} weeks ago"},"future":{"one":"in {0} week","other":"in {0} weeks"}},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":{"one":"{0} hour ago","other":"{0} hours ago"},"future":{"one":"in {0} hour","other":"in {0} hours"}},"minute":{"current":"this minute","past":{"one":"{0} minute ago","other":"{0} minutes ago"},"future":{"one":"in {0} minute","other":"in {0} minutes"}},"second":{"current":"now","past":{"one":"{0} second ago","other":"{0} seconds ago"},"future":{"one":"in {0} second","other":"in {0} seconds"}}},"short":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"narrow":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"now":{"now":{"current":"now","future":"in a moment","past":"just now"}},"mini":{"year":"{0}yr","month":"{0}mo","week":"{0}wk","day":"{0}d","hour":"{0}h","minute":"{0}m","second":"{0}s","now":"now"},"short-time":{"year":"{0} yr.","month":"{0} mo.","week":"{0} wk.","day":{"one":"{0} day","other":"{0} days"},"hour":"{0} hr.","minute":"{0} min.","second":"{0} sec."},"long-time":{"year":{"one":"{0} year","other":"{0} years"},"month":{"one":"{0} month","other":"{0} months"},"week":{"one":"{0} week","other":"{0} weeks"},"day":{"one":"{0} day","other":"{0} days"},"hour":{"one":"{0} hour","other":"{0} hours"},"minute":{"one":"{0} minute","other":"{0} minutes"},"second":{"one":"{0} second","other":"{0} seconds"}}}')}},__webpack_module_cache__={};function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[e]={id:e,loaded:!1,exports:{}};return __webpack_modules__[e].call(n.exports,n,n.exports,__webpack_require__),n.loaded=!0,n.exports}__webpack_require__.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},(()=>{var e,t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__;__webpack_require__.t=function(n,r){if(1&r&&(n=this(n)),8&r||"object"==typeof n&&n&&(4&r&&n.__esModule||16&r&&"function"==typeof n.then))return n;var i=Object.create(null);__webpack_require__.r(i);var a={};e=e||[null,t({}),t([]),t(t)];for(var o=2&r&&n;"object"==typeof o&&!~e.indexOf(o);o=t(o))Object.getOwnPropertyNames(o).forEach(e=>a[e]=()=>n[e]);return a.default=()=>n,__webpack_require__.d(i,a),i}})(),__webpack_require__.d=(e,t)=>{for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.hmd=e=>((e=Object.create(e)).children||(e.children=[]),Object.defineProperty(e,"exports",{enumerable:!0,set(){throw Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+e.id)}}),e),__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},__webpack_require__.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),__webpack_require__.p="/assets/",__webpack_require__.nc=void 0;var __webpack_exports__={};(()=>{"use strict";var e,t,n,r,i=__webpack_require__(32316),a=__webpack_require__(8126),o=__webpack_require__(5690),s=__webpack_require__(30381),u=__webpack_require__.n(s),c=__webpack_require__(67294),l=__webpack_require__(73935),f=__webpack_require__.n(l),d=__webpack_require__(57209),h=__webpack_require__(37703),p=__webpack_require__(97779),b=__webpack_require__(28500);function m(e){return function(t){var n=t.dispatch,r=t.getState;return function(t){return function(i){return"function"==typeof i?i(n,r,e):t(i)}}}}var g=m();g.withExtraArgument=m;let v=g;var y=__webpack_require__(76489);function w(e){return function(t){return function(n){return function(r){n(r);var i=e||document&&document.cookie||"",a=t.getState();if("MATCH_ROUTE"===r.type&&"/signin"!==a.notifications.currentUrl){var o=(0,y.Q)(i);if(o.explorer)try{var s=JSON.parse(o.explorer);if("error"===s.status){var u=_(s.url);n({type:"NOTIFY_ERROR_MSG",msg:u})}}catch(c){n({type:"NOTIFY_ERROR_MSG",msg:"Invalid explorer status"})}}}}}}function _(e){var t="Can't connect to explorer: ".concat(e);return e.match(/^wss?:.+/)?t:"".concat(t,". You must use a websocket.")}var E=__webpack_require__(16353);function S(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function ei(e,t){if(e){if("string"==typeof e)return ea(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return ea(e,t)}}function ea(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1,i=!1,a=arguments[1],o=a;return new n(function(n){return t.subscribe({next:function(t){var a=!i;if(i=!0,!a||r)try{o=e(o,t)}catch(s){return n.error(s)}else o=t},error:function(e){n.error(e)},complete:function(){if(!i&&!r)return n.error(TypeError("Cannot reduce an empty sequence"));n.next(o),n.complete()}})})},t.concat=function(){for(var e=this,t=arguments.length,n=Array(t),r=0;r=0&&i.splice(e,1),o()}});i.push(s)},error:function(e){r.error(e)},complete:function(){o()}});function o(){a.closed&&0===i.length&&r.complete()}return function(){i.forEach(function(e){return e.unsubscribe()}),a.unsubscribe()}})},t[ed]=function(){return this},e.from=function(t){var n="function"==typeof this?this:e;if(null==t)throw TypeError(t+" is not an object");var r=ep(t,ed);if(r){var i=r.call(t);if(Object(i)!==i)throw TypeError(i+" is not an object");return em(i)&&i.constructor===n?i:new n(function(e){return i.subscribe(e)})}if(ec("iterator")&&(r=ep(t,ef)))return new n(function(e){ev(function(){if(!e.closed){for(var n,i=er(r.call(t));!(n=i()).done;){var a=n.value;if(e.next(a),e.closed)return}e.complete()}})});if(Array.isArray(t))return new n(function(e){ev(function(){if(!e.closed){for(var n=0;n0))return n.connection.key;var r=n.connection.filter?n.connection.filter:[];r.sort();var i={};return r.forEach(function(e){i[e]=t[e]}),"".concat(n.connection.key,"(").concat(eV(i),")")}var a=e;if(t){var o=eV(t);a+="(".concat(o,")")}return n&&Object.keys(n).forEach(function(e){-1===eW.indexOf(e)&&(n[e]&&Object.keys(n[e]).length?a+="@".concat(e,"(").concat(eV(n[e]),")"):a+="@".concat(e))}),a},{setStringify:function(e){var t=eV;return eV=e,t}}),eV=function(e){return JSON.stringify(e,eq)};function eq(e,t){return(0,eO.s)(t)&&!Array.isArray(t)&&(t=Object.keys(t).sort().reduce(function(e,n){return e[n]=t[n],e},{})),t}function eZ(e,t){if(e.arguments&&e.arguments.length){var n={};return e.arguments.forEach(function(e){var r;return ez(n,e.name,e.value,t)}),n}return null}function eX(e){return e.alias?e.alias.value:e.name.value}function eJ(e,t,n){for(var r,i=0,a=t.selections;it.indexOf(i))throw __DEV__?new Q.ej("illegal argument: ".concat(i)):new Q.ej(27)}return e}function tt(e,t){return t?t(e):eT.of()}function tn(e){return"function"==typeof e?new ta(e):e}function tr(e){return e.request.length<=1}var ti=function(e){function t(t,n){var r=e.call(this,t)||this;return r.link=n,r}return(0,en.ZT)(t,e),t}(Error),ta=function(){function e(e){e&&(this.request=e)}return e.empty=function(){return new e(function(){return eT.of()})},e.from=function(t){return 0===t.length?e.empty():t.map(tn).reduce(function(e,t){return e.concat(t)})},e.split=function(t,n,r){var i=tn(n),a=tn(r||new e(tt));return new e(tr(i)&&tr(a)?function(e){return t(e)?i.request(e)||eT.of():a.request(e)||eT.of()}:function(e,n){return t(e)?i.request(e,n)||eT.of():a.request(e,n)||eT.of()})},e.execute=function(e,t){return e.request(eM(t.context,e7(te(t))))||eT.of()},e.concat=function(t,n){var r=tn(t);if(tr(r))return __DEV__&&Q.kG.warn(new ti("You are calling concat on a terminating link, which will have no effect",r)),r;var i=tn(n);return new e(tr(i)?function(e){return r.request(e,function(e){return i.request(e)||eT.of()})||eT.of()}:function(e,t){return r.request(e,function(e){return i.request(e,t)||eT.of()})||eT.of()})},e.prototype.split=function(t,n,r){return this.concat(e.split(t,n,r||new e(tt)))},e.prototype.concat=function(t){return e.concat(this,t)},e.prototype.request=function(e,t){throw __DEV__?new Q.ej("request is not implemented"):new Q.ej(22)},e.prototype.onError=function(e,t){if(t&&t.error)return t.error(e),!1;throw e},e.prototype.setOnError=function(e){return this.onError=e,this},e}(),to=__webpack_require__(25821),ts=__webpack_require__(25217),tu={Name:[],Document:["definitions"],OperationDefinition:["name","variableDefinitions","directives","selectionSet"],VariableDefinition:["variable","type","defaultValue","directives"],Variable:["name"],SelectionSet:["selections"],Field:["alias","name","arguments","directives","selectionSet"],Argument:["name","value"],FragmentSpread:["name","directives"],InlineFragment:["typeCondition","directives","selectionSet"],FragmentDefinition:["name","variableDefinitions","typeCondition","directives","selectionSet"],IntValue:[],FloatValue:[],StringValue:[],BooleanValue:[],NullValue:[],EnumValue:[],ListValue:["values"],ObjectValue:["fields"],ObjectField:["name","value"],Directive:["name","arguments"],NamedType:["name"],ListType:["type"],NonNullType:["type"],SchemaDefinition:["description","directives","operationTypes"],OperationTypeDefinition:["type"],ScalarTypeDefinition:["description","name","directives"],ObjectTypeDefinition:["description","name","interfaces","directives","fields"],FieldDefinition:["description","name","arguments","type","directives"],InputValueDefinition:["description","name","type","defaultValue","directives"],InterfaceTypeDefinition:["description","name","interfaces","directives","fields"],UnionTypeDefinition:["description","name","directives","types"],EnumTypeDefinition:["description","name","directives","values"],EnumValueDefinition:["description","name","directives"],InputObjectTypeDefinition:["description","name","directives","fields"],DirectiveDefinition:["description","name","arguments","locations"],SchemaExtension:["directives","operationTypes"],ScalarTypeExtension:["name","directives"],ObjectTypeExtension:["name","interfaces","directives","fields"],InterfaceTypeExtension:["name","interfaces","directives","fields"],UnionTypeExtension:["name","directives","types"],EnumTypeExtension:["name","directives","values"],InputObjectTypeExtension:["name","directives","fields"]},tc=Object.freeze({});function tl(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:tu,r=void 0,i=Array.isArray(e),a=[e],o=-1,s=[],u=void 0,c=void 0,l=void 0,f=[],d=[],h=e;do{var p,b=++o===a.length,m=b&&0!==s.length;if(b){if(c=0===d.length?void 0:f[f.length-1],u=l,l=d.pop(),m){if(i)u=u.slice();else{for(var g={},v=0,y=Object.keys(u);v1)for(var r=new tB,i=1;i=0;--a){var o=i[a],s=isNaN(+o)?{}:[];s[o]=t,t=s}n=r.merge(n,t)}),n}var tW=Object.prototype.hasOwnProperty;function tK(e,t){var n,r,i,a,o;return(0,en.mG)(this,void 0,void 0,function(){var s,u,c,l,f,d,h,p,b,m,g,v,y,w,_,E,S,k,x,T,M,O,A;return(0,en.Jh)(this,function(L){switch(L.label){case 0:if(void 0===TextDecoder)throw Error("TextDecoder must be defined in the environment: please import a polyfill.");s=new TextDecoder("utf-8"),u=null===(n=e.headers)||void 0===n?void 0:n.get("content-type"),c="boundary=",l=(null==u?void 0:u.includes(c))?null==u?void 0:u.substring((null==u?void 0:u.indexOf(c))+c.length).replace(/['"]/g,"").replace(/\;(.*)/gm,"").trim():"-",f="\r\n--".concat(l),d="",h=tI(e),p=!0,L.label=1;case 1:if(!p)return[3,3];return[4,h.next()];case 2:for(m=(b=L.sent()).value,g=b.done,v="string"==typeof m?m:s.decode(m),y=d.length-f.length+1,p=!g,d+=v,w=d.indexOf(f,y);w>-1;){if(_=void 0,_=(O=[d.slice(0,w),d.slice(w+f.length),])[0],d=O[1],E=_.indexOf("\r\n\r\n"),(k=(S=tV(_.slice(0,E)))["content-type"])&&-1===k.toLowerCase().indexOf("application/json"))throw Error("Unsupported patch content type: application/json is required.");if(x=_.slice(E))try{T=tq(e,x),Object.keys(T).length>1||"data"in T||"incremental"in T||"errors"in T||"payload"in T?tz(T)?(M={},"payload"in T&&(M=(0,en.pi)({},T.payload)),"errors"in T&&(M=(0,en.pi)((0,en.pi)({},M),{extensions:(0,en.pi)((0,en.pi)({},"extensions"in M?M.extensions:null),((A={})[tN.YG]=T.errors,A))})),null===(r=t.next)||void 0===r||r.call(t,M)):null===(i=t.next)||void 0===i||i.call(t,T):1===Object.keys(T).length&&"hasNext"in T&&!T.hasNext&&(null===(a=t.complete)||void 0===a||a.call(t))}catch(C){tZ(C,t)}w=d.indexOf(f)}return[3,1];case 3:return null===(o=t.complete)||void 0===o||o.call(t),[2]}})})}function tV(e){var t={};return e.split("\n").forEach(function(e){var n=e.indexOf(":");if(n>-1){var r=e.slice(0,n).trim().toLowerCase(),i=e.slice(n+1).trim();t[r]=i}}),t}function tq(e,t){e.status>=300&&tD(e,function(){try{return JSON.parse(t)}catch(e){return t}}(),"Response not successful: Received status code ".concat(e.status));try{return JSON.parse(t)}catch(n){var r=n;throw r.name="ServerParseError",r.response=e,r.statusCode=e.status,r.bodyText=t,r}}function tZ(e,t){var n,r;"AbortError"!==e.name&&(e.result&&e.result.errors&&e.result.data&&(null===(n=t.next)||void 0===n||n.call(t,e.result)),null===(r=t.error)||void 0===r||r.call(t,e))}function tX(e,t,n){tJ(t)(e).then(function(e){var t,r;null===(t=n.next)||void 0===t||t.call(n,e),null===(r=n.complete)||void 0===r||r.call(n)}).catch(function(e){return tZ(e,n)})}function tJ(e){return function(t){return t.text().then(function(e){return tq(t,e)}).then(function(n){return t.status>=300&&tD(t,n,"Response not successful: Received status code ".concat(t.status)),Array.isArray(n)||tW.call(n,"data")||tW.call(n,"errors")||tD(t,n,"Server response was missing for query '".concat(Array.isArray(e)?e.map(function(e){return e.operationName}):e.operationName,"'.")),n})}}var tQ=function(e){if(!e&&"undefined"==typeof fetch)throw __DEV__?new Q.ej("\n\"fetch\" has not been found globally and no fetcher has been configured. To fix this, install a fetch package (like https://www.npmjs.com/package/cross-fetch), instantiate the fetcher, and pass it into your HttpLink constructor. For example:\n\nimport fetch from 'cross-fetch';\nimport { ApolloClient, HttpLink } from '@apollo/client';\nconst client = new ApolloClient({\n link: new HttpLink({ uri: '/graphql', fetch })\n});\n "):new Q.ej(23)},t1=__webpack_require__(87392);function t0(e){return tl(e,{leave:t3})}var t2=80,t3={Name:function(e){return e.value},Variable:function(e){return"$"+e.name},Document:function(e){return t6(e.definitions,"\n\n")+"\n"},OperationDefinition:function(e){var t=e.operation,n=e.name,r=t8("(",t6(e.variableDefinitions,", "),")"),i=t6(e.directives," "),a=e.selectionSet;return n||i||r||"query"!==t?t6([t,t6([n,r]),i,a]," "):a},VariableDefinition:function(e){var t=e.variable,n=e.type,r=e.defaultValue,i=e.directives;return t+": "+n+t8(" = ",r)+t8(" ",t6(i," "))},SelectionSet:function(e){return t5(e.selections)},Field:function(e){var t=e.alias,n=e.name,r=e.arguments,i=e.directives,a=e.selectionSet,o=t8("",t,": ")+n,s=o+t8("(",t6(r,", "),")");return s.length>t2&&(s=o+t8("(\n",t9(t6(r,"\n")),"\n)")),t6([s,t6(i," "),a]," ")},Argument:function(e){var t;return e.name+": "+e.value},FragmentSpread:function(e){var t;return"..."+e.name+t8(" ",t6(e.directives," "))},InlineFragment:function(e){var t=e.typeCondition,n=e.directives,r=e.selectionSet;return t6(["...",t8("on ",t),t6(n," "),r]," ")},FragmentDefinition:function(e){var t=e.name,n=e.typeCondition,r=e.variableDefinitions,i=e.directives,a=e.selectionSet;return"fragment ".concat(t).concat(t8("(",t6(r,", "),")")," ")+"on ".concat(n," ").concat(t8("",t6(i," ")," "))+a},IntValue:function(e){return e.value},FloatValue:function(e){return e.value},StringValue:function(e,t){var n=e.value;return e.block?(0,t1.LZ)(n,"description"===t?"":" "):JSON.stringify(n)},BooleanValue:function(e){return e.value?"true":"false"},NullValue:function(){return"null"},EnumValue:function(e){return e.value},ListValue:function(e){return"["+t6(e.values,", ")+"]"},ObjectValue:function(e){return"{"+t6(e.fields,", ")+"}"},ObjectField:function(e){var t;return e.name+": "+e.value},Directive:function(e){var t;return"@"+e.name+t8("(",t6(e.arguments,", "),")")},NamedType:function(e){return e.name},ListType:function(e){return"["+e.type+"]"},NonNullType:function(e){return e.type+"!"},SchemaDefinition:t4(function(e){var t=e.directives,n=e.operationTypes;return t6(["schema",t6(t," "),t5(n)]," ")}),OperationTypeDefinition:function(e){var t;return e.operation+": "+e.type},ScalarTypeDefinition:t4(function(e){var t;return t6(["scalar",e.name,t6(e.directives," ")]," ")}),ObjectTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["type",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")}),FieldDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.type,i=e.directives;return t+(ne(n)?t8("(\n",t9(t6(n,"\n")),"\n)"):t8("(",t6(n,", "),")"))+": "+r+t8(" ",t6(i," "))}),InputValueDefinition:t4(function(e){var t=e.name,n=e.type,r=e.defaultValue,i=e.directives;return t6([t+": "+n,t8("= ",r),t6(i," ")]," ")}),InterfaceTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["interface",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")}),UnionTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.types;return t6(["union",t,t6(n," "),r&&0!==r.length?"= "+t6(r," | "):""]," ")}),EnumTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.values;return t6(["enum",t,t6(n," "),t5(r)]," ")}),EnumValueDefinition:t4(function(e){var t;return t6([e.name,t6(e.directives," ")]," ")}),InputObjectTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.fields;return t6(["input",t,t6(n," "),t5(r)]," ")}),DirectiveDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.repeatable,i=e.locations;return"directive @"+t+(ne(n)?t8("(\n",t9(t6(n,"\n")),"\n)"):t8("(",t6(n,", "),")"))+(r?" repeatable":"")+" on "+t6(i," | ")}),SchemaExtension:function(e){var t=e.directives,n=e.operationTypes;return t6(["extend schema",t6(t," "),t5(n)]," ")},ScalarTypeExtension:function(e){var t;return t6(["extend scalar",e.name,t6(e.directives," ")]," ")},ObjectTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["extend type",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")},InterfaceTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["extend interface",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")},UnionTypeExtension:function(e){var t=e.name,n=e.directives,r=e.types;return t6(["extend union",t,t6(n," "),r&&0!==r.length?"= "+t6(r," | "):""]," ")},EnumTypeExtension:function(e){var t=e.name,n=e.directives,r=e.values;return t6(["extend enum",t,t6(n," "),t5(r)]," ")},InputObjectTypeExtension:function(e){var t=e.name,n=e.directives,r=e.fields;return t6(["extend input",t,t6(n," "),t5(r)]," ")}};function t4(e){return function(t){return t6([t.description,e(t)],"\n")}}function t6(e){var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return null!==(t=null==e?void 0:e.filter(function(e){return e}).join(n))&&void 0!==t?t:""}function t5(e){return t8("{\n",t9(t6(e,"\n")),"\n}")}function t8(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return null!=t&&""!==t?e+t+n:""}function t9(e){return t8(" ",e.replace(/\n/g,"\n "))}function t7(e){return -1!==e.indexOf("\n")}function ne(e){return null!=e&&e.some(t7)}var nt,nn,nr,ni={http:{includeQuery:!0,includeExtensions:!1,preserveHeaderCase:!1},headers:{accept:"*/*","content-type":"application/json"},options:{method:"POST"}},na=function(e,t){return t(e)};function no(e,t){for(var n=[],r=2;rObject.create(null),{forEach:nv,slice:ny}=Array.prototype,{hasOwnProperty:nw}=Object.prototype;class n_{constructor(e=!0,t=ng){this.weakness=e,this.makeData=t}lookup(...e){return this.lookupArray(e)}lookupArray(e){let t=this;return nv.call(e,e=>t=t.getChildTrie(e)),nw.call(t,"data")?t.data:t.data=this.makeData(ny.call(e))}peek(...e){return this.peekArray(e)}peekArray(e){let t=this;for(let n=0,r=e.length;t&&n=0;--o)t.definitions[o].kind===nL.h.OPERATION_DEFINITION&&++a;var s=nN(e),u=e.some(function(e){return e.remove}),c=function(e){return u&&e&&e.some(s)},l=new Map,f=!1,d={enter:function(e){if(c(e.directives))return f=!0,null}},h=tl(t,{Field:d,InlineFragment:d,VariableDefinition:{enter:function(){return!1}},Variable:{enter:function(e,t,n,r,a){var o=i(a);o&&o.variables.add(e.name.value)}},FragmentSpread:{enter:function(e,t,n,r,a){if(c(e.directives))return f=!0,null;var o=i(a);o&&o.fragmentSpreads.add(e.name.value)}},FragmentDefinition:{enter:function(e,t,n,r){l.set(JSON.stringify(r),e)},leave:function(e,t,n,i){return e===l.get(JSON.stringify(i))?e:a>0&&e.selectionSet.selections.every(function(e){return e.kind===nL.h.FIELD&&"__typename"===e.name.value})?(r(e.name.value).removed=!0,f=!0,null):void 0}},Directive:{leave:function(e){if(s(e))return f=!0,null}}});if(!f)return t;var p=function(e){return e.transitiveVars||(e.transitiveVars=new Set(e.variables),e.removed||e.fragmentSpreads.forEach(function(t){p(r(t)).transitiveVars.forEach(function(t){e.transitiveVars.add(t)})})),e},b=new Set;h.definitions.forEach(function(e){e.kind===nL.h.OPERATION_DEFINITION?p(n(e.name&&e.name.value)).fragmentSpreads.forEach(function(e){b.add(e)}):e.kind!==nL.h.FRAGMENT_DEFINITION||0!==a||r(e.name.value).removed||b.add(e.name.value)}),b.forEach(function(e){p(r(e)).fragmentSpreads.forEach(function(e){b.add(e)})});var m=function(e){return!!(!b.has(e)||r(e).removed)},g={enter:function(e){if(m(e.name.value))return null}};return nD(tl(h,{FragmentSpread:g,FragmentDefinition:g,OperationDefinition:{leave:function(e){if(e.variableDefinitions){var t=p(n(e.name&&e.name.value)).transitiveVars;if(t.size0},t.prototype.tearDownQuery=function(){this.isTornDown||(this.concast&&this.observer&&(this.concast.removeObserver(this.observer),delete this.concast,delete this.observer),this.stopPolling(),this.subscriptions.forEach(function(e){return e.unsubscribe()}),this.subscriptions.clear(),this.queryManager.stopQuery(this.queryId),this.observers.clear(),this.isTornDown=!0)},t}(eT);function n4(e){var t=e.options,n=t.fetchPolicy,r=t.nextFetchPolicy;return"cache-and-network"===n||"network-only"===n?e.reobserve({fetchPolicy:"cache-first",nextFetchPolicy:function(){return(this.nextFetchPolicy=r,"function"==typeof r)?r.apply(this,arguments):n}}):e.reobserve()}function n6(e){__DEV__&&Q.kG.error("Unhandled error",e.message,e.stack)}function n5(e){__DEV__&&e&&__DEV__&&Q.kG.debug("Missing cache result fields: ".concat(JSON.stringify(e)),e)}function n8(e){return"network-only"===e||"no-cache"===e||"standby"===e}nK(n3);function n9(e){return e.kind===nL.h.FIELD||e.kind===nL.h.FRAGMENT_SPREAD||e.kind===nL.h.INLINE_FRAGMENT}function n7(e){return e.kind===Kind.SCALAR_TYPE_DEFINITION||e.kind===Kind.OBJECT_TYPE_DEFINITION||e.kind===Kind.INTERFACE_TYPE_DEFINITION||e.kind===Kind.UNION_TYPE_DEFINITION||e.kind===Kind.ENUM_TYPE_DEFINITION||e.kind===Kind.INPUT_OBJECT_TYPE_DEFINITION}function re(e){return e.kind===Kind.SCALAR_TYPE_EXTENSION||e.kind===Kind.OBJECT_TYPE_EXTENSION||e.kind===Kind.INTERFACE_TYPE_EXTENSION||e.kind===Kind.UNION_TYPE_EXTENSION||e.kind===Kind.ENUM_TYPE_EXTENSION||e.kind===Kind.INPUT_OBJECT_TYPE_EXTENSION}var rt=function(){return Object.create(null)},rn=Array.prototype,rr=rn.forEach,ri=rn.slice,ra=function(){function e(e,t){void 0===e&&(e=!0),void 0===t&&(t=rt),this.weakness=e,this.makeData=t}return e.prototype.lookup=function(){for(var e=[],t=0;tclass{constructor(){this.id=["slot",rc++,Date.now(),Math.random().toString(36).slice(2),].join(":")}hasValue(){for(let e=rs;e;e=e.parent)if(this.id in e.slots){let t=e.slots[this.id];if(t===ru)break;return e!==rs&&(rs.slots[this.id]=t),!0}return rs&&(rs.slots[this.id]=ru),!1}getValue(){if(this.hasValue())return rs.slots[this.id]}withValue(e,t,n,r){let i={__proto__:null,[this.id]:e},a=rs;rs={parent:a,slots:i};try{return t.apply(r,n)}finally{rs=a}}static bind(e){let t=rs;return function(){let n=rs;try{return rs=t,e.apply(this,arguments)}finally{rs=n}}}static noContext(e,t,n){if(!rs)return e.apply(n,t);{let r=rs;try{return rs=null,e.apply(n,t)}finally{rs=r}}}};function rf(e){try{return e()}catch(t){}}let rd="@wry/context:Slot",rh=rf(()=>globalThis)||rf(()=>global)||Object.create(null),rp=rh,rb=rp[rd]||Array[rd]||function(e){try{Object.defineProperty(rp,rd,{value:e,enumerable:!1,writable:!1,configurable:!0})}finally{return e}}(rl()),{bind:rm,noContext:rg}=rb;function rv(){}var ry=function(){function e(e,t){void 0===e&&(e=1/0),void 0===t&&(t=rv),this.max=e,this.dispose=t,this.map=new Map,this.newest=null,this.oldest=null}return e.prototype.has=function(e){return this.map.has(e)},e.prototype.get=function(e){var t=this.getNode(e);return t&&t.value},e.prototype.getNode=function(e){var t=this.map.get(e);if(t&&t!==this.newest){var n=t.older,r=t.newer;r&&(r.older=n),n&&(n.newer=r),t.older=this.newest,t.older.newer=t,t.newer=null,this.newest=t,t===this.oldest&&(this.oldest=r)}return t},e.prototype.set=function(e,t){var n=this.getNode(e);return n?n.value=t:(n={key:e,value:t,newer:null,older:this.newest},this.newest&&(this.newest.newer=n),this.newest=n,this.oldest=this.oldest||n,this.map.set(e,n),n.value)},e.prototype.clean=function(){for(;this.oldest&&this.map.size>this.max;)this.delete(this.oldest.key)},e.prototype.delete=function(e){var t=this.map.get(e);return!!t&&(t===this.newest&&(this.newest=t.older),t===this.oldest&&(this.oldest=t.newer),t.newer&&(t.newer.older=t.older),t.older&&(t.older.newer=t.newer),this.map.delete(e),this.dispose(t.value,e),!0)},e}(),rw=new rb,r_=Object.prototype.hasOwnProperty,rE=void 0===(n=Array.from)?function(e){var t=[];return e.forEach(function(e){return t.push(e)}),t}:n;function rS(e){var t=e.unsubscribe;"function"==typeof t&&(e.unsubscribe=void 0,t())}var rk=[],rx=100;function rT(e,t){if(!e)throw Error(t||"assertion failure")}function rM(e,t){var n=e.length;return n>0&&n===t.length&&e[n-1]===t[n-1]}function rO(e){switch(e.length){case 0:throw Error("unknown value");case 1:return e[0];case 2:throw e[1]}}function rA(e){return e.slice(0)}var rL=function(){function e(t){this.fn=t,this.parents=new Set,this.childValues=new Map,this.dirtyChildren=null,this.dirty=!0,this.recomputing=!1,this.value=[],this.deps=null,++e.count}return e.prototype.peek=function(){if(1===this.value.length&&!rN(this))return rC(this),this.value[0]},e.prototype.recompute=function(e){return rT(!this.recomputing,"already recomputing"),rC(this),rN(this)?rI(this,e):rO(this.value)},e.prototype.setDirty=function(){this.dirty||(this.dirty=!0,this.value.length=0,rR(this),rS(this))},e.prototype.dispose=function(){var e=this;this.setDirty(),rH(this),rF(this,function(t,n){t.setDirty(),r$(t,e)})},e.prototype.forget=function(){this.dispose()},e.prototype.dependOn=function(e){e.add(this),this.deps||(this.deps=rk.pop()||new Set),this.deps.add(e)},e.prototype.forgetDeps=function(){var e=this;this.deps&&(rE(this.deps).forEach(function(t){return t.delete(e)}),this.deps.clear(),rk.push(this.deps),this.deps=null)},e.count=0,e}();function rC(e){var t=rw.getValue();if(t)return e.parents.add(t),t.childValues.has(e)||t.childValues.set(e,[]),rN(e)?rY(t,e):rB(t,e),t}function rI(e,t){return rH(e),rw.withValue(e,rD,[e,t]),rz(e,t)&&rP(e),rO(e.value)}function rD(e,t){e.recomputing=!0,e.value.length=0;try{e.value[0]=e.fn.apply(null,t)}catch(n){e.value[1]=n}e.recomputing=!1}function rN(e){return e.dirty||!!(e.dirtyChildren&&e.dirtyChildren.size)}function rP(e){e.dirty=!1,!rN(e)&&rj(e)}function rR(e){rF(e,rY)}function rj(e){rF(e,rB)}function rF(e,t){var n=e.parents.size;if(n)for(var r=rE(e.parents),i=0;i0&&e.childValues.forEach(function(t,n){r$(e,n)}),e.forgetDeps(),rT(null===e.dirtyChildren)}function r$(e,t){t.parents.delete(e),e.childValues.delete(t),rU(e,t)}function rz(e,t){if("function"==typeof e.subscribe)try{rS(e),e.unsubscribe=e.subscribe.apply(null,t)}catch(n){return e.setDirty(),!1}return!0}var rG={setDirty:!0,dispose:!0,forget:!0};function rW(e){var t=new Map,n=e&&e.subscribe;function r(e){var r=rw.getValue();if(r){var i=t.get(e);i||t.set(e,i=new Set),r.dependOn(i),"function"==typeof n&&(rS(i),i.unsubscribe=n(e))}}return r.dirty=function(e,n){var r=t.get(e);if(r){var i=n&&r_.call(rG,n)?n:"setDirty";rE(r).forEach(function(e){return e[i]()}),t.delete(e),rS(r)}},r}function rK(){var e=new ra("function"==typeof WeakMap);return function(){return e.lookupArray(arguments)}}var rV=rK(),rq=new Set;function rZ(e,t){void 0===t&&(t=Object.create(null));var n=new ry(t.max||65536,function(e){return e.dispose()}),r=t.keyArgs,i=t.makeCacheKey||rK(),a=function(){var a=i.apply(null,r?r.apply(null,arguments):arguments);if(void 0===a)return e.apply(null,arguments);var o=n.get(a);o||(n.set(a,o=new rL(e)),o.subscribe=t.subscribe,o.forget=function(){return n.delete(a)});var s=o.recompute(Array.prototype.slice.call(arguments));return n.set(a,o),rq.add(n),rw.hasValue()||(rq.forEach(function(e){return e.clean()}),rq.clear()),s};function o(e){var t=n.get(e);t&&t.setDirty()}function s(e){var t=n.get(e);if(t)return t.peek()}function u(e){return n.delete(e)}return Object.defineProperty(a,"size",{get:function(){return n.map.size},configurable:!1,enumerable:!1}),a.dirtyKey=o,a.dirty=function(){o(i.apply(null,arguments))},a.peekKey=s,a.peek=function(){return s(i.apply(null,arguments))},a.forgetKey=u,a.forget=function(){return u(i.apply(null,arguments))},a.makeCacheKey=i,a.getKey=r?function(){return i.apply(null,r.apply(null,arguments))}:i,Object.freeze(a)}var rX=new rb,rJ=new WeakMap;function rQ(e){var t=rJ.get(e);return t||rJ.set(e,t={vars:new Set,dep:rW()}),t}function r1(e){rQ(e).vars.forEach(function(t){return t.forgetCache(e)})}function r0(e){rQ(e).vars.forEach(function(t){return t.attachCache(e)})}function r2(e){var t=new Set,n=new Set,r=function(a){if(arguments.length>0){if(e!==a){e=a,t.forEach(function(e){rQ(e).dep.dirty(r),r3(e)});var o=Array.from(n);n.clear(),o.forEach(function(t){return t(e)})}}else{var s=rX.getValue();s&&(i(s),rQ(s).dep(r))}return e};r.onNextChange=function(e){return n.add(e),function(){n.delete(e)}};var i=r.attachCache=function(e){return t.add(e),rQ(e).vars.add(r),r};return r.forgetCache=function(e){return t.delete(e)},r}function r3(e){e.broadcastWatches&&e.broadcastWatches()}var r4=function(){function e(e){var t=e.cache,n=e.client,r=e.resolvers,i=e.fragmentMatcher;this.selectionsToResolveCache=new WeakMap,this.cache=t,n&&(this.client=n),r&&this.addResolvers(r),i&&this.setFragmentMatcher(i)}return e.prototype.addResolvers=function(e){var t=this;this.resolvers=this.resolvers||{},Array.isArray(e)?e.forEach(function(e){t.resolvers=tj(t.resolvers,e)}):this.resolvers=tj(this.resolvers,e)},e.prototype.setResolvers=function(e){this.resolvers={},this.addResolvers(e)},e.prototype.getResolvers=function(){return this.resolvers||{}},e.prototype.runResolvers=function(e){var t=e.document,n=e.remoteResult,r=e.context,i=e.variables,a=e.onlyRunForcedResolvers,o=void 0!==a&&a;return(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(e){return t?[2,this.resolveDocument(t,n.data,r,i,this.fragmentMatcher,o).then(function(e){return(0,en.pi)((0,en.pi)({},n),{data:e.result})})]:[2,n]})})},e.prototype.setFragmentMatcher=function(e){this.fragmentMatcher=e},e.prototype.getFragmentMatcher=function(){return this.fragmentMatcher},e.prototype.clientQuery=function(e){return tb(["client"],e)&&this.resolvers?e:null},e.prototype.serverQuery=function(e){return n$(e)},e.prototype.prepareContext=function(e){var t=this.cache;return(0,en.pi)((0,en.pi)({},e),{cache:t,getCacheKey:function(e){return t.identify(e)}})},e.prototype.addExportedVariables=function(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(r){return e?[2,this.resolveDocument(e,this.buildRootValueFromCache(e,t)||{},this.prepareContext(n),t).then(function(e){return(0,en.pi)((0,en.pi)({},t),e.exportedVariables)})]:[2,(0,en.pi)({},t)]})})},e.prototype.shouldForceResolvers=function(e){var t=!1;return tl(e,{Directive:{enter:function(e){if("client"===e.name.value&&e.arguments&&(t=e.arguments.some(function(e){return"always"===e.name.value&&"BooleanValue"===e.value.kind&&!0===e.value.value})))return tc}}}),t},e.prototype.buildRootValueFromCache=function(e,t){return this.cache.diff({query:nH(e),variables:t,returnPartialData:!0,optimistic:!1}).result},e.prototype.resolveDocument=function(e,t,n,r,i,a){return void 0===n&&(n={}),void 0===r&&(r={}),void 0===i&&(i=function(){return!0}),void 0===a&&(a=!1),(0,en.mG)(this,void 0,void 0,function(){var o,s,u,c,l,f,d,h,p,b,m;return(0,en.Jh)(this,function(g){return o=e8(e),s=e4(e),u=eL(s),c=this.collectSelectionsToResolve(o,u),f=(l=o.operation)?l.charAt(0).toUpperCase()+l.slice(1):"Query",d=this,h=d.cache,p=d.client,b={fragmentMap:u,context:(0,en.pi)((0,en.pi)({},n),{cache:h,client:p}),variables:r,fragmentMatcher:i,defaultOperationType:f,exportedVariables:{},selectionsToResolve:c,onlyRunForcedResolvers:a},m=!1,[2,this.resolveSelectionSet(o.selectionSet,m,t,b).then(function(e){return{result:e,exportedVariables:b.exportedVariables}})]})})},e.prototype.resolveSelectionSet=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c=this;return(0,en.Jh)(this,function(l){return i=r.fragmentMap,a=r.context,o=r.variables,s=[n],u=function(e){return(0,en.mG)(c,void 0,void 0,function(){var u,c;return(0,en.Jh)(this,function(l){return(t||r.selectionsToResolve.has(e))&&td(e,o)?eQ(e)?[2,this.resolveField(e,t,n,r).then(function(t){var n;void 0!==t&&s.push(((n={})[eX(e)]=t,n))})]:(e1(e)?u=e:(u=i[e.name.value],__DEV__?(0,Q.kG)(u,"No fragment named ".concat(e.name.value)):(0,Q.kG)(u,11)),u&&u.typeCondition&&(c=u.typeCondition.name.value,r.fragmentMatcher(n,c,a)))?[2,this.resolveSelectionSet(u.selectionSet,t,n,r).then(function(e){s.push(e)})]:[2]:[2]})})},[2,Promise.all(e.selections.map(u)).then(function(){return tF(s)})]})})},e.prototype.resolveField=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c,l,f,d,h=this;return(0,en.Jh)(this,function(p){return n?(i=r.variables,a=e.name.value,o=eX(e),s=a!==o,c=Promise.resolve(u=n[o]||n[a]),(!r.onlyRunForcedResolvers||this.shouldForceResolvers(e))&&(l=n.__typename||r.defaultOperationType,(f=this.resolvers&&this.resolvers[l])&&(d=f[s?a:o])&&(c=Promise.resolve(rX.withValue(this.cache,d,[n,eZ(e,i),r.context,{field:e,fragmentMap:r.fragmentMap},])))),[2,c.then(function(n){if(void 0===n&&(n=u),e.directives&&e.directives.forEach(function(e){"export"===e.name.value&&e.arguments&&e.arguments.forEach(function(e){"as"===e.name.value&&"StringValue"===e.value.kind&&(r.exportedVariables[e.value.value]=n)})}),!e.selectionSet||null==n)return n;var i,a,o=null!==(a=null===(i=e.directives)||void 0===i?void 0:i.some(function(e){return"client"===e.name.value}))&&void 0!==a&&a;return Array.isArray(n)?h.resolveSubSelectedArray(e,t||o,n,r):e.selectionSet?h.resolveSelectionSet(e.selectionSet,t||o,n,r):void 0})]):[2,null]})})},e.prototype.resolveSubSelectedArray=function(e,t,n,r){var i=this;return Promise.all(n.map(function(n){return null===n?null:Array.isArray(n)?i.resolveSubSelectedArray(e,t,n,r):e.selectionSet?i.resolveSelectionSet(e.selectionSet,t,n,r):void 0}))},e.prototype.collectSelectionsToResolve=function(e,t){var n=function(e){return!Array.isArray(e)},r=this.selectionsToResolveCache;function i(e){if(!r.has(e)){var a=new Set;r.set(e,a),tl(e,{Directive:function(e,t,r,i,o){"client"===e.name.value&&o.forEach(function(e){n(e)&&n9(e)&&a.add(e)})},FragmentSpread:function(e,r,o,s,u){var c=t[e.name.value];__DEV__?(0,Q.kG)(c,"No fragment named ".concat(e.name.value)):(0,Q.kG)(c,12);var l=i(c);l.size>0&&(u.forEach(function(e){n(e)&&n9(e)&&a.add(e)}),a.add(e),l.forEach(function(e){a.add(e)}))}})}return r.get(e)}return i(e)},e}(),r6=new(t_.mr?WeakMap:Map);function r5(e,t){var n=e[t];"function"==typeof n&&(e[t]=function(){return r6.set(e,(r6.get(e)+1)%1e15),n.apply(this,arguments)})}function r8(e){e.notifyTimeout&&(clearTimeout(e.notifyTimeout),e.notifyTimeout=void 0)}var r9=function(){function e(e,t){void 0===t&&(t=e.generateQueryId()),this.queryId=t,this.listeners=new Set,this.document=null,this.lastRequestId=1,this.subscriptions=new Set,this.stopped=!1,this.dirty=!1,this.observableQuery=null;var n=this.cache=e.cache;r6.has(n)||(r6.set(n,0),r5(n,"evict"),r5(n,"modify"),r5(n,"reset"))}return e.prototype.init=function(e){var t=e.networkStatus||nZ.I.loading;return this.variables&&this.networkStatus!==nZ.I.loading&&!(0,nm.D)(this.variables,e.variables)&&(t=nZ.I.setVariables),(0,nm.D)(e.variables,this.variables)||(this.lastDiff=void 0),Object.assign(this,{document:e.document,variables:e.variables,networkError:null,graphQLErrors:this.graphQLErrors||[],networkStatus:t}),e.observableQuery&&this.setObservableQuery(e.observableQuery),e.lastRequestId&&(this.lastRequestId=e.lastRequestId),this},e.prototype.reset=function(){r8(this),this.dirty=!1},e.prototype.getDiff=function(e){void 0===e&&(e=this.variables);var t=this.getDiffOptions(e);if(this.lastDiff&&(0,nm.D)(t,this.lastDiff.options))return this.lastDiff.diff;this.updateWatch(this.variables=e);var n=this.observableQuery;if(n&&"no-cache"===n.options.fetchPolicy)return{complete:!1};var r=this.cache.diff(t);return this.updateLastDiff(r,t),r},e.prototype.updateLastDiff=function(e,t){this.lastDiff=e?{diff:e,options:t||this.getDiffOptions()}:void 0},e.prototype.getDiffOptions=function(e){var t;return void 0===e&&(e=this.variables),{query:this.document,variables:e,returnPartialData:!0,optimistic:!0,canonizeResults:null===(t=this.observableQuery)||void 0===t?void 0:t.options.canonizeResults}},e.prototype.setDiff=function(e){var t=this,n=this.lastDiff&&this.lastDiff.diff;this.updateLastDiff(e),this.dirty||(0,nm.D)(n&&n.result,e&&e.result)||(this.dirty=!0,this.notifyTimeout||(this.notifyTimeout=setTimeout(function(){return t.notify()},0)))},e.prototype.setObservableQuery=function(e){var t=this;e!==this.observableQuery&&(this.oqListener&&this.listeners.delete(this.oqListener),this.observableQuery=e,e?(e.queryInfo=this,this.listeners.add(this.oqListener=function(){t.getDiff().fromOptimisticTransaction?e.observe():n4(e)})):delete this.oqListener)},e.prototype.notify=function(){var e=this;r8(this),this.shouldNotify()&&this.listeners.forEach(function(t){return t(e)}),this.dirty=!1},e.prototype.shouldNotify=function(){if(!this.dirty||!this.listeners.size)return!1;if((0,nZ.O)(this.networkStatus)&&this.observableQuery){var e=this.observableQuery.options.fetchPolicy;if("cache-only"!==e&&"cache-and-network"!==e)return!1}return!0},e.prototype.stop=function(){if(!this.stopped){this.stopped=!0,this.reset(),this.cancel(),this.cancel=e.prototype.cancel,this.subscriptions.forEach(function(e){return e.unsubscribe()});var t=this.observableQuery;t&&t.stopPolling()}},e.prototype.cancel=function(){},e.prototype.updateWatch=function(e){var t=this;void 0===e&&(e=this.variables);var n=this.observableQuery;if(!n||"no-cache"!==n.options.fetchPolicy){var r=(0,en.pi)((0,en.pi)({},this.getDiffOptions(e)),{watcher:this,callback:function(e){return t.setDiff(e)}});this.lastWatch&&(0,nm.D)(r,this.lastWatch)||(this.cancel(),this.cancel=this.cache.watch(this.lastWatch=r))}},e.prototype.resetLastWrite=function(){this.lastWrite=void 0},e.prototype.shouldWrite=function(e,t){var n=this.lastWrite;return!(n&&n.dmCount===r6.get(this.cache)&&(0,nm.D)(t,n.variables)&&(0,nm.D)(e.data,n.result.data))},e.prototype.markResult=function(e,t,n,r){var i=this,a=new tB,o=(0,tP.O)(e.errors)?e.errors.slice(0):[];if(this.reset(),"incremental"in e&&(0,tP.O)(e.incremental)){var s=tG(this.getDiff().result,e);e.data=s}else if("hasNext"in e&&e.hasNext){var u=this.getDiff();e.data=a.merge(u.result,e.data)}this.graphQLErrors=o,"no-cache"===n.fetchPolicy?this.updateLastDiff({result:e.data,complete:!0},this.getDiffOptions(n.variables)):0!==r&&(r7(e,n.errorPolicy)?this.cache.performTransaction(function(a){if(i.shouldWrite(e,n.variables))a.writeQuery({query:t,data:e.data,variables:n.variables,overwrite:1===r}),i.lastWrite={result:e,variables:n.variables,dmCount:r6.get(i.cache)};else if(i.lastDiff&&i.lastDiff.diff.complete){e.data=i.lastDiff.diff.result;return}var o=i.getDiffOptions(n.variables),s=a.diff(o);i.stopped||i.updateWatch(n.variables),i.updateLastDiff(s,o),s.complete&&(e.data=s.result)}):this.lastWrite=void 0)},e.prototype.markReady=function(){return this.networkError=null,this.networkStatus=nZ.I.ready},e.prototype.markError=function(e){return this.networkStatus=nZ.I.error,this.lastWrite=void 0,this.reset(),e.graphQLErrors&&(this.graphQLErrors=e.graphQLErrors),e.networkError&&(this.networkError=e.networkError),e},e}();function r7(e,t){void 0===t&&(t="none");var n="ignore"===t||"all"===t,r=!nO(e);return!r&&n&&e.data&&(r=!0),r}var ie=Object.prototype.hasOwnProperty,it=function(){function e(e){var t=e.cache,n=e.link,r=e.defaultOptions,i=e.queryDeduplication,a=void 0!==i&&i,o=e.onBroadcast,s=e.ssrMode,u=void 0!==s&&s,c=e.clientAwareness,l=void 0===c?{}:c,f=e.localState,d=e.assumeImmutableResults;this.clientAwareness={},this.queries=new Map,this.fetchCancelFns=new Map,this.transformCache=new(t_.mr?WeakMap:Map),this.queryIdCounter=1,this.requestIdCounter=1,this.mutationIdCounter=1,this.inFlightLinkObservables=new Map,this.cache=t,this.link=n,this.defaultOptions=r||Object.create(null),this.queryDeduplication=a,this.clientAwareness=l,this.localState=f||new r4({cache:t}),this.ssrMode=u,this.assumeImmutableResults=!!d,(this.onBroadcast=o)&&(this.mutationStore=Object.create(null))}return e.prototype.stop=function(){var e=this;this.queries.forEach(function(t,n){e.stopQueryNoBroadcast(n)}),this.cancelPendingFetches(__DEV__?new Q.ej("QueryManager stopped while query was in flight"):new Q.ej(14))},e.prototype.cancelPendingFetches=function(e){this.fetchCancelFns.forEach(function(t){return t(e)}),this.fetchCancelFns.clear()},e.prototype.mutate=function(e){var t,n,r=e.mutation,i=e.variables,a=e.optimisticResponse,o=e.updateQueries,s=e.refetchQueries,u=void 0===s?[]:s,c=e.awaitRefetchQueries,l=void 0!==c&&c,f=e.update,d=e.onQueryUpdated,h=e.fetchPolicy,p=void 0===h?(null===(t=this.defaultOptions.mutate)||void 0===t?void 0:t.fetchPolicy)||"network-only":h,b=e.errorPolicy,m=void 0===b?(null===(n=this.defaultOptions.mutate)||void 0===n?void 0:n.errorPolicy)||"none":b,g=e.keepRootFields,v=e.context;return(0,en.mG)(this,void 0,void 0,function(){var e,t,n,s,c,h;return(0,en.Jh)(this,function(b){switch(b.label){case 0:if(__DEV__?(0,Q.kG)(r,"mutation option is required. You must specify your GraphQL document in the mutation option."):(0,Q.kG)(r,15),__DEV__?(0,Q.kG)("network-only"===p||"no-cache"===p,"Mutations support only 'network-only' or 'no-cache' fetchPolicy strings. The default `network-only` behavior automatically writes mutation results to the cache. Passing `no-cache` skips the cache write."):(0,Q.kG)("network-only"===p||"no-cache"===p,16),e=this.generateMutationId(),n=(t=this.transform(r)).document,s=t.hasClientExports,r=this.cache.transformForLink(n),i=this.getVariables(r,i),!s)return[3,2];return[4,this.localState.addExportedVariables(r,i,v)];case 1:i=b.sent(),b.label=2;case 2:return c=this.mutationStore&&(this.mutationStore[e]={mutation:r,variables:i,loading:!0,error:null}),a&&this.markMutationOptimistic(a,{mutationId:e,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,updateQueries:o,update:f,keepRootFields:g}),this.broadcastQueries(),h=this,[2,new Promise(function(t,n){return nM(h.getObservableFromLink(r,(0,en.pi)((0,en.pi)({},v),{optimisticResponse:a}),i,!1),function(t){if(nO(t)&&"none"===m)throw new tN.cA({graphQLErrors:nA(t)});c&&(c.loading=!1,c.error=null);var n=(0,en.pi)({},t);return"function"==typeof u&&(u=u(n)),"ignore"===m&&nO(n)&&delete n.errors,h.markMutationResult({mutationId:e,result:n,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,update:f,updateQueries:o,awaitRefetchQueries:l,refetchQueries:u,removeOptimistic:a?e:void 0,onQueryUpdated:d,keepRootFields:g})}).subscribe({next:function(e){h.broadcastQueries(),"hasNext"in e&&!1!==e.hasNext||t(e)},error:function(t){c&&(c.loading=!1,c.error=t),a&&h.cache.removeOptimistic(e),h.broadcastQueries(),n(t instanceof tN.cA?t:new tN.cA({networkError:t}))}})})]}})})},e.prototype.markMutationResult=function(e,t){var n=this;void 0===t&&(t=this.cache);var r=e.result,i=[],a="no-cache"===e.fetchPolicy;if(!a&&r7(r,e.errorPolicy)){if(tU(r)||i.push({result:r.data,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}),tU(r)&&(0,tP.O)(r.incremental)){var o=t.diff({id:"ROOT_MUTATION",query:this.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0}),s=void 0;o.result&&(s=tG(o.result,r)),void 0!==s&&(r.data=s,i.push({result:s,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}))}var u=e.updateQueries;u&&this.queries.forEach(function(e,a){var o=e.observableQuery,s=o&&o.queryName;if(s&&ie.call(u,s)){var c,l=u[s],f=n.queries.get(a),d=f.document,h=f.variables,p=t.diff({query:d,variables:h,returnPartialData:!0,optimistic:!1}),b=p.result;if(p.complete&&b){var m=l(b,{mutationResult:r,queryName:d&&e3(d)||void 0,queryVariables:h});m&&i.push({result:m,dataId:"ROOT_QUERY",query:d,variables:h})}}})}if(i.length>0||e.refetchQueries||e.update||e.onQueryUpdated||e.removeOptimistic){var c=[];if(this.refetchQueries({updateCache:function(t){a||i.forEach(function(e){return t.write(e)});var o=e.update,s=!t$(r)||tU(r)&&!r.hasNext;if(o){if(!a){var u=t.diff({id:"ROOT_MUTATION",query:n.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0});u.complete&&("incremental"in(r=(0,en.pi)((0,en.pi)({},r),{data:u.result}))&&delete r.incremental,"hasNext"in r&&delete r.hasNext)}s&&o(t,r,{context:e.context,variables:e.variables})}a||e.keepRootFields||!s||t.modify({id:"ROOT_MUTATION",fields:function(e,t){var n=t.fieldName,r=t.DELETE;return"__typename"===n?e:r}})},include:e.refetchQueries,optimistic:!1,removeOptimistic:e.removeOptimistic,onQueryUpdated:e.onQueryUpdated||null}).forEach(function(e){return c.push(e)}),e.awaitRefetchQueries||e.onQueryUpdated)return Promise.all(c).then(function(){return r})}return Promise.resolve(r)},e.prototype.markMutationOptimistic=function(e,t){var n=this,r="function"==typeof e?e(t.variables):e;return this.cache.recordOptimisticTransaction(function(e){try{n.markMutationResult((0,en.pi)((0,en.pi)({},t),{result:{data:r}}),e)}catch(i){__DEV__&&Q.kG.error(i)}},t.mutationId)},e.prototype.fetchQuery=function(e,t,n){return this.fetchQueryObservable(e,t,n).promise},e.prototype.getQueryStore=function(){var e=Object.create(null);return this.queries.forEach(function(t,n){e[n]={variables:t.variables,networkStatus:t.networkStatus,networkError:t.networkError,graphQLErrors:t.graphQLErrors}}),e},e.prototype.resetErrors=function(e){var t=this.queries.get(e);t&&(t.networkError=void 0,t.graphQLErrors=[])},e.prototype.transform=function(e){var t=this.transformCache;if(!t.has(e)){var n=this.cache.transformDocument(e),r=nY(n),i=this.localState.clientQuery(n),a=r&&this.localState.serverQuery(r),o={document:n,hasClientExports:tm(n),hasForcedResolvers:this.localState.shouldForceResolvers(n),clientQuery:i,serverQuery:a,defaultVars:e9(e2(n)),asQuery:(0,en.pi)((0,en.pi)({},n),{definitions:n.definitions.map(function(e){return"OperationDefinition"===e.kind&&"query"!==e.operation?(0,en.pi)((0,en.pi)({},e),{operation:"query"}):e})})},s=function(e){e&&!t.has(e)&&t.set(e,o)};s(e),s(n),s(i),s(a)}return t.get(e)},e.prototype.getVariables=function(e,t){return(0,en.pi)((0,en.pi)({},this.transform(e).defaultVars),t)},e.prototype.watchQuery=function(e){void 0===(e=(0,en.pi)((0,en.pi)({},e),{variables:this.getVariables(e.query,e.variables)})).notifyOnNetworkStatusChange&&(e.notifyOnNetworkStatusChange=!1);var t=new r9(this),n=new n3({queryManager:this,queryInfo:t,options:e});return this.queries.set(n.queryId,t),t.init({document:n.query,observableQuery:n,variables:n.variables}),n},e.prototype.query=function(e,t){var n=this;return void 0===t&&(t=this.generateQueryId()),__DEV__?(0,Q.kG)(e.query,"query option is required. You must specify your GraphQL document in the query option."):(0,Q.kG)(e.query,17),__DEV__?(0,Q.kG)("Document"===e.query.kind,'You must wrap the query string in a "gql" tag.'):(0,Q.kG)("Document"===e.query.kind,18),__DEV__?(0,Q.kG)(!e.returnPartialData,"returnPartialData option only supported on watchQuery."):(0,Q.kG)(!e.returnPartialData,19),__DEV__?(0,Q.kG)(!e.pollInterval,"pollInterval option only supported on watchQuery."):(0,Q.kG)(!e.pollInterval,20),this.fetchQuery(t,e).finally(function(){return n.stopQuery(t)})},e.prototype.generateQueryId=function(){return String(this.queryIdCounter++)},e.prototype.generateRequestId=function(){return this.requestIdCounter++},e.prototype.generateMutationId=function(){return String(this.mutationIdCounter++)},e.prototype.stopQueryInStore=function(e){this.stopQueryInStoreNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryInStoreNoBroadcast=function(e){var t=this.queries.get(e);t&&t.stop()},e.prototype.clearStore=function(e){return void 0===e&&(e={discardWatches:!0}),this.cancelPendingFetches(__DEV__?new Q.ej("Store reset while query was in flight (not completed in link chain)"):new Q.ej(21)),this.queries.forEach(function(e){e.observableQuery?e.networkStatus=nZ.I.loading:e.stop()}),this.mutationStore&&(this.mutationStore=Object.create(null)),this.cache.reset(e)},e.prototype.getObservableQueries=function(e){var t=this;void 0===e&&(e="active");var n=new Map,r=new Map,i=new Set;return Array.isArray(e)&&e.forEach(function(e){"string"==typeof e?r.set(e,!1):eN(e)?r.set(t.transform(e).document,!1):(0,eO.s)(e)&&e.query&&i.add(e)}),this.queries.forEach(function(t,i){var a=t.observableQuery,o=t.document;if(a){if("all"===e){n.set(i,a);return}var s=a.queryName;if("standby"===a.options.fetchPolicy||"active"===e&&!a.hasObservers())return;("active"===e||s&&r.has(s)||o&&r.has(o))&&(n.set(i,a),s&&r.set(s,!0),o&&r.set(o,!0))}}),i.size&&i.forEach(function(e){var r=nG("legacyOneTimeQuery"),i=t.getQuery(r).init({document:e.query,variables:e.variables}),a=new n3({queryManager:t,queryInfo:i,options:(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"network-only"})});(0,Q.kG)(a.queryId===r),i.setObservableQuery(a),n.set(r,a)}),__DEV__&&r.size&&r.forEach(function(e,t){!e&&__DEV__&&Q.kG.warn("Unknown query ".concat("string"==typeof t?"named ":"").concat(JSON.stringify(t,null,2)," requested in refetchQueries options.include array"))}),n},e.prototype.reFetchObservableQueries=function(e){var t=this;void 0===e&&(e=!1);var n=[];return this.getObservableQueries(e?"all":"active").forEach(function(r,i){var a=r.options.fetchPolicy;r.resetLastResults(),(e||"standby"!==a&&"cache-only"!==a)&&n.push(r.refetch()),t.getQuery(i).setDiff(null)}),this.broadcastQueries(),Promise.all(n)},e.prototype.setObservableQuery=function(e){this.getQuery(e.queryId).setObservableQuery(e)},e.prototype.startGraphQLSubscription=function(e){var t=this,n=e.query,r=e.fetchPolicy,i=e.errorPolicy,a=e.variables,o=e.context,s=void 0===o?{}:o;n=this.transform(n).document,a=this.getVariables(n,a);var u=function(e){return t.getObservableFromLink(n,s,e).map(function(a){"no-cache"!==r&&(r7(a,i)&&t.cache.write({query:n,result:a.data,dataId:"ROOT_SUBSCRIPTION",variables:e}),t.broadcastQueries());var o=nO(a),s=(0,tN.ls)(a);if(o||s){var u={};throw o&&(u.graphQLErrors=a.errors),s&&(u.protocolErrors=a.extensions[tN.YG]),new tN.cA(u)}return a})};if(this.transform(n).hasClientExports){var c=this.localState.addExportedVariables(n,a,s).then(u);return new eT(function(e){var t=null;return c.then(function(n){return t=n.subscribe(e)},e.error),function(){return t&&t.unsubscribe()}})}return u(a)},e.prototype.stopQuery=function(e){this.stopQueryNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryNoBroadcast=function(e){this.stopQueryInStoreNoBroadcast(e),this.removeQuery(e)},e.prototype.removeQuery=function(e){this.fetchCancelFns.delete(e),this.queries.has(e)&&(this.getQuery(e).stop(),this.queries.delete(e))},e.prototype.broadcastQueries=function(){this.onBroadcast&&this.onBroadcast(),this.queries.forEach(function(e){return e.notify()})},e.prototype.getLocalState=function(){return this.localState},e.prototype.getObservableFromLink=function(e,t,n,r){var i,a,o=this;void 0===r&&(r=null!==(i=null==t?void 0:t.queryDeduplication)&&void 0!==i?i:this.queryDeduplication);var s=this.transform(e).serverQuery;if(s){var u=this,c=u.inFlightLinkObservables,l=u.link,f={query:s,variables:n,operationName:e3(s)||void 0,context:this.prepareContext((0,en.pi)((0,en.pi)({},t),{forceFetch:!r}))};if(t=f.context,r){var d=c.get(s)||new Map;c.set(s,d);var h=nx(n);if(!(a=d.get(h))){var p=new nq([np(l,f)]);d.set(h,a=p),p.beforeNext(function(){d.delete(h)&&d.size<1&&c.delete(s)})}}else a=new nq([np(l,f)])}else a=new nq([eT.of({data:{}})]),t=this.prepareContext(t);var b=this.transform(e).clientQuery;return b&&(a=nM(a,function(e){return o.localState.runResolvers({document:b,remoteResult:e,context:t,variables:n})})),a},e.prototype.getResultsFromLink=function(e,t,n){var r=e.lastRequestId=this.generateRequestId(),i=this.cache.transformForLink(this.transform(e.document).document);return nM(this.getObservableFromLink(i,n.context,n.variables),function(a){var o=nA(a),s=o.length>0;if(r>=e.lastRequestId){if(s&&"none"===n.errorPolicy)throw e.markError(new tN.cA({graphQLErrors:o}));e.markResult(a,i,n,t),e.markReady()}var u={data:a.data,loading:!1,networkStatus:nZ.I.ready};return s&&"ignore"!==n.errorPolicy&&(u.errors=o,u.networkStatus=nZ.I.error),u},function(t){var n=(0,tN.MS)(t)?t:new tN.cA({networkError:t});throw r>=e.lastRequestId&&e.markError(n),n})},e.prototype.fetchQueryObservable=function(e,t,n){return this.fetchConcastWithInfo(e,t,n).concast},e.prototype.fetchConcastWithInfo=function(e,t,n){var r,i,a=this;void 0===n&&(n=nZ.I.loading);var o=this.transform(t.query).document,s=this.getVariables(o,t.variables),u=this.getQuery(e),c=this.defaultOptions.watchQuery,l=t.fetchPolicy,f=void 0===l?c&&c.fetchPolicy||"cache-first":l,d=t.errorPolicy,h=void 0===d?c&&c.errorPolicy||"none":d,p=t.returnPartialData,b=void 0!==p&&p,m=t.notifyOnNetworkStatusChange,g=void 0!==m&&m,v=t.context,y=void 0===v?{}:v,w=Object.assign({},t,{query:o,variables:s,fetchPolicy:f,errorPolicy:h,returnPartialData:b,notifyOnNetworkStatusChange:g,context:y}),_=function(e){w.variables=e;var r=a.fetchQueryByPolicy(u,w,n);return"standby"!==w.fetchPolicy&&r.sources.length>0&&u.observableQuery&&u.observableQuery.applyNextFetchPolicy("after-fetch",t),r},E=function(){return a.fetchCancelFns.delete(e)};if(this.fetchCancelFns.set(e,function(e){E(),setTimeout(function(){return r.cancel(e)})}),this.transform(w.query).hasClientExports)r=new nq(this.localState.addExportedVariables(w.query,w.variables,w.context).then(_).then(function(e){return e.sources})),i=!0;else{var S=_(w.variables);i=S.fromLink,r=new nq(S.sources)}return r.promise.then(E,E),{concast:r,fromLink:i}},e.prototype.refetchQueries=function(e){var t=this,n=e.updateCache,r=e.include,i=e.optimistic,a=void 0!==i&&i,o=e.removeOptimistic,s=void 0===o?a?nG("refetchQueries"):void 0:o,u=e.onQueryUpdated,c=new Map;r&&this.getObservableQueries(r).forEach(function(e,n){c.set(n,{oq:e,lastDiff:t.getQuery(n).getDiff()})});var l=new Map;return n&&this.cache.batch({update:n,optimistic:a&&s||!1,removeOptimistic:s,onWatchUpdated:function(e,t,n){var r=e.watcher instanceof r9&&e.watcher.observableQuery;if(r){if(u){c.delete(r.queryId);var i=u(r,t,n);return!0===i&&(i=r.refetch()),!1!==i&&l.set(r,i),i}null!==u&&c.set(r.queryId,{oq:r,lastDiff:n,diff:t})}}}),c.size&&c.forEach(function(e,n){var r,i=e.oq,a=e.lastDiff,o=e.diff;if(u){if(!o){var s=i.queryInfo;s.reset(),o=s.getDiff()}r=u(i,o,a)}u&&!0!==r||(r=i.refetch()),!1!==r&&l.set(i,r),n.indexOf("legacyOneTimeQuery")>=0&&t.stopQueryNoBroadcast(n)}),s&&this.cache.removeOptimistic(s),l},e.prototype.fetchQueryByPolicy=function(e,t,n){var r=this,i=t.query,a=t.variables,o=t.fetchPolicy,s=t.refetchWritePolicy,u=t.errorPolicy,c=t.returnPartialData,l=t.context,f=t.notifyOnNetworkStatusChange,d=e.networkStatus;e.init({document:this.transform(i).document,variables:a,networkStatus:n});var h=function(){return e.getDiff(a)},p=function(t,n){void 0===n&&(n=e.networkStatus||nZ.I.loading);var o=t.result;!__DEV__||c||(0,nm.D)(o,{})||n5(t.missing);var s=function(e){return eT.of((0,en.pi)({data:e,loading:(0,nZ.O)(n),networkStatus:n},t.complete?null:{partial:!0}))};return o&&r.transform(i).hasForcedResolvers?r.localState.runResolvers({document:i,remoteResult:{data:o},context:l,variables:a,onlyRunForcedResolvers:!0}).then(function(e){return s(e.data||void 0)}):"none"===u&&n===nZ.I.refetch&&Array.isArray(t.missing)?s(void 0):s(o)},b="no-cache"===o?0:n===nZ.I.refetch&&"merge"!==s?1:2,m=function(){return r.getResultsFromLink(e,b,{variables:a,context:l,fetchPolicy:o,errorPolicy:u})},g=f&&"number"==typeof d&&d!==n&&(0,nZ.O)(n);switch(o){default:case"cache-first":var v=h();if(v.complete)return{fromLink:!1,sources:[p(v,e.markReady())]};if(c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-and-network":var v=h();if(v.complete||c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-only":return{fromLink:!1,sources:[p(h(),e.markReady())]};case"network-only":if(g)return{fromLink:!0,sources:[p(h()),m()]};return{fromLink:!0,sources:[m()]};case"no-cache":if(g)return{fromLink:!0,sources:[p(e.getDiff()),m(),]};return{fromLink:!0,sources:[m()]};case"standby":return{fromLink:!1,sources:[]}}},e.prototype.getQuery=function(e){return e&&!this.queries.has(e)&&this.queries.set(e,new r9(this,e)),this.queries.get(e)},e.prototype.prepareContext=function(e){void 0===e&&(e={});var t=this.localState.prepareContext(e);return(0,en.pi)((0,en.pi)({},t),{clientAwareness:this.clientAwareness})},e}(),ir=__webpack_require__(14012),ii=!1,ia=function(){function e(e){var t=this;this.resetStoreCallbacks=[],this.clearStoreCallbacks=[];var n=e.uri,r=e.credentials,i=e.headers,a=e.cache,o=e.ssrMode,s=void 0!==o&&o,u=e.ssrForceFetchDelay,c=void 0===u?0:u,l=e.connectToDevTools,f=void 0===l?"object"==typeof window&&!window.__APOLLO_CLIENT__&&__DEV__:l,d=e.queryDeduplication,h=void 0===d||d,p=e.defaultOptions,b=e.assumeImmutableResults,m=void 0!==b&&b,g=e.resolvers,v=e.typeDefs,y=e.fragmentMatcher,w=e.name,_=e.version,E=e.link;if(E||(E=n?new nh({uri:n,credentials:r,headers:i}):ta.empty()),!a)throw __DEV__?new Q.ej("To initialize Apollo Client, you must specify a 'cache' property in the options object. \nFor more information, please visit: https://go.apollo.dev/c/docs"):new Q.ej(9);if(this.link=E,this.cache=a,this.disableNetworkFetches=s||c>0,this.queryDeduplication=h,this.defaultOptions=p||Object.create(null),this.typeDefs=v,c&&setTimeout(function(){return t.disableNetworkFetches=!1},c),this.watchQuery=this.watchQuery.bind(this),this.query=this.query.bind(this),this.mutate=this.mutate.bind(this),this.resetStore=this.resetStore.bind(this),this.reFetchObservableQueries=this.reFetchObservableQueries.bind(this),f&&"object"==typeof window&&(window.__APOLLO_CLIENT__=this),!ii&&f&&__DEV__&&(ii=!0,"undefined"!=typeof window&&window.document&&window.top===window.self&&!window.__APOLLO_DEVTOOLS_GLOBAL_HOOK__)){var S=window.navigator,k=S&&S.userAgent,x=void 0;"string"==typeof k&&(k.indexOf("Chrome/")>-1?x="https://chrome.google.com/webstore/detail/apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm":k.indexOf("Firefox/")>-1&&(x="https://addons.mozilla.org/en-US/firefox/addon/apollo-developer-tools/")),x&&__DEV__&&Q.kG.log("Download the Apollo DevTools for a better development experience: "+x)}this.version=nb,this.localState=new r4({cache:a,client:this,resolvers:g,fragmentMatcher:y}),this.queryManager=new it({cache:this.cache,link:this.link,defaultOptions:this.defaultOptions,queryDeduplication:h,ssrMode:s,clientAwareness:{name:w,version:_},localState:this.localState,assumeImmutableResults:m,onBroadcast:f?function(){t.devToolsHookCb&&t.devToolsHookCb({action:{},state:{queries:t.queryManager.getQueryStore(),mutations:t.queryManager.mutationStore||{}},dataWithOptimisticResults:t.cache.extract(!0)})}:void 0})}return e.prototype.stop=function(){this.queryManager.stop()},e.prototype.watchQuery=function(e){return this.defaultOptions.watchQuery&&(e=(0,ir.J)(this.defaultOptions.watchQuery,e)),this.disableNetworkFetches&&("network-only"===e.fetchPolicy||"cache-and-network"===e.fetchPolicy)&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.watchQuery(e)},e.prototype.query=function(e){return this.defaultOptions.query&&(e=(0,ir.J)(this.defaultOptions.query,e)),__DEV__?(0,Q.kG)("cache-and-network"!==e.fetchPolicy,"The cache-and-network fetchPolicy does not work with client.query, because client.query can only return a single result. Please use client.watchQuery to receive multiple results from the cache and the network, or consider using a different fetchPolicy, such as cache-first or network-only."):(0,Q.kG)("cache-and-network"!==e.fetchPolicy,10),this.disableNetworkFetches&&"network-only"===e.fetchPolicy&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.query(e)},e.prototype.mutate=function(e){return this.defaultOptions.mutate&&(e=(0,ir.J)(this.defaultOptions.mutate,e)),this.queryManager.mutate(e)},e.prototype.subscribe=function(e){return this.queryManager.startGraphQLSubscription(e)},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!1),this.cache.readQuery(e,t)},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!1),this.cache.readFragment(e,t)},e.prototype.writeQuery=function(e){var t=this.cache.writeQuery(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.writeFragment=function(e){var t=this.cache.writeFragment(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.__actionHookForDevTools=function(e){this.devToolsHookCb=e},e.prototype.__requestRaw=function(e){return np(this.link,e)},e.prototype.resetStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!1})}).then(function(){return Promise.all(e.resetStoreCallbacks.map(function(e){return e()}))}).then(function(){return e.reFetchObservableQueries()})},e.prototype.clearStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!0})}).then(function(){return Promise.all(e.clearStoreCallbacks.map(function(e){return e()}))})},e.prototype.onResetStore=function(e){var t=this;return this.resetStoreCallbacks.push(e),function(){t.resetStoreCallbacks=t.resetStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.onClearStore=function(e){var t=this;return this.clearStoreCallbacks.push(e),function(){t.clearStoreCallbacks=t.clearStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.reFetchObservableQueries=function(e){return this.queryManager.reFetchObservableQueries(e)},e.prototype.refetchQueries=function(e){var t=this.queryManager.refetchQueries(e),n=[],r=[];t.forEach(function(e,t){n.push(t),r.push(e)});var i=Promise.all(r);return i.queries=n,i.results=r,i.catch(function(e){__DEV__&&Q.kG.debug("In client.refetchQueries, Promise.all promise rejected with error ".concat(e))}),i},e.prototype.getObservableQueries=function(e){return void 0===e&&(e="active"),this.queryManager.getObservableQueries(e)},e.prototype.extract=function(e){return this.cache.extract(e)},e.prototype.restore=function(e){return this.cache.restore(e)},e.prototype.addResolvers=function(e){this.localState.addResolvers(e)},e.prototype.setResolvers=function(e){this.localState.setResolvers(e)},e.prototype.getResolvers=function(){return this.localState.getResolvers()},e.prototype.setLocalStateFragmentMatcher=function(e){this.localState.setFragmentMatcher(e)},e.prototype.setLink=function(e){this.link=this.queryManager.link=e},e}(),io=function(){function e(){this.getFragmentDoc=rZ(eA)}return e.prototype.batch=function(e){var t,n=this,r="string"==typeof e.optimistic?e.optimistic:!1===e.optimistic?null:void 0;return this.performTransaction(function(){return t=e.update(n)},r),t},e.prototype.recordOptimisticTransaction=function(e,t){this.performTransaction(e,t)},e.prototype.transformDocument=function(e){return e},e.prototype.transformForLink=function(e){return e},e.prototype.identify=function(e){},e.prototype.gc=function(){return[]},e.prototype.modify=function(e){return!1},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{rootId:e.id||"ROOT_QUERY",optimistic:t}))},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{query:this.getFragmentDoc(e.fragment,e.fragmentName),rootId:e.id,optimistic:t}))},e.prototype.writeQuery=function(e){var t=e.id,n=e.data,r=(0,en._T)(e,["id","data"]);return this.write(Object.assign(r,{dataId:t||"ROOT_QUERY",result:n}))},e.prototype.writeFragment=function(e){var t=e.id,n=e.data,r=e.fragment,i=e.fragmentName,a=(0,en._T)(e,["id","data","fragment","fragmentName"]);return this.write(Object.assign(a,{query:this.getFragmentDoc(r,i),dataId:t,result:n}))},e.prototype.updateQuery=function(e,t){return this.batch({update:function(n){var r=n.readQuery(e),i=t(r);return null==i?r:(n.writeQuery((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e.prototype.updateFragment=function(e,t){return this.batch({update:function(n){var r=n.readFragment(e),i=t(r);return null==i?r:(n.writeFragment((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e}(),is=function(e){function t(n,r,i,a){var o,s=e.call(this,n)||this;if(s.message=n,s.path=r,s.query=i,s.variables=a,Array.isArray(s.path)){s.missing=s.message;for(var u=s.path.length-1;u>=0;--u)s.missing=((o={})[s.path[u]]=s.missing,o)}else s.missing=s.path;return s.__proto__=t.prototype,s}return(0,en.ZT)(t,e),t}(Error),iu=__webpack_require__(10542),ic=Object.prototype.hasOwnProperty;function il(e){return null==e}function id(e,t){var n=e.__typename,r=e.id,i=e._id;if("string"==typeof n&&(t&&(t.keyObject=il(r)?il(i)?void 0:{_id:i}:{id:r}),il(r)&&!il(i)&&(r=i),!il(r)))return"".concat(n,":").concat("number"==typeof r||"string"==typeof r?r:JSON.stringify(r))}var ih={dataIdFromObject:id,addTypename:!0,resultCaching:!0,canonizeResults:!1};function ip(e){return(0,n1.o)(ih,e)}function ib(e){var t=e.canonizeResults;return void 0===t?ih.canonizeResults:t}function im(e,t){return eD(t)?e.get(t.__ref,"__typename"):t&&t.__typename}var ig=/^[_a-z][_0-9a-z]*/i;function iv(e){var t=e.match(ig);return t?t[0]:e}function iy(e,t,n){return!!(0,eO.s)(t)&&((0,tP.k)(t)?t.every(function(t){return iy(e,t,n)}):e.selections.every(function(e){if(eQ(e)&&td(e,n)){var r=eX(e);return ic.call(t,r)&&(!e.selectionSet||iy(e.selectionSet,t[r],n))}return!0}))}function iw(e){return(0,eO.s)(e)&&!eD(e)&&!(0,tP.k)(e)}function i_(){return new tB}function iE(e,t){var n=eL(e4(e));return{fragmentMap:n,lookupFragment:function(e){var r=n[e];return!r&&t&&(r=t.lookup(e)),r||null}}}var iS=Object.create(null),ik=function(){return iS},ix=Object.create(null),iT=function(){function e(e,t){var n=this;this.policies=e,this.group=t,this.data=Object.create(null),this.rootIds=Object.create(null),this.refs=Object.create(null),this.getFieldValue=function(e,t){return(0,iu.J)(eD(e)?n.get(e.__ref,t):e&&e[t])},this.canRead=function(e){return eD(e)?n.has(e.__ref):"object"==typeof e},this.toReference=function(e,t){if("string"==typeof e)return eI(e);if(eD(e))return e;var r=n.policies.identify(e)[0];if(r){var i=eI(r);return t&&n.merge(r,e),i}}}return e.prototype.toObject=function(){return(0,en.pi)({},this.data)},e.prototype.has=function(e){return void 0!==this.lookup(e,!0)},e.prototype.get=function(e,t){if(this.group.depend(e,t),ic.call(this.data,e)){var n=this.data[e];if(n&&ic.call(n,t))return n[t]}return"__typename"===t&&ic.call(this.policies.rootTypenamesById,e)?this.policies.rootTypenamesById[e]:this instanceof iL?this.parent.get(e,t):void 0},e.prototype.lookup=function(e,t){return(t&&this.group.depend(e,"__exists"),ic.call(this.data,e))?this.data[e]:this instanceof iL?this.parent.lookup(e,t):this.policies.rootTypenamesById[e]?Object.create(null):void 0},e.prototype.merge=function(e,t){var n,r=this;eD(e)&&(e=e.__ref),eD(t)&&(t=t.__ref);var i="string"==typeof e?this.lookup(n=e):e,a="string"==typeof t?this.lookup(n=t):t;if(a){__DEV__?(0,Q.kG)("string"==typeof n,"store.merge expects a string ID"):(0,Q.kG)("string"==typeof n,1);var o=new tB(iI).merge(i,a);if(this.data[n]=o,o!==i&&(delete this.refs[n],this.group.caching)){var s=Object.create(null);i||(s.__exists=1),Object.keys(a).forEach(function(e){if(!i||i[e]!==o[e]){s[e]=1;var t=iv(e);t===e||r.policies.hasKeyArgs(o.__typename,t)||(s[t]=1),void 0!==o[e]||r instanceof iL||delete o[e]}}),s.__typename&&!(i&&i.__typename)&&this.policies.rootTypenamesById[n]===o.__typename&&delete s.__typename,Object.keys(s).forEach(function(e){return r.group.dirty(n,e)})}}},e.prototype.modify=function(e,t){var n=this,r=this.lookup(e);if(r){var i=Object.create(null),a=!1,o=!0,s={DELETE:iS,INVALIDATE:ix,isReference:eD,toReference:this.toReference,canRead:this.canRead,readField:function(t,r){return n.policies.readField("string"==typeof t?{fieldName:t,from:r||eI(e)}:t,{store:n})}};if(Object.keys(r).forEach(function(u){var c=iv(u),l=r[u];if(void 0!==l){var f="function"==typeof t?t:t[u]||t[c];if(f){var d=f===ik?iS:f((0,iu.J)(l),(0,en.pi)((0,en.pi)({},s),{fieldName:c,storeFieldName:u,storage:n.getStorage(e,u)}));d===ix?n.group.dirty(e,u):(d===iS&&(d=void 0),d!==l&&(i[u]=d,a=!0,l=d))}void 0!==l&&(o=!1)}}),a)return this.merge(e,i),o&&(this instanceof iL?this.data[e]=void 0:delete this.data[e],this.group.dirty(e,"__exists")),!0}return!1},e.prototype.delete=function(e,t,n){var r,i=this.lookup(e);if(i){var a=this.getFieldValue(i,"__typename"),o=t&&n?this.policies.getStoreFieldName({typename:a,fieldName:t,args:n}):t;return this.modify(e,o?((r={})[o]=ik,r):ik)}return!1},e.prototype.evict=function(e,t){var n=!1;return e.id&&(ic.call(this.data,e.id)&&(n=this.delete(e.id,e.fieldName,e.args)),this instanceof iL&&this!==t&&(n=this.parent.evict(e,t)||n),(e.fieldName||n)&&this.group.dirty(e.id,e.fieldName||"__exists")),n},e.prototype.clear=function(){this.replace(null)},e.prototype.extract=function(){var e=this,t=this.toObject(),n=[];return this.getRootIdSet().forEach(function(t){ic.call(e.policies.rootTypenamesById,t)||n.push(t)}),n.length&&(t.__META={extraRootIds:n.sort()}),t},e.prototype.replace=function(e){var t=this;if(Object.keys(this.data).forEach(function(n){e&&ic.call(e,n)||t.delete(n)}),e){var n=e.__META,r=(0,en._T)(e,["__META"]);Object.keys(r).forEach(function(e){t.merge(e,r[e])}),n&&n.extraRootIds.forEach(this.retain,this)}},e.prototype.retain=function(e){return this.rootIds[e]=(this.rootIds[e]||0)+1},e.prototype.release=function(e){if(this.rootIds[e]>0){var t=--this.rootIds[e];return t||delete this.rootIds[e],t}return 0},e.prototype.getRootIdSet=function(e){return void 0===e&&(e=new Set),Object.keys(this.rootIds).forEach(e.add,e),this instanceof iL?this.parent.getRootIdSet(e):Object.keys(this.policies.rootTypenamesById).forEach(e.add,e),e},e.prototype.gc=function(){var e=this,t=this.getRootIdSet(),n=this.toObject();t.forEach(function(r){ic.call(n,r)&&(Object.keys(e.findChildRefIds(r)).forEach(t.add,t),delete n[r])});var r=Object.keys(n);if(r.length){for(var i=this;i instanceof iL;)i=i.parent;r.forEach(function(e){return i.delete(e)})}return r},e.prototype.findChildRefIds=function(e){if(!ic.call(this.refs,e)){var t=this.refs[e]=Object.create(null),n=this.data[e];if(!n)return t;var r=new Set([n]);r.forEach(function(e){eD(e)&&(t[e.__ref]=!0),(0,eO.s)(e)&&Object.keys(e).forEach(function(t){var n=e[t];(0,eO.s)(n)&&r.add(n)})})}return this.refs[e]},e.prototype.makeCacheKey=function(){return this.group.keyMaker.lookupArray(arguments)},e}(),iM=function(){function e(e,t){void 0===t&&(t=null),this.caching=e,this.parent=t,this.d=null,this.resetCaching()}return e.prototype.resetCaching=function(){this.d=this.caching?rW():null,this.keyMaker=new n_(t_.mr)},e.prototype.depend=function(e,t){if(this.d){this.d(iO(e,t));var n=iv(t);n!==t&&this.d(iO(e,n)),this.parent&&this.parent.depend(e,t)}},e.prototype.dirty=function(e,t){this.d&&this.d.dirty(iO(e,t),"__exists"===t?"forget":"setDirty")},e}();function iO(e,t){return t+"#"+e}function iA(e,t){iD(e)&&e.group.depend(t,"__exists")}!function(e){var t=function(e){function t(t){var n=t.policies,r=t.resultCaching,i=void 0===r||r,a=t.seed,o=e.call(this,n,new iM(i))||this;return o.stump=new iC(o),o.storageTrie=new n_(t_.mr),a&&o.replace(a),o}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,t){return this.stump.addLayer(e,t)},t.prototype.removeLayer=function(){return this},t.prototype.getStorage=function(){return this.storageTrie.lookupArray(arguments)},t}(e);e.Root=t}(iT||(iT={}));var iL=function(e){function t(t,n,r,i){var a=e.call(this,n.policies,i)||this;return a.id=t,a.parent=n,a.replay=r,a.group=i,r(a),a}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,n){return new t(e,this,n,this.group)},t.prototype.removeLayer=function(e){var t=this,n=this.parent.removeLayer(e);return e===this.id?(this.group.caching&&Object.keys(this.data).forEach(function(e){var r=t.data[e],i=n.lookup(e);i?r?r!==i&&Object.keys(r).forEach(function(n){(0,nm.D)(r[n],i[n])||t.group.dirty(e,n)}):(t.group.dirty(e,"__exists"),Object.keys(i).forEach(function(n){t.group.dirty(e,n)})):t.delete(e)}),n):n===this.parent?this:n.addLayer(this.id,this.replay)},t.prototype.toObject=function(){return(0,en.pi)((0,en.pi)({},this.parent.toObject()),this.data)},t.prototype.findChildRefIds=function(t){var n=this.parent.findChildRefIds(t);return ic.call(this.data,t)?(0,en.pi)((0,en.pi)({},n),e.prototype.findChildRefIds.call(this,t)):n},t.prototype.getStorage=function(){for(var e=this.parent;e.parent;)e=e.parent;return e.getStorage.apply(e,arguments)},t}(iT),iC=function(e){function t(t){return e.call(this,"EntityStore.Stump",t,function(){},new iM(t.group.caching,t.group))||this}return(0,en.ZT)(t,e),t.prototype.removeLayer=function(){return this},t.prototype.merge=function(){return this.parent.merge.apply(this.parent,arguments)},t}(iL);function iI(e,t,n){var r=e[n],i=t[n];return(0,nm.D)(r,i)?r:i}function iD(e){return!!(e instanceof iT&&e.group.caching)}function iN(e){return[e.selectionSet,e.objectOrReference,e.context,e.context.canonizeResults,]}var iP=function(){function e(e){var t=this;this.knownResults=new(t_.mr?WeakMap:Map),this.config=(0,n1.o)(e,{addTypename:!1!==e.addTypename,canonizeResults:ib(e)}),this.canon=e.canon||new nk,this.executeSelectionSet=rZ(function(e){var n,r=e.context.canonizeResults,i=iN(e);i[3]=!r;var a=(n=t.executeSelectionSet).peek.apply(n,i);return a?r?(0,en.pi)((0,en.pi)({},a),{result:t.canon.admit(a.result)}):a:(iA(e.context.store,e.enclosingRef.__ref),t.execSelectionSetImpl(e))},{max:this.config.resultCacheMaxSize,keyArgs:iN,makeCacheKey:function(e,t,n,r){if(iD(n.store))return n.store.makeCacheKey(e,eD(t)?t.__ref:t,n.varString,r)}}),this.executeSubSelectedArray=rZ(function(e){return iA(e.context.store,e.enclosingRef.__ref),t.execSubSelectedArrayImpl(e)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var t=e.field,n=e.array,r=e.context;if(iD(r.store))return r.store.makeCacheKey(t,n,r.varString)}})}return e.prototype.resetCanon=function(){this.canon=new nk},e.prototype.diffQueryAgainstStore=function(e){var t,n=e.store,r=e.query,i=e.rootId,a=void 0===i?"ROOT_QUERY":i,o=e.variables,s=e.returnPartialData,u=void 0===s||s,c=e.canonizeResults,l=void 0===c?this.config.canonizeResults:c,f=this.config.cache.policies;o=(0,en.pi)((0,en.pi)({},e9(e6(r))),o);var d=eI(a),h=this.executeSelectionSet({selectionSet:e8(r).selectionSet,objectOrReference:d,enclosingRef:d,context:(0,en.pi)({store:n,query:r,policies:f,variables:o,varString:nx(o),canonizeResults:l},iE(r,this.config.fragments))});if(h.missing&&(t=[new is(iR(h.missing),h.missing,r,o)],!u))throw t[0];return{result:h.result,complete:!t,missing:t}},e.prototype.isFresh=function(e,t,n,r){if(iD(r.store)&&this.knownResults.get(e)===n){var i=this.executeSelectionSet.peek(n,t,r,this.canon.isKnown(e));if(i&&e===i.result)return!0}return!1},e.prototype.execSelectionSetImpl=function(e){var t,n=this,r=e.selectionSet,i=e.objectOrReference,a=e.enclosingRef,o=e.context;if(eD(i)&&!o.policies.rootTypenamesById[i.__ref]&&!o.store.has(i.__ref))return{result:this.canon.empty,missing:"Dangling reference to missing ".concat(i.__ref," object")};var s=o.variables,u=o.policies,c=o.store.getFieldValue(i,"__typename"),l=[],f=new tB;function d(e,n){var r;return e.missing&&(t=f.merge(t,((r={})[n]=e.missing,r))),e.result}this.config.addTypename&&"string"==typeof c&&!u.rootIdsByTypename[c]&&l.push({__typename:c});var h=new Set(r.selections);h.forEach(function(e){var r,p;if(td(e,s)){if(eQ(e)){var b=u.readField({fieldName:e.name.value,field:e,variables:o.variables,from:i},o),m=eX(e);void 0===b?nj.added(e)||(t=f.merge(t,((r={})[m]="Can't find field '".concat(e.name.value,"' on ").concat(eD(i)?i.__ref+" object":"object "+JSON.stringify(i,null,2)),r))):(0,tP.k)(b)?b=d(n.executeSubSelectedArray({field:e,array:b,enclosingRef:a,context:o}),m):e.selectionSet?null!=b&&(b=d(n.executeSelectionSet({selectionSet:e.selectionSet,objectOrReference:b,enclosingRef:eD(b)?b:a,context:o}),m)):o.canonizeResults&&(b=n.canon.pass(b)),void 0!==b&&l.push(((p={})[m]=b,p))}else{var g=eC(e,o.lookupFragment);if(!g&&e.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(e.name.value)):new Q.ej(5);g&&u.fragmentMatches(g,c)&&g.selectionSet.selections.forEach(h.add,h)}}});var p={result:tF(l),missing:t},b=o.canonizeResults?this.canon.admit(p):(0,iu.J)(p);return b.result&&this.knownResults.set(b.result,r),b},e.prototype.execSubSelectedArrayImpl=function(e){var t,n=this,r=e.field,i=e.array,a=e.enclosingRef,o=e.context,s=new tB;function u(e,n){var r;return e.missing&&(t=s.merge(t,((r={})[n]=e.missing,r))),e.result}return r.selectionSet&&(i=i.filter(o.store.canRead)),i=i.map(function(e,t){return null===e?null:(0,tP.k)(e)?u(n.executeSubSelectedArray({field:r,array:e,enclosingRef:a,context:o}),t):r.selectionSet?u(n.executeSelectionSet({selectionSet:r.selectionSet,objectOrReference:e,enclosingRef:eD(e)?e:a,context:o}),t):(__DEV__&&ij(o.store,r,e),e)}),{result:o.canonizeResults?this.canon.admit(i):i,missing:t}},e}();function iR(e){try{JSON.stringify(e,function(e,t){if("string"==typeof t)throw t;return t})}catch(t){return t}}function ij(e,t,n){if(!t.selectionSet){var r=new Set([n]);r.forEach(function(n){(0,eO.s)(n)&&(__DEV__?(0,Q.kG)(!eD(n),"Missing selection set for object of type ".concat(im(e,n)," returned for query field ").concat(t.name.value)):(0,Q.kG)(!eD(n),6),Object.values(n).forEach(r.add,r))})}}function iF(e){var t=nG("stringifyForDisplay");return JSON.stringify(e,function(e,n){return void 0===n?t:n}).split(JSON.stringify(t)).join("")}var iY=Object.create(null);function iB(e){var t=JSON.stringify(e);return iY[t]||(iY[t]=Object.create(null))}function iU(e){var t=iB(e);return t.keyFieldsFn||(t.keyFieldsFn=function(t,n){var r=function(e,t){return n.readField(t,e)},i=n.keyObject=i$(e,function(e){var i=iW(n.storeObject,e,r);return void 0===i&&t!==n.storeObject&&ic.call(t,e[0])&&(i=iW(t,e,iG)),__DEV__?(0,Q.kG)(void 0!==i,"Missing field '".concat(e.join("."),"' while extracting keyFields from ").concat(JSON.stringify(t))):(0,Q.kG)(void 0!==i,2),i});return"".concat(n.typename,":").concat(JSON.stringify(i))})}function iH(e){var t=iB(e);return t.keyArgsFn||(t.keyArgsFn=function(t,n){var r=n.field,i=n.variables,a=n.fieldName,o=JSON.stringify(i$(e,function(e){var n=e[0],a=n.charAt(0);if("@"===a){if(r&&(0,tP.O)(r.directives)){var o=n.slice(1),s=r.directives.find(function(e){return e.name.value===o}),u=s&&eZ(s,i);return u&&iW(u,e.slice(1))}return}if("$"===a){var c=n.slice(1);if(i&&ic.call(i,c)){var l=e.slice(0);return l[0]=c,iW(i,l)}return}if(t)return iW(t,e)}));return(t||"{}"!==o)&&(a+=":"+o),a})}function i$(e,t){var n=new tB;return iz(e).reduce(function(e,r){var i,a=t(r);if(void 0!==a){for(var o=r.length-1;o>=0;--o)a=((i={})[r[o]]=a,i);e=n.merge(e,a)}return e},Object.create(null))}function iz(e){var t=iB(e);if(!t.paths){var n=t.paths=[],r=[];e.forEach(function(t,i){(0,tP.k)(t)?(iz(t).forEach(function(e){return n.push(r.concat(e))}),r.length=0):(r.push(t),(0,tP.k)(e[i+1])||(n.push(r.slice(0)),r.length=0))})}return t.paths}function iG(e,t){return e[t]}function iW(e,t,n){return n=n||iG,iK(t.reduce(function e(t,r){return(0,tP.k)(t)?t.map(function(t){return e(t,r)}):t&&n(t,r)},e))}function iK(e){return(0,eO.s)(e)?(0,tP.k)(e)?e.map(iK):i$(Object.keys(e).sort(),function(t){return iW(e,t)}):e}function iV(e){return void 0!==e.args?e.args:e.field?eZ(e.field,e.variables):null}eK.setStringify(nx);var iq=function(){},iZ=function(e,t){return t.fieldName},iX=function(e,t,n){return(0,n.mergeObjects)(e,t)},iJ=function(e,t){return t},iQ=function(){function e(e){this.config=e,this.typePolicies=Object.create(null),this.toBeAdded=Object.create(null),this.supertypeMap=new Map,this.fuzzySubtypes=new Map,this.rootIdsByTypename=Object.create(null),this.rootTypenamesById=Object.create(null),this.usingPossibleTypes=!1,this.config=(0,en.pi)({dataIdFromObject:id},e),this.cache=this.config.cache,this.setRootTypename("Query"),this.setRootTypename("Mutation"),this.setRootTypename("Subscription"),e.possibleTypes&&this.addPossibleTypes(e.possibleTypes),e.typePolicies&&this.addTypePolicies(e.typePolicies)}return e.prototype.identify=function(e,t){var n,r,i=this,a=t&&(t.typename||(null===(n=t.storeObject)||void 0===n?void 0:n.__typename))||e.__typename;if(a===this.rootTypenamesById.ROOT_QUERY)return["ROOT_QUERY"];for(var o=t&&t.storeObject||e,s=(0,en.pi)((0,en.pi)({},t),{typename:a,storeObject:o,readField:t&&t.readField||function(){var e=i0(arguments,o);return i.readField(e,{store:i.cache.data,variables:e.variables})}}),u=a&&this.getTypePolicy(a),c=u&&u.keyFn||this.config.dataIdFromObject;c;){var l=c((0,en.pi)((0,en.pi)({},e),o),s);if((0,tP.k)(l))c=iU(l);else{r=l;break}}return r=r?String(r):void 0,s.keyObject?[r,s.keyObject]:[r]},e.prototype.addTypePolicies=function(e){var t=this;Object.keys(e).forEach(function(n){var r=e[n],i=r.queryType,a=r.mutationType,o=r.subscriptionType,s=(0,en._T)(r,["queryType","mutationType","subscriptionType"]);i&&t.setRootTypename("Query",n),a&&t.setRootTypename("Mutation",n),o&&t.setRootTypename("Subscription",n),ic.call(t.toBeAdded,n)?t.toBeAdded[n].push(s):t.toBeAdded[n]=[s]})},e.prototype.updateTypePolicy=function(e,t){var n=this,r=this.getTypePolicy(e),i=t.keyFields,a=t.fields;function o(e,t){e.merge="function"==typeof t?t:!0===t?iX:!1===t?iJ:e.merge}o(r,t.merge),r.keyFn=!1===i?iq:(0,tP.k)(i)?iU(i):"function"==typeof i?i:r.keyFn,a&&Object.keys(a).forEach(function(t){var r=n.getFieldPolicy(e,t,!0),i=a[t];if("function"==typeof i)r.read=i;else{var s=i.keyArgs,u=i.read,c=i.merge;r.keyFn=!1===s?iZ:(0,tP.k)(s)?iH(s):"function"==typeof s?s:r.keyFn,"function"==typeof u&&(r.read=u),o(r,c)}r.read&&r.merge&&(r.keyFn=r.keyFn||iZ)})},e.prototype.setRootTypename=function(e,t){void 0===t&&(t=e);var n="ROOT_"+e.toUpperCase(),r=this.rootTypenamesById[n];t!==r&&(__DEV__?(0,Q.kG)(!r||r===e,"Cannot change root ".concat(e," __typename more than once")):(0,Q.kG)(!r||r===e,3),r&&delete this.rootIdsByTypename[r],this.rootIdsByTypename[t]=n,this.rootTypenamesById[n]=t)},e.prototype.addPossibleTypes=function(e){var t=this;this.usingPossibleTypes=!0,Object.keys(e).forEach(function(n){t.getSupertypeSet(n,!0),e[n].forEach(function(e){t.getSupertypeSet(e,!0).add(n);var r=e.match(ig);r&&r[0]===e||t.fuzzySubtypes.set(e,RegExp(e))})})},e.prototype.getTypePolicy=function(e){var t=this;if(!ic.call(this.typePolicies,e)){var n=this.typePolicies[e]=Object.create(null);n.fields=Object.create(null);var r=this.supertypeMap.get(e);r&&r.size&&r.forEach(function(e){var r=t.getTypePolicy(e),i=r.fields;Object.assign(n,(0,en._T)(r,["fields"])),Object.assign(n.fields,i)})}var i=this.toBeAdded[e];return i&&i.length&&i.splice(0).forEach(function(n){t.updateTypePolicy(e,n)}),this.typePolicies[e]},e.prototype.getFieldPolicy=function(e,t,n){if(e){var r=this.getTypePolicy(e).fields;return r[t]||n&&(r[t]=Object.create(null))}},e.prototype.getSupertypeSet=function(e,t){var n=this.supertypeMap.get(e);return!n&&t&&this.supertypeMap.set(e,n=new Set),n},e.prototype.fragmentMatches=function(e,t,n,r){var i=this;if(!e.typeCondition)return!0;if(!t)return!1;var a=e.typeCondition.name.value;if(t===a)return!0;if(this.usingPossibleTypes&&this.supertypeMap.has(a))for(var o=this.getSupertypeSet(t,!0),s=[o],u=function(e){var t=i.getSupertypeSet(e,!1);t&&t.size&&0>s.indexOf(t)&&s.push(t)},c=!!(n&&this.fuzzySubtypes.size),l=!1,f=0;f1?a:t}:(r=(0,en.pi)({},i),ic.call(r,"from")||(r.from=t)),__DEV__&&void 0===r.from&&__DEV__&&Q.kG.warn("Undefined 'from' passed to readField with arguments ".concat(iF(Array.from(e)))),void 0===r.variables&&(r.variables=n),r}function i2(e){return function(t,n){if((0,tP.k)(t)||(0,tP.k)(n))throw __DEV__?new Q.ej("Cannot automatically merge arrays"):new Q.ej(4);if((0,eO.s)(t)&&(0,eO.s)(n)){var r=e.getFieldValue(t,"__typename"),i=e.getFieldValue(n,"__typename");if(r&&i&&r!==i)return n;if(eD(t)&&iw(n))return e.merge(t.__ref,n),t;if(iw(t)&&eD(n))return e.merge(t,n.__ref),n;if(iw(t)&&iw(n))return(0,en.pi)((0,en.pi)({},t),n)}return n}}function i3(e,t,n){var r="".concat(t).concat(n),i=e.flavors.get(r);return i||e.flavors.set(r,i=e.clientOnly===t&&e.deferred===n?e:(0,en.pi)((0,en.pi)({},e),{clientOnly:t,deferred:n})),i}var i4=function(){function e(e,t,n){this.cache=e,this.reader=t,this.fragments=n}return e.prototype.writeToStore=function(e,t){var n=this,r=t.query,i=t.result,a=t.dataId,o=t.variables,s=t.overwrite,u=e2(r),c=i_();o=(0,en.pi)((0,en.pi)({},e9(u)),o);var l=(0,en.pi)((0,en.pi)({store:e,written:Object.create(null),merge:function(e,t){return c.merge(e,t)},variables:o,varString:nx(o)},iE(r,this.fragments)),{overwrite:!!s,incomingById:new Map,clientOnly:!1,deferred:!1,flavors:new Map}),f=this.processSelectionSet({result:i||Object.create(null),dataId:a,selectionSet:u.selectionSet,mergeTree:{map:new Map},context:l});if(!eD(f))throw __DEV__?new Q.ej("Could not identify object ".concat(JSON.stringify(i))):new Q.ej(7);return l.incomingById.forEach(function(t,r){var i=t.storeObject,a=t.mergeTree,o=t.fieldNodeSet,s=eI(r);if(a&&a.map.size){var u=n.applyMerges(a,s,i,l);if(eD(u))return;i=u}if(__DEV__&&!l.overwrite){var c=Object.create(null);o.forEach(function(e){e.selectionSet&&(c[e.name.value]=!0)});var f=function(e){return!0===c[iv(e)]},d=function(e){var t=a&&a.map.get(e);return Boolean(t&&t.info&&t.info.merge)};Object.keys(i).forEach(function(e){f(e)&&!d(e)&&at(s,i,e,l.store)})}e.merge(r,i)}),e.retain(f.__ref),f},e.prototype.processSelectionSet=function(e){var t=this,n=e.dataId,r=e.result,i=e.selectionSet,a=e.context,o=e.mergeTree,s=this.cache.policies,u=Object.create(null),c=n&&s.rootTypenamesById[n]||eJ(r,i,a.fragmentMap)||n&&a.store.get(n,"__typename");"string"==typeof c&&(u.__typename=c);var l=function(){var e=i0(arguments,u,a.variables);if(eD(e.from)){var t=a.incomingById.get(e.from.__ref);if(t){var n=s.readField((0,en.pi)((0,en.pi)({},e),{from:t.storeObject}),a);if(void 0!==n)return n}}return s.readField(e,a)},f=new Set;this.flattenFields(i,r,a,c).forEach(function(e,n){var i,a=r[eX(n)];if(f.add(n),void 0!==a){var d=s.getStoreFieldName({typename:c,fieldName:n.name.value,field:n,variables:e.variables}),h=i5(o,d),p=t.processFieldValue(a,n,n.selectionSet?i3(e,!1,!1):e,h),b=void 0;n.selectionSet&&(eD(p)||iw(p))&&(b=l("__typename",p));var m=s.getMergeFunction(c,n.name.value,b);m?h.info={field:n,typename:c,merge:m}:i7(o,d),u=e.merge(u,((i={})[d]=p,i))}else __DEV__&&!e.clientOnly&&!e.deferred&&!nj.added(n)&&!s.getReadFunction(c,n.name.value)&&__DEV__&&Q.kG.error("Missing field '".concat(eX(n),"' while writing result ").concat(JSON.stringify(r,null,2)).substring(0,1e3))});try{var d=s.identify(r,{typename:c,selectionSet:i,fragmentMap:a.fragmentMap,storeObject:u,readField:l}),h=d[0],p=d[1];n=n||h,p&&(u=a.merge(u,p))}catch(b){if(!n)throw b}if("string"==typeof n){var m=eI(n),g=a.written[n]||(a.written[n]=[]);if(g.indexOf(i)>=0||(g.push(i),this.reader&&this.reader.isFresh(r,m,i,a)))return m;var v=a.incomingById.get(n);return v?(v.storeObject=a.merge(v.storeObject,u),v.mergeTree=i8(v.mergeTree,o),f.forEach(function(e){return v.fieldNodeSet.add(e)})):a.incomingById.set(n,{storeObject:u,mergeTree:i9(o)?void 0:o,fieldNodeSet:f}),m}return u},e.prototype.processFieldValue=function(e,t,n,r){var i=this;return t.selectionSet&&null!==e?(0,tP.k)(e)?e.map(function(e,a){var o=i.processFieldValue(e,t,n,i5(r,a));return i7(r,a),o}):this.processSelectionSet({result:e,selectionSet:t.selectionSet,context:n,mergeTree:r}):__DEV__?nJ(e):e},e.prototype.flattenFields=function(e,t,n,r){void 0===r&&(r=eJ(t,e,n.fragmentMap));var i=new Map,a=this.cache.policies,o=new n_(!1);return function e(s,u){var c=o.lookup(s,u.clientOnly,u.deferred);c.visited||(c.visited=!0,s.selections.forEach(function(o){if(td(o,n.variables)){var s=u.clientOnly,c=u.deferred;if(!(s&&c)&&(0,tP.O)(o.directives)&&o.directives.forEach(function(e){var t=e.name.value;if("client"===t&&(s=!0),"defer"===t){var r=eZ(e,n.variables);r&&!1===r.if||(c=!0)}}),eQ(o)){var l=i.get(o);l&&(s=s&&l.clientOnly,c=c&&l.deferred),i.set(o,i3(n,s,c))}else{var f=eC(o,n.lookupFragment);if(!f&&o.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(o.name.value)):new Q.ej(8);f&&a.fragmentMatches(f,r,t,n.variables)&&e(f.selectionSet,i3(n,s,c))}}}))}(e,n),i},e.prototype.applyMerges=function(e,t,n,r,i){var a=this;if(e.map.size&&!eD(n)){var o,s,u=!(0,tP.k)(n)&&(eD(t)||iw(t))?t:void 0,c=n;u&&!i&&(i=[eD(u)?u.__ref:u]);var l=function(e,t){return(0,tP.k)(e)?"number"==typeof t?e[t]:void 0:r.store.getFieldValue(e,String(t))};e.map.forEach(function(e,t){var n=l(u,t),o=l(c,t);if(void 0!==o){i&&i.push(t);var f=a.applyMerges(e,n,o,r,i);f!==o&&(s=s||new Map).set(t,f),i&&(0,Q.kG)(i.pop()===t)}}),s&&(n=(0,tP.k)(c)?c.slice(0):(0,en.pi)({},c),s.forEach(function(e,t){n[t]=e}))}return e.info?this.cache.policies.runMergeFunction(t,n,e.info,r,i&&(o=r.store).getStorage.apply(o,i)):n},e}(),i6=[];function i5(e,t){var n=e.map;return n.has(t)||n.set(t,i6.pop()||{map:new Map}),n.get(t)}function i8(e,t){if(e===t||!t||i9(t))return e;if(!e||i9(e))return t;var n=e.info&&t.info?(0,en.pi)((0,en.pi)({},e.info),t.info):e.info||t.info,r=e.map.size&&t.map.size,i=r?new Map:e.map.size?e.map:t.map,a={info:n,map:i};if(r){var o=new Set(t.map.keys());e.map.forEach(function(e,n){a.map.set(n,i8(e,t.map.get(n))),o.delete(n)}),o.forEach(function(n){a.map.set(n,i8(t.map.get(n),e.map.get(n)))})}return a}function i9(e){return!e||!(e.info||e.map.size)}function i7(e,t){var n=e.map,r=n.get(t);r&&i9(r)&&(i6.push(r),n.delete(t))}var ae=new Set;function at(e,t,n,r){var i=function(e){var t=r.getFieldValue(e,n);return"object"==typeof t&&t},a=i(e);if(a){var o=i(t);if(!(!o||eD(a)||(0,nm.D)(a,o)||Object.keys(a).every(function(e){return void 0!==r.getFieldValue(o,e)}))){var s=r.getFieldValue(e,"__typename")||r.getFieldValue(t,"__typename"),u=iv(n),c="".concat(s,".").concat(u);if(!ae.has(c)){ae.add(c);var l=[];(0,tP.k)(a)||(0,tP.k)(o)||[a,o].forEach(function(e){var t=r.getFieldValue(e,"__typename");"string"!=typeof t||l.includes(t)||l.push(t)}),__DEV__&&Q.kG.warn("Cache data may be lost when replacing the ".concat(u," field of a ").concat(s," object.\n\nThis could cause additional (usually avoidable) network requests to fetch data that were otherwise cached.\n\nTo address this problem (which is not a bug in Apollo Client), ").concat(l.length?"either ensure all objects of type "+l.join(" and ")+" have an ID or a custom merge function, or ":"","define a custom merge function for the ").concat(c," field, so InMemoryCache can safely merge these objects:\n\n existing: ").concat(JSON.stringify(a).slice(0,1e3),"\n incoming: ").concat(JSON.stringify(o).slice(0,1e3),"\n\nFor more information about these options, please refer to the documentation:\n\n * Ensuring entity objects have IDs: https://go.apollo.dev/c/generating-unique-identifiers\n * Defining custom merge functions: https://go.apollo.dev/c/merging-non-normalized-objects\n"))}}}}var an=function(e){function t(t){void 0===t&&(t={});var n=e.call(this)||this;return n.watches=new Set,n.typenameDocumentCache=new Map,n.makeVar=r2,n.txCount=0,n.config=ip(t),n.addTypename=!!n.config.addTypename,n.policies=new iQ({cache:n,dataIdFromObject:n.config.dataIdFromObject,possibleTypes:n.config.possibleTypes,typePolicies:n.config.typePolicies}),n.init(),n}return(0,en.ZT)(t,e),t.prototype.init=function(){var e=this.data=new iT.Root({policies:this.policies,resultCaching:this.config.resultCaching});this.optimisticData=e.stump,this.resetResultCache()},t.prototype.resetResultCache=function(e){var t=this,n=this.storeReader,r=this.config.fragments;this.storeWriter=new i4(this,this.storeReader=new iP({cache:this,addTypename:this.addTypename,resultCacheMaxSize:this.config.resultCacheMaxSize,canonizeResults:ib(this.config),canon:e?void 0:n&&n.canon,fragments:r}),r),this.maybeBroadcastWatch=rZ(function(e,n){return t.broadcastWatch(e,n)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var n=e.optimistic?t.optimisticData:t.data;if(iD(n)){var r=e.optimistic,i=e.id,a=e.variables;return n.makeCacheKey(e.query,e.callback,nx({optimistic:r,id:i,variables:a}))}}}),new Set([this.data.group,this.optimisticData.group,]).forEach(function(e){return e.resetCaching()})},t.prototype.restore=function(e){return this.init(),e&&this.data.replace(e),this},t.prototype.extract=function(e){return void 0===e&&(e=!1),(e?this.optimisticData:this.data).extract()},t.prototype.read=function(e){var t=e.returnPartialData,n=void 0!==t&&t;try{return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,config:this.config,returnPartialData:n})).result||null}catch(r){if(r instanceof is)return null;throw r}},t.prototype.write=function(e){try{return++this.txCount,this.storeWriter.writeToStore(this.data,e)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.modify=function(e){if(ic.call(e,"id")&&!e.id)return!1;var t=e.optimistic?this.optimisticData:this.data;try{return++this.txCount,t.modify(e.id||"ROOT_QUERY",e.fields)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.diff=function(e){return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,rootId:e.id||"ROOT_QUERY",config:this.config}))},t.prototype.watch=function(e){var t=this;return this.watches.size||r0(this),this.watches.add(e),e.immediate&&this.maybeBroadcastWatch(e),function(){t.watches.delete(e)&&!t.watches.size&&r1(t),t.maybeBroadcastWatch.forget(e)}},t.prototype.gc=function(e){nx.reset();var t=this.optimisticData.gc();return e&&!this.txCount&&(e.resetResultCache?this.resetResultCache(e.resetResultIdentities):e.resetResultIdentities&&this.storeReader.resetCanon()),t},t.prototype.retain=function(e,t){return(t?this.optimisticData:this.data).retain(e)},t.prototype.release=function(e,t){return(t?this.optimisticData:this.data).release(e)},t.prototype.identify=function(e){if(eD(e))return e.__ref;try{return this.policies.identify(e)[0]}catch(t){__DEV__&&Q.kG.warn(t)}},t.prototype.evict=function(e){if(!e.id){if(ic.call(e,"id"))return!1;e=(0,en.pi)((0,en.pi)({},e),{id:"ROOT_QUERY"})}try{return++this.txCount,this.optimisticData.evict(e,this.data)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.reset=function(e){var t=this;return this.init(),nx.reset(),e&&e.discardWatches?(this.watches.forEach(function(e){return t.maybeBroadcastWatch.forget(e)}),this.watches.clear(),r1(this)):this.broadcastWatches(),Promise.resolve()},t.prototype.removeOptimistic=function(e){var t=this.optimisticData.removeLayer(e);t!==this.optimisticData&&(this.optimisticData=t,this.broadcastWatches())},t.prototype.batch=function(e){var t,n=this,r=e.update,i=e.optimistic,a=void 0===i||i,o=e.removeOptimistic,s=e.onWatchUpdated,u=function(e){var i=n,a=i.data,o=i.optimisticData;++n.txCount,e&&(n.data=n.optimisticData=e);try{return t=r(n)}finally{--n.txCount,n.data=a,n.optimisticData=o}},c=new Set;return s&&!this.txCount&&this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e){return c.add(e),!1}})),"string"==typeof a?this.optimisticData=this.optimisticData.addLayer(a,u):!1===a?u(this.data):u(),"string"==typeof o&&(this.optimisticData=this.optimisticData.removeLayer(o)),s&&c.size?(this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e,t){var n=s.call(this,e,t);return!1!==n&&c.delete(e),n}})),c.size&&c.forEach(function(e){return n.maybeBroadcastWatch.dirty(e)})):this.broadcastWatches(e),t},t.prototype.performTransaction=function(e,t){return this.batch({update:e,optimistic:t||null!==t})},t.prototype.transformDocument=function(e){if(this.addTypename){var t=this.typenameDocumentCache.get(e);return t||(t=nj(e),this.typenameDocumentCache.set(e,t),this.typenameDocumentCache.set(t,t)),t}return e},t.prototype.transformForLink=function(e){var t=this.config.fragments;return t?t.transform(e):e},t.prototype.broadcastWatches=function(e){var t=this;this.txCount||this.watches.forEach(function(n){return t.maybeBroadcastWatch(n,e)})},t.prototype.broadcastWatch=function(e,t){var n=e.lastDiff,r=this.diff(e);(!t||(e.optimistic&&"string"==typeof t.optimistic&&(r.fromOptimisticTransaction=!0),!t.onWatchUpdated||!1!==t.onWatchUpdated.call(this,e,r,n)))&&(n&&(0,nm.D)(n.result,r.result)||e.callback(e.lastDiff=r,n))},t}(io),ar={possibleTypes:{ApproveJobProposalSpecPayload:["ApproveJobProposalSpecSuccess","JobAlreadyExistsError","NotFoundError"],BridgePayload:["Bridge","NotFoundError"],CancelJobProposalSpecPayload:["CancelJobProposalSpecSuccess","NotFoundError"],ChainPayload:["Chain","NotFoundError"],CreateAPITokenPayload:["CreateAPITokenSuccess","InputErrors"],CreateBridgePayload:["CreateBridgeSuccess"],CreateCSAKeyPayload:["CSAKeyExistsError","CreateCSAKeySuccess"],CreateFeedsManagerChainConfigPayload:["CreateFeedsManagerChainConfigSuccess","InputErrors","NotFoundError"],CreateFeedsManagerPayload:["CreateFeedsManagerSuccess","DuplicateFeedsManagerError","InputErrors","NotFoundError","SingleFeedsManagerError"],CreateJobPayload:["CreateJobSuccess","InputErrors"],CreateOCR2KeyBundlePayload:["CreateOCR2KeyBundleSuccess"],CreateOCRKeyBundlePayload:["CreateOCRKeyBundleSuccess"],CreateP2PKeyPayload:["CreateP2PKeySuccess"],DeleteAPITokenPayload:["DeleteAPITokenSuccess","InputErrors"],DeleteBridgePayload:["DeleteBridgeConflictError","DeleteBridgeInvalidNameError","DeleteBridgeSuccess","NotFoundError"],DeleteCSAKeyPayload:["DeleteCSAKeySuccess","NotFoundError"],DeleteFeedsManagerChainConfigPayload:["DeleteFeedsManagerChainConfigSuccess","NotFoundError"],DeleteJobPayload:["DeleteJobSuccess","NotFoundError"],DeleteOCR2KeyBundlePayload:["DeleteOCR2KeyBundleSuccess","NotFoundError"],DeleteOCRKeyBundlePayload:["DeleteOCRKeyBundleSuccess","NotFoundError"],DeleteP2PKeyPayload:["DeleteP2PKeySuccess","NotFoundError"],DeleteVRFKeyPayload:["DeleteVRFKeySuccess","NotFoundError"],DisableFeedsManagerPayload:["DisableFeedsManagerSuccess","NotFoundError"],DismissJobErrorPayload:["DismissJobErrorSuccess","NotFoundError"],EnableFeedsManagerPayload:["EnableFeedsManagerSuccess","NotFoundError"],Error:["CSAKeyExistsError","DeleteBridgeConflictError","DeleteBridgeInvalidNameError","DuplicateFeedsManagerError","InputError","JobAlreadyExistsError","NotFoundError","RunJobCannotRunError","SingleFeedsManagerError"],EthTransactionPayload:["EthTransaction","NotFoundError"],FeaturesPayload:["Features"],FeedsManagerPayload:["FeedsManager","NotFoundError"],GetSQLLoggingPayload:["SQLLogging"],GlobalLogLevelPayload:["GlobalLogLevel"],JobPayload:["Job","NotFoundError"],JobProposalPayload:["JobProposal","NotFoundError"],JobRunPayload:["JobRun","NotFoundError"],JobSpec:["BlockHeaderFeederSpec","BlockhashStoreSpec","BootstrapSpec","CronSpec","DirectRequestSpec","FluxMonitorSpec","GatewaySpec","KeeperSpec","OCR2Spec","OCRSpec","StandardCapabilitiesSpec","StreamSpec","VRFSpec","WebhookSpec","WorkflowSpec"],NodePayload:["Node","NotFoundError"],PaginatedPayload:["BridgesPayload","ChainsPayload","EthTransactionAttemptsPayload","EthTransactionsPayload","JobRunsPayload","JobsPayload","NodesPayload"],RejectJobProposalSpecPayload:["NotFoundError","RejectJobProposalSpecSuccess"],RunJobPayload:["NotFoundError","RunJobCannotRunError","RunJobSuccess"],SetGlobalLogLevelPayload:["InputErrors","SetGlobalLogLevelSuccess"],SetSQLLoggingPayload:["SetSQLLoggingSuccess"],SetServicesLogLevelsPayload:["InputErrors","SetServicesLogLevelsSuccess"],UpdateBridgePayload:["NotFoundError","UpdateBridgeSuccess"],UpdateFeedsManagerChainConfigPayload:["InputErrors","NotFoundError","UpdateFeedsManagerChainConfigSuccess"],UpdateFeedsManagerPayload:["InputErrors","NotFoundError","UpdateFeedsManagerSuccess"],UpdateJobProposalSpecDefinitionPayload:["NotFoundError","UpdateJobProposalSpecDefinitionSuccess"],UpdatePasswordPayload:["InputErrors","UpdatePasswordSuccess"],VRFKeyPayload:["NotFoundError","VRFKeySuccess"]}};let ai=ar;var aa=(r=void 0,location.origin),ao=new nh({uri:"".concat(aa,"/query"),credentials:"include"}),as=new ia({cache:new an({possibleTypes:ai.possibleTypes}),link:ao});if(a.Z.locale(o),u().defaultFormat="YYYY-MM-DD h:mm:ss A","undefined"!=typeof document){var au,ac,al=f().hydrate;ac=X,al(c.createElement(et,{client:as},c.createElement(d.zj,null,c.createElement(i.MuiThemeProvider,{theme:J.r},c.createElement(ac,null)))),document.getElementById("root"))}})()})(); \ No newline at end of file +`+(a!==i?`result of cast: ${a}`:""))}return r}_cast(e,t){let n=void 0===e?e:this.transforms.reduce((t,n)=>n.call(this,t,e,this),e);return void 0===n&&(n=this.getDefault()),n}_validate(e,t={},n){let{sync:r,path:i,from:a=[],originalValue:o=e,strict:s=this.spec.strict,abortEarly:u=this.spec.abortEarly}=t,c=e;s||(c=this._cast(c,pB({assert:!1},t)));let l={value:c,path:i,options:t,originalValue:o,schema:this,label:this.spec.label,sync:r,from:a},f=[];this._typeError&&f.push(this._typeError),this._whitelistError&&f.push(this._whitelistError),this._blacklistError&&f.push(this._blacklistError),pO({args:l,value:c,path:i,sync:r,tests:f,endEarly:u},e=>{if(e)return void n(e,c);pO({tests:this.tests,args:l,path:i,sync:r,value:c,endEarly:u},n)})}validate(e,t,n){let r=this.resolve(pB({},t,{value:e}));return"function"==typeof n?r._validate(e,t,n):new Promise((n,i)=>r._validate(e,t,(e,t)=>{e?i(e):n(t)}))}validateSync(e,t){let n;return this.resolve(pB({},t,{value:e}))._validate(e,pB({},t,{sync:!0}),(e,t)=>{if(e)throw e;n=t}),n}isValid(e,t){return this.validate(e,t).then(()=>!0,e=>{if(pT.isError(e))return!1;throw e})}isValidSync(e,t){try{return this.validateSync(e,t),!0}catch(n){if(pT.isError(n))return!1;throw n}}_getDefault(){let e=this.spec.default;return null==e?e:"function"==typeof e?e.call(this):pn(e)}getDefault(e){return this.resolve(e||{})._getDefault()}default(e){return 0===arguments.length?this._getDefault():this.clone({default:e})}strict(e=!0){var t=this.clone();return t.spec.strict=e,t}_isPresent(e){return null!=e}defined(e=pf.defined){return this.test({message:e,name:"defined",exclusive:!0,test:e=>void 0!==e})}required(e=pf.required){return this.clone({presence:"required"}).withMutation(t=>t.test({message:e,name:"required",exclusive:!0,test(e){return this.schema._isPresent(e)}}))}notRequired(){var e=this.clone({presence:"optional"});return e.tests=e.tests.filter(e=>"required"!==e.OPTIONS.name),e}nullable(e=!0){return this.clone({nullable:!1!==e})}transform(e){var t=this.clone();return t.transforms.push(e),t}test(...e){let t;if(void 0===(t=1===e.length?"function"==typeof e[0]?{test:e[0]}:e[0]:2===e.length?{name:e[0],test:e[1]}:{name:e[0],message:e[1],test:e[2]}).message&&(t.message=pf.default),"function"!=typeof t.test)throw TypeError("`test` is a required parameters");let n=this.clone(),r=pR(t),i=t.exclusive||t.name&&!0===n.exclusiveTests[t.name];if(t.exclusive&&!t.name)throw TypeError("Exclusive tests must provide a unique `name` identifying the test");return t.name&&(n.exclusiveTests[t.name]=!!t.exclusive),n.tests=n.tests.filter(e=>e.OPTIONS.name!==t.name||!i&&e.OPTIONS.test!==r.OPTIONS.test),n.tests.push(r),n}when(e,t){Array.isArray(e)||"string"==typeof e||(t=e,e=".");let n=this.clone(),r=pS(e).map(e=>new pD(e));return r.forEach(e=>{e.isSibling&&n.deps.push(e.key)}),n.conditions.push(new pE(r,t)),n}typeError(e){var t=this.clone();return t._typeError=pR({message:e,name:"typeError",test(e){return!!(void 0===e||this.schema.isType(e))||this.createError({params:{type:this.schema._type}})}}),t}oneOf(e,t=pf.oneOf){var n=this.clone();return e.forEach(e=>{n._whitelist.add(e),n._blacklist.delete(e)}),n._whitelistError=pR({message:t,name:"oneOf",test(e){if(void 0===e)return!0;let t=this.schema._whitelist;return!!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}notOneOf(e,t=pf.notOneOf){var n=this.clone();return e.forEach(e=>{n._blacklist.add(e),n._whitelist.delete(e)}),n._blacklistError=pR({message:t,name:"notOneOf",test(e){let t=this.schema._blacklist;return!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),n}strip(e=!0){let t=this.clone();return t.spec.strip=e,t}describe(){let e=this.clone(),{label:t,meta:n}=e.spec,r={meta:n,label:t,type:e.type,oneOf:e._whitelist.describe(),notOneOf:e._blacklist.describe(),tests:e.tests.map(e=>({name:e.OPTIONS.name,params:e.OPTIONS.params})).filter((e,t,n)=>n.findIndex(t=>t.name===e.name)===t)};return r}}for(let pH of(pU.prototype.__isYupSchema__=!0,["validate","validateSync"]))pU.prototype[`${pH}At`]=function(e,t,n={}){let{parent:r,parentPath:i,schema:a}=pF(this,e,t,n.context);return a[pH](r&&r[i],pB({},n,{parent:r,path:e}))};for(let p$ of["equals","is"])pU.prototype[p$]=pU.prototype.oneOf;for(let pz of["not","nope"])pU.prototype[pz]=pU.prototype.notOneOf;pU.prototype.optional=pU.prototype.notRequired;let pG=pU;function pW(){return new pG}pW.prototype=pG.prototype;let pK=e=>null==e;function pV(){return new pq}class pq extends pU{constructor(){super({type:"boolean"}),this.withMutation(()=>{this.transform(function(e){if(!this.isType(e)){if(/^(true|1)$/i.test(String(e)))return!0;if(/^(false|0)$/i.test(String(e)))return!1}return e})})}_typeCheck(e){return e instanceof Boolean&&(e=e.valueOf()),"boolean"==typeof e}isTrue(e=pb.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"true"},test:e=>pK(e)||!0===e})}isFalse(e=pb.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"false"},test:e=>pK(e)||!1===e})}}pV.prototype=pq.prototype;let pZ=/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,pX=/^((https?|ftp):)?\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,pJ=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i,pQ=e=>pK(e)||e===e.trim(),p1=({}).toString();function p0(){return new p2}class p2 extends pU{constructor(){super({type:"string"}),this.withMutation(()=>{this.transform(function(e){if(this.isType(e)||Array.isArray(e))return e;let t=null!=e&&e.toString?e.toString():e;return t===p1?e:t})})}_typeCheck(e){return e instanceof String&&(e=e.valueOf()),"string"==typeof e}_isPresent(e){return super._isPresent(e)&&!!e.length}length(e,t=pd.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pK(t)||t.length===this.resolve(e)}})}min(e,t=pd.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t.length>=this.resolve(e)}})}max(e,t=pd.max){return this.test({name:"max",exclusive:!0,message:t,params:{max:e},test(t){return pK(t)||t.length<=this.resolve(e)}})}matches(e,t){let n=!1,r,i;return t&&("object"==typeof t?{excludeEmptyString:n=!1,message:r,name:i}=t:r=t),this.test({name:i||"matches",message:r||pd.matches,params:{regex:e},test:t=>pK(t)||""===t&&n||-1!==t.search(e)})}email(e=pd.email){return this.matches(pZ,{name:"email",message:e,excludeEmptyString:!0})}url(e=pd.url){return this.matches(pX,{name:"url",message:e,excludeEmptyString:!0})}uuid(e=pd.uuid){return this.matches(pJ,{name:"uuid",message:e,excludeEmptyString:!1})}ensure(){return this.default("").transform(e=>null===e?"":e)}trim(e=pd.trim){return this.transform(e=>null!=e?e.trim():e).test({message:e,name:"trim",test:pQ})}lowercase(e=pd.lowercase){return this.transform(e=>pK(e)?e:e.toLowerCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pK(e)||e===e.toLowerCase()})}uppercase(e=pd.uppercase){return this.transform(e=>pK(e)?e:e.toUpperCase()).test({message:e,name:"string_case",exclusive:!0,test:e=>pK(e)||e===e.toUpperCase()})}}p0.prototype=p2.prototype;let p3=e=>e!=+e;function p4(){return new p6}class p6 extends pU{constructor(){super({type:"number"}),this.withMutation(()=>{this.transform(function(e){let t=e;if("string"==typeof t){if(""===(t=t.replace(/\s/g,"")))return NaN;t=+t}return this.isType(t)?t:parseFloat(t)})})}_typeCheck(e){return e instanceof Number&&(e=e.valueOf()),"number"==typeof e&&!p3(e)}min(e,t=ph.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t>=this.resolve(e)}})}max(e,t=ph.max){return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pK(t)||t<=this.resolve(e)}})}lessThan(e,t=ph.lessThan){return this.test({message:t,name:"max",exclusive:!0,params:{less:e},test(t){return pK(t)||tthis.resolve(e)}})}positive(e=ph.positive){return this.moreThan(0,e)}negative(e=ph.negative){return this.lessThan(0,e)}integer(e=ph.integer){return this.test({name:"integer",message:e,test:e=>pK(e)||Number.isInteger(e)})}truncate(){return this.transform(e=>pK(e)?e:0|e)}round(e){var t,n=["ceil","floor","round","trunc"];if("trunc"===(e=(null==(t=e)?void 0:t.toLowerCase())||"round"))return this.truncate();if(-1===n.indexOf(e.toLowerCase()))throw TypeError("Only valid options for round() are: "+n.join(", "));return this.transform(t=>pK(t)?t:Math[e](t))}}p4.prototype=p6.prototype;var p5=/^(\d{4}|[+\-]\d{6})(?:-?(\d{2})(?:-?(\d{2}))?)?(?:[ T]?(\d{2}):?(\d{2})(?::?(\d{2})(?:[,\.](\d{1,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?)?)?$/;function p8(e){var t,n,r=[1,4,5,6,7,10,11],i=0;if(n=p5.exec(e)){for(var a,o=0;a=r[o];++o)n[a]=+n[a]||0;n[2]=(+n[2]||1)-1,n[3]=+n[3]||1,n[7]=n[7]?String(n[7]).substr(0,3):0,(void 0===n[8]||""===n[8])&&(void 0===n[9]||""===n[9])?t=+new Date(n[1],n[2],n[3],n[4],n[5],n[6],n[7]):("Z"!==n[8]&&void 0!==n[9]&&(i=60*n[10]+n[11],"+"===n[9]&&(i=0-i)),t=Date.UTC(n[1],n[2],n[3],n[4],n[5]+i,n[6],n[7]))}else t=Date.parse?Date.parse(e):NaN;return t}let p9=new Date(""),p7=e=>"[object Date]"===Object.prototype.toString.call(e);function be(){return new bt}class bt extends pU{constructor(){super({type:"date"}),this.withMutation(()=>{this.transform(function(e){return this.isType(e)?e:(e=p8(e),isNaN(e)?p9:new Date(e))})})}_typeCheck(e){return p7(e)&&!isNaN(e.getTime())}prepareParam(e,t){let n;if(pD.isRef(e))n=e;else{let r=this.cast(e);if(!this._typeCheck(r))throw TypeError(`\`${t}\` must be a Date or a value that can be \`cast()\` to a Date`);n=r}return n}min(e,t=pp.min){let n=this.prepareParam(e,"min");return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(e){return pK(e)||e>=this.resolve(n)}})}max(e,t=pp.max){var n=this.prepareParam(e,"max");return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(e){return pK(e)||e<=this.resolve(n)}})}}bt.INVALID_DATE=p9,be.prototype=bt.prototype,be.INVALID_DATE=p9;var bn=n(11865),br=n.n(bn),bi=n(68929),ba=n.n(bi),bo=n(67523),bs=n.n(bo),bu=n(94633),bc=n.n(bu);function bl(e,t=[]){let n=[],r=[];function i(e,i){var a=(0,pC.split)(e)[0];~r.indexOf(a)||r.push(a),~t.indexOf(`${i}-${a}`)||n.push([i,a])}for(let a in e)if(py()(e,a)){let o=e[a];~r.indexOf(a)||r.push(a),pD.isRef(o)&&o.isSibling?i(o.path,a):pw(o)&&"deps"in o&&o.deps.forEach(e=>i(e,a))}return bc().array(r,n).reverse()}function bf(e,t){let n=1/0;return e.some((e,r)=>{var i;if((null==(i=t.path)?void 0:i.indexOf(e))!==-1)return n=r,!0}),n}function bd(e){return(t,n)=>bf(e,t)-bf(e,n)}function bh(){return(bh=Object.assign||function(e){for(var t=1;t"[object Object]"===Object.prototype.toString.call(e);function bb(e,t){let n=Object.keys(e.fields);return Object.keys(t).filter(e=>-1===n.indexOf(e))}let bm=bd([]);class bg extends pU{constructor(e){super({type:"object"}),this.fields=Object.create(null),this._sortErrors=bm,this._nodes=[],this._excludedEdges=[],this.withMutation(()=>{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null}),e&&this.shape(e)})}_typeCheck(e){return bp(e)||"function"==typeof e}_cast(e,t={}){var n;let r=super._cast(e,t);if(void 0===r)return this.getDefault();if(!this._typeCheck(r))return r;let i=this.fields,a=null!=(n=t.stripUnknown)?n:this.spec.noUnknown,o=this._nodes.concat(Object.keys(r).filter(e=>-1===this._nodes.indexOf(e))),s={},u=bh({},t,{parent:s,__validating:t.__validating||!1}),c=!1;for(let l of o){let f=i[l],d=py()(r,l);if(f){let h,p=r[l];u.path=(t.path?`${t.path}.`:"")+l;let b="spec"in(f=f.resolve({value:p,context:t.context,parent:s}))?f.spec:void 0,m=null==b?void 0:b.strict;if(null==b?void 0:b.strip){c=c||l in r;continue}void 0!==(h=t.__validating&&m?r[l]:f.cast(r[l],u))&&(s[l]=h)}else d&&!a&&(s[l]=r[l]);s[l]!==r[l]&&(c=!0)}return c?s:r}_validate(e,t={},n){let r=[],{sync:i,from:a=[],originalValue:o=e,abortEarly:s=this.spec.abortEarly,recursive:u=this.spec.recursive}=t;a=[{schema:this,value:o},...a],t.__validating=!0,t.originalValue=o,t.from=a,super._validate(e,t,(e,c)=>{if(e){if(!pT.isError(e)||s)return void n(e,c);r.push(e)}if(!u||!bp(c)){n(r[0]||null,c);return}o=o||c;let l=this._nodes.map(e=>(n,r)=>{let i=-1===e.indexOf(".")?(t.path?`${t.path}.`:"")+e:`${t.path||""}["${e}"]`,s=this.fields[e];if(s&&"validate"in s){s.validate(c[e],bh({},t,{path:i,from:a,strict:!0,parent:c,originalValue:o[e]}),r);return}r(null)});pO({sync:i,tests:l,value:c,errors:r,endEarly:s,sort:this._sortErrors,path:t.path},n)})}clone(e){let t=super.clone(e);return t.fields=bh({},this.fields),t._nodes=this._nodes,t._excludedEdges=this._excludedEdges,t._sortErrors=this._sortErrors,t}concat(e){let t=super.concat(e),n=t.fields;for(let[r,i]of Object.entries(this.fields)){let a=n[r];void 0===a?n[r]=i:a instanceof pU&&i instanceof pU&&(n[r]=i.concat(a))}return t.withMutation(()=>t.shape(n))}getDefaultFromShape(){let e={};return this._nodes.forEach(t=>{let n=this.fields[t];e[t]="default"in n?n.getDefault():void 0}),e}_getDefault(){return"default"in this.spec?super._getDefault():this._nodes.length?this.getDefaultFromShape():void 0}shape(e,t=[]){let n=this.clone(),r=Object.assign(n.fields,e);if(n.fields=r,n._sortErrors=bd(Object.keys(r)),t.length){Array.isArray(t[0])||(t=[t]);let i=t.map(([e,t])=>`${e}-${t}`);n._excludedEdges=n._excludedEdges.concat(i)}return n._nodes=bl(r,n._excludedEdges),n}pick(e){let t={};for(let n of e)this.fields[n]&&(t[n]=this.fields[n]);return this.clone().withMutation(e=>(e.fields={},e.shape(t)))}omit(e){let t=this.clone(),n=t.fields;for(let r of(t.fields={},e))delete n[r];return t.withMutation(()=>t.shape(n))}from(e,t,n){let r=(0,pC.getter)(e,!0);return this.transform(i=>{if(null==i)return i;let a=i;return py()(i,e)&&(a=bh({},i),n||delete a[e],a[t]=r(i)),a})}noUnknown(e=!0,t=pm.noUnknown){"string"==typeof e&&(t=e,e=!0);let n=this.test({name:"noUnknown",exclusive:!0,message:t,test(t){if(null==t)return!0;let n=bb(this.schema,t);return!e||0===n.length||this.createError({params:{unknown:n.join(", ")}})}});return n.spec.noUnknown=e,n}unknown(e=!0,t=pm.noUnknown){return this.noUnknown(!e,t)}transformKeys(e){return this.transform(t=>t&&bs()(t,(t,n)=>e(n)))}camelCase(){return this.transformKeys(ba())}snakeCase(){return this.transformKeys(br())}constantCase(){return this.transformKeys(e=>br()(e).toUpperCase())}describe(){let e=super.describe();return e.fields=pL()(this.fields,e=>e.describe()),e}}function bv(e){return new bg(e)}function by(){return(by=Object.assign||function(e){for(var t=1;t{this.transform(function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null})})}_typeCheck(e){return Array.isArray(e)}get _subType(){return this.innerType}_cast(e,t){let n=super._cast(e,t);if(!this._typeCheck(n)||!this.innerType)return n;let r=!1,i=n.map((e,n)=>{let i=this.innerType.cast(e,by({},t,{path:`${t.path||""}[${n}]`}));return i!==e&&(r=!0),i});return r?i:n}_validate(e,t={},n){var r,i;let a=[],o=t.sync,s=t.path,u=this.innerType,c=null!=(r=t.abortEarly)?r:this.spec.abortEarly,l=null!=(i=t.recursive)?i:this.spec.recursive,f=null!=t.originalValue?t.originalValue:e;super._validate(e,t,(e,r)=>{if(e){if(!pT.isError(e)||c)return void n(e,r);a.push(e)}if(!l||!u||!this._typeCheck(r)){n(a[0]||null,r);return}f=f||r;let i=Array(r.length);for(let d=0;du.validate(h,b,t)}pO({sync:o,path:s,value:r,errors:a,endEarly:c,tests:i},n)})}clone(e){let t=super.clone(e);return t.innerType=this.innerType,t}concat(e){let t=super.concat(e);return t.innerType=this.innerType,e.innerType&&(t.innerType=t.innerType?t.innerType.concat(e.innerType):e.innerType),t}of(e){let t=this.clone();if(!pw(e))throw TypeError("`array.of()` sub-schema must be a valid yup schema not: "+pl(e));return t.innerType=e,t}length(e,t=pg.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(t){return pK(t)||t.length===this.resolve(e)}})}min(e,t){return t=t||pg.min,this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(t){return pK(t)||t.length>=this.resolve(e)}})}max(e,t){return t=t||pg.max,this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(t){return pK(t)||t.length<=this.resolve(e)}})}ensure(){return this.default(()=>[]).transform((e,t)=>this._typeCheck(e)?e:null==t?[]:[].concat(t))}compact(e){let t=e?(t,n,r)=>!e(t,n,r):e=>!!e;return this.transform(e=>null!=e?e.filter(t):e)}describe(){let e=super.describe();return this.innerType&&(e.innerType=this.innerType.describe()),e}nullable(e=!0){return super.nullable(e)}defined(){return super.defined()}required(e){return super.required(e)}}bw.prototype=b_.prototype;var bE=bv().shape({name:p0().required("Required"),url:p0().required("Required")}),bS=function(e){var t=e.initialValues,n=e.onSubmit,r=e.submitButtonText,i=e.nameDisabled,a=void 0!==i&&i;return l.createElement(hT,{initialValues:t,validationSchema:bE,onSubmit:n},function(e){var t=e.isSubmitting;return l.createElement(l.Fragment,null,l.createElement(hR,{"data-testid":"bridge-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hP,{component:hX,id:"name",name:"name",label:"Name",disabled:a,required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(hP,{component:hX,id:"url",name:"url",label:"Bridge URL",placeholder:"https://",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"url-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:7},l.createElement(hP,{component:hX,id:"minimumContractPayment",name:"minimumContractPayment",label:"Minimum Contract Payment",placeholder:"0",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"minimumContractPayment-helper-text"}})),l.createElement(d.Z,{item:!0,xs:7},l.createElement(hP,{component:hX,id:"confirmations",name:"confirmations",label:"Confirmations",placeholder:"0",type:"number",fullWidth:!0,inputProps:{min:0},FormHelperTextProps:{"data-testid":"confirmations-helper-text"}})))),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},r)))))})},bk=function(e){var t=e.bridge,n=e.onSubmit,r={name:t.name,url:t.url,minimumContractPayment:t.minimumContractPayment,confirmations:t.confirmations};return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:40},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Edit Bridge",action:l.createElement(aA.Z,{component:tz,href:"/bridges/".concat(t.id)},"Cancel")}),l.createElement(aW.Z,null,l.createElement(bS,{nameDisabled:!0,initialValues:r,onSubmit:n,submitButtonText:"Save Bridge"}))))))};function bx(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]&&arguments[0],t=e?function(){return l.createElement(x.default,{variant:"body1"},"Loading...")}:function(){return null};return{isLoading:e,LoadingPlaceholder:t}},mc=n(76023);function ml(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function mB(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=4?[e[0],e[1],e[2],e[3],"".concat(e[0],".").concat(e[1]),"".concat(e[0],".").concat(e[2]),"".concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[0]),"".concat(e[1],".").concat(e[2]),"".concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[1]),"".concat(e[2],".").concat(e[3]),"".concat(e[3],".").concat(e[0]),"".concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[0]),"".concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[1],".").concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[2],".").concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[3],".").concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[2],".").concat(e[1],".").concat(e[0])]:void 0}var mZ={};function mX(e){if(0===e.length||1===e.length)return e;var t=e.join(".");return mZ[t]||(mZ[t]=mq(e)),mZ[t]}function mJ(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0;return mX(e.filter(function(e){return"token"!==e})).reduce(function(e,t){return mK({},e,n[t])},t)}function mQ(e){return e.join(" ")}function m1(e,t){var n=0;return function(r){return n+=1,r.map(function(r,i){return m0({node:r,stylesheet:e,useInlineStyles:t,key:"code-segment-".concat(n,"-").concat(i)})})}}function m0(e){var t=e.node,n=e.stylesheet,r=e.style,i=void 0===r?{}:r,a=e.useInlineStyles,o=e.key,s=t.properties,u=t.type,c=t.tagName,f=t.value;if("text"===u)return f;if(c){var d,h=m1(n,a);if(a){var p=Object.keys(n).reduce(function(e,t){return t.split(".").forEach(function(t){e.includes(t)||e.push(t)}),e},[]),b=s.className&&s.className.includes("token")?["token"]:[],m=s.className&&b.concat(s.className.filter(function(e){return!p.includes(e)}));d=mK({},s,{className:mQ(m)||void 0,style:mJ(s.className,Object.assign({},s.style,i),n)})}else d=mK({},s,{className:mQ(s.className)});var g=h(t.children);return l.createElement(c,(0,mV.Z)({key:o},d),g)}}let m2=function(e,t){return -1!==e.listLanguages().indexOf(t)};var m3=/\n/g;function m4(e){return e.match(m3)}function m6(e){var t=e.lines,n=e.startingLineNumber,r=e.style;return t.map(function(e,t){var i=t+n;return l.createElement("span",{key:"line-".concat(t),className:"react-syntax-highlighter-line-number",style:"function"==typeof r?r(i):r},"".concat(i,"\n"))})}function m5(e){var t=e.codeString,n=e.codeStyle,r=e.containerStyle,i=void 0===r?{float:"left",paddingRight:"10px"}:r,a=e.numberStyle,o=void 0===a?{}:a,s=e.startingLineNumber;return l.createElement("code",{style:Object.assign({},n,i)},m6({lines:t.replace(/\n$/,"").split("\n"),style:o,startingLineNumber:s}))}function m8(e){return"".concat(e.toString().length,".25em")}function m9(e,t){return{type:"element",tagName:"span",properties:{key:"line-number--".concat(e),className:["comment","linenumber","react-syntax-highlighter-line-number"],style:t},children:[{type:"text",value:e}]}}function m7(e,t,n){var r,i={display:"inline-block",minWidth:m8(n),paddingRight:"1em",textAlign:"right",userSelect:"none"};return mK({},i,"function"==typeof e?e(t):e)}function ge(e){var t=e.children,n=e.lineNumber,r=e.lineNumberStyle,i=e.largestLineNumber,a=e.showInlineLineNumbers,o=e.lineProps,s=void 0===o?{}:o,u=e.className,c=void 0===u?[]:u,l=e.showLineNumbers,f=e.wrapLongLines,d="function"==typeof s?s(n):s;if(d.className=c,n&&a){var h=m7(r,n,i);t.unshift(m9(n,h))}return f&l&&(d.style=mK({},d.style,{display:"flex"})),{type:"element",tagName:"span",properties:d,children:t}}function gt(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],r=0;r2&&void 0!==arguments[2]?arguments[2]:[];return ge({children:e,lineNumber:t,lineNumberStyle:s,largestLineNumber:o,showInlineLineNumbers:i,lineProps:n,className:a,showLineNumbers:r,wrapLongLines:u})}function b(e,t){if(r&&t&&i){var n=m7(s,t,o);e.unshift(m9(t,n))}return e}function m(e,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return t||r.length>0?p(e,n,r):b(e,n)}for(var g=function(){var e=l[h],t=e.children[0].value;if(m4(t)){var n=t.split("\n");n.forEach(function(t,i){var o=r&&f.length+a,s={type:"text",value:"".concat(t,"\n")};if(0===i){var u=l.slice(d+1,h).concat(ge({children:[s],className:e.properties.className})),c=m(u,o);f.push(c)}else if(i===n.length-1){if(l[h+1]&&l[h+1].children&&l[h+1].children[0]){var p={type:"text",value:"".concat(t)},b=ge({children:[p],className:e.properties.className});l.splice(h+1,0,b)}else{var g=[s],v=m(g,o,e.properties.className);f.push(v)}}else{var y=[s],w=m(y,o,e.properties.className);f.push(w)}}),d=h}h++};h code[class*="language-"]':{background:"#f5f2f0",padding:".1em",borderRadius:".3em",whiteSpace:"normal"},comment:{color:"slategray"},prolog:{color:"slategray"},doctype:{color:"slategray"},cdata:{color:"slategray"},punctuation:{color:"#999"},namespace:{Opacity:".7"},property:{color:"#905"},tag:{color:"#905"},boolean:{color:"#905"},number:{color:"#905"},constant:{color:"#905"},symbol:{color:"#905"},deleted:{color:"#905"},selector:{color:"#690"},"attr-name":{color:"#690"},string:{color:"#690"},char:{color:"#690"},builtin:{color:"#690"},inserted:{color:"#690"},operator:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},entity:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)",cursor:"help"},url:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".language-css .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".style .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},atrule:{color:"#07a"},"attr-value":{color:"#07a"},keyword:{color:"#07a"},function:{color:"#DD4A68"},"class-name":{color:"#DD4A68"},regex:{color:"#e90"},important:{color:"#e90",fontWeight:"bold"},variable:{color:"#e90"},bold:{fontWeight:"bold"},italic:{fontStyle:"italic"}};var gu=n(98695),gc=n.n(gu);let gl=["abap","abnf","actionscript","ada","agda","al","antlr4","apacheconf","apl","applescript","aql","arduino","arff","asciidoc","asm6502","aspnet","autohotkey","autoit","bash","basic","batch","bbcode","birb","bison","bnf","brainfuck","brightscript","bro","bsl","c","cil","clike","clojure","cmake","coffeescript","concurnas","cpp","crystal","csharp","csp","css-extras","css","cypher","d","dart","dax","dhall","diff","django","dns-zone-file","docker","ebnf","editorconfig","eiffel","ejs","elixir","elm","erb","erlang","etlua","excel-formula","factor","firestore-security-rules","flow","fortran","fsharp","ftl","gcode","gdscript","gedcom","gherkin","git","glsl","gml","go","graphql","groovy","haml","handlebars","haskell","haxe","hcl","hlsl","hpkp","hsts","http","ichigojam","icon","iecst","ignore","inform7","ini","io","j","java","javadoc","javadoclike","javascript","javastacktrace","jolie","jq","js-extras","js-templates","jsdoc","json","json5","jsonp","jsstacktrace","jsx","julia","keyman","kotlin","latex","latte","less","lilypond","liquid","lisp","livescript","llvm","lolcode","lua","makefile","markdown","markup-templating","markup","matlab","mel","mizar","mongodb","monkey","moonscript","n1ql","n4js","nand2tetris-hdl","naniscript","nasm","neon","nginx","nim","nix","nsis","objectivec","ocaml","opencl","oz","parigp","parser","pascal","pascaligo","pcaxis","peoplecode","perl","php-extras","php","phpdoc","plsql","powerquery","powershell","processing","prolog","properties","protobuf","pug","puppet","pure","purebasic","purescript","python","q","qml","qore","r","racket","reason","regex","renpy","rest","rip","roboconf","robotframework","ruby","rust","sas","sass","scala","scheme","scss","shell-session","smali","smalltalk","smarty","sml","solidity","solution-file","soy","sparql","splunk-spl","sqf","sql","stan","stylus","swift","t4-cs","t4-templating","t4-vb","tap","tcl","textile","toml","tsx","tt2","turtle","twig","typescript","typoscript","unrealscript","vala","vbnet","velocity","verilog","vhdl","vim","visual-basic","warpscript","wasm","wiki","xeora","xml-doc","xojo","xquery","yaml","yang","zig"];var gf=go(gc(),gs);gf.supportedLanguages=gl;let gd=gf;var gh=n(64566);function gp(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function gb(){var e=gp(["\n query FetchConfigV2 {\n configv2 {\n user\n effective\n }\n }\n"]);return gb=function(){return e},e}var gm=n0(gb()),gg=function(e){var t=e.children;return l.createElement(ir.Z,null,l.createElement(r7.default,{component:"th",scope:"row",colSpan:3},t))},gv=function(){return l.createElement(gg,null,"...")},gy=function(e){var t=e.children;return l.createElement(gg,null,t)},gw=function(e){var t=e.loading,n=e.toml,r=e.error,i=void 0===r?"":r,a=e.title,o=e.expanded;if(i)return l.createElement(gy,null,i);if(t)return l.createElement(gv,null);a||(a="TOML");var s={display:"block"};return l.createElement(x.default,null,l.createElement(mP.Z,{defaultExpanded:o},l.createElement(mR.Z,{expandIcon:l.createElement(gh.Z,null)},a),l.createElement(mj.Z,{style:s},l.createElement(gd,{language:"toml",style:gs},n))))},g_=function(){var e=rv(gm,{fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return(null==t?void 0:t.configv2.effective)=="N/A"?l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"TOML Configuration"}),l.createElement(gw,{title:"V2 config dump:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0})))):l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"TOML Configuration"}),l.createElement(gw,{title:"User specified:",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.user,showHead:!0,expanded:!0}),l.createElement(gw,{title:"Effective (with defaults):",error:null==r?void 0:r.message,loading:n,toml:null==t?void 0:t.configv2.effective,showHead:!0})))))},gE=n(34823),gS=function(e){return(0,b.createStyles)({cell:{paddingTop:1.5*e.spacing.unit,paddingBottom:1.5*e.spacing.unit}})},gk=(0,b.withStyles)(gS)(function(e){var t=e.classes,n=(0,A.I0)();(0,l.useEffect)(function(){n((0,ty.DQ)())});var r=(0,A.v9)(gE.N,A.wU);return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Node"}),l.createElement(r8.Z,null,l.createElement(r9.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,{className:t.cell},l.createElement(x.default,null,"Version"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.version))),l.createElement(ir.Z,null,l.createElement(r7.default,{className:t.cell},l.createElement(x.default,null,"SHA"),l.createElement(x.default,{variant:"subtitle1",color:"textSecondary"},r.commitSHA))))))}),gx=function(){return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,sm:12,md:8},l.createElement(d.Z,{container:!0},l.createElement(g_,null))),l.createElement(d.Z,{item:!0,sm:12,md:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gk,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mN,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(mE,null))))))},gT=function(){return l.createElement(gx,null)},gM=function(){return l.createElement(gT,null)},gO=n(44431),gA=1e18,gL=function(e){return new gO.BigNumber(e).dividedBy(gA).toFixed(8)},gC=function(e){var t=e.keys,n=e.chainID,r=e.hideHeaderTitle;return l.createElement(l.Fragment,null,l.createElement(sl.Z,{title:!r&&"Account Balances",subheader:"Chain ID "+n}),l.createElement(aW.Z,null,l.createElement(w.default,{dense:!1,disablePadding:!0},t&&t.map(function(e,r){return l.createElement(l.Fragment,null,l.createElement(_.default,{disableGutters:!0,key:["acc-balance",n.toString(),r.toString()].join("-")},l.createElement(E.Z,{primary:l.createElement(l.Fragment,null,l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(op,{title:"Address"}),l.createElement(ob,{value:e.address})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(op,{title:"Native Token Balance"}),l.createElement(ob,{value:e.ethBalance||"--"})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(op,{title:"LINK Balance"}),l.createElement(ob,{value:e.linkBalance?gL(e.linkBalance):"--"}))))})),r+1s&&l.createElement(gB.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,{className:r.footer},l.createElement(aA.Z,{href:"/runs",component:tz},"View More"))))))});function vt(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vn(){var e=vt(["\n ","\n query FetchRecentJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...RecentJobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return vn=function(){return e},e}var vr=5,vi=n0(vn(),g9),va=function(){var e=rv(vi,{variables:{offset:0,limit:vr},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(ve,{data:t,errorMsg:null==r?void 0:r.message,loading:n,maxRunsSize:vr})},vo=function(e){return(0,b.createStyles)({style:{textAlign:"center",padding:2.5*e.spacing.unit,position:"fixed",left:"0",bottom:"0",width:"100%",borderRadius:0},bareAnchor:{color:e.palette.common.black,textDecoration:"none"}})},vs=(0,b.withStyles)(vo)(function(e){var t=e.classes,n=(0,A.v9)(gE.N,A.wU),r=(0,A.I0)();return(0,l.useEffect)(function(){r((0,ty.DQ)())}),l.createElement(ii.default,{className:t.style},l.createElement(x.default,null,"Chainlink Node ",n.version," at commit"," ",l.createElement("a",{target:"_blank",rel:"noopener noreferrer",href:"https://github.com/smartcontractkit/chainlink/commit/".concat(n.commitSHA),className:t.bareAnchor},n.commitSHA)))}),vu=function(e){return(0,b.createStyles)({cell:{borderColor:e.palette.divider,borderTop:"1px solid",borderBottom:"none",paddingTop:2*e.spacing.unit,paddingBottom:2*e.spacing.unit,paddingLeft:2*e.spacing.unit},block:{display:"block"},overflowEllipsis:{textOverflow:"ellipsis",overflow:"hidden"}})},vc=(0,b.withStyles)(vu)(function(e){var t=e.classes,n=e.job;return l.createElement(ir.Z,null,l.createElement(r7.default,{scope:"row",className:t.cell},l.createElement(d.Z,{container:!0,spacing:0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(ih,{href:"/jobs/".concat(n.id),classes:{linkContent:t.block}},l.createElement(x.default,{className:t.overflowEllipsis,variant:"body1",component:"span",color:"primary"},n.name||n.id))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,{variant:"body1",color:"textSecondary"},"Created ",l.createElement(aO,{tooltip:!0},n.createdAt))))))});function vl(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vf(){var e=vl(["\n fragment RecentJobsPayload_ResultsFields on Job {\n id\n name\n createdAt\n }\n"]);return vf=function(){return e},e}var vd=n0(vf()),vh=function(){return(0,b.createStyles)({cardHeader:{borderBottom:0},table:{tableLayout:"fixed"}})},vp=(0,b.withStyles)(vh)(function(e){var t,n,r=e.classes,i=e.data,a=e.errorMsg,o=e.loading;return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Recent Jobs",className:r.cardHeader}),l.createElement(r8.Z,{className:r.table},l.createElement(r9.Z,null,l.createElement(g$,{visible:o}),l.createElement(gz,{visible:(null===(t=null==i?void 0:i.jobs.results)||void 0===t?void 0:t.length)===0},"No recently created jobs"),l.createElement(gU,{msg:a}),null===(n=null==i?void 0:i.jobs.results)||void 0===n?void 0:n.map(function(e,t){return l.createElement(vc,{job:e,key:t})}))))});function vb(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function vm(){var e=vb(["\n ","\n query FetchRecentJobs($offset: Int, $limit: Int) {\n jobs(offset: $offset, limit: $limit) {\n results {\n ...RecentJobsPayload_ResultsFields\n }\n }\n }\n"]);return vm=function(){return e},e}var vg=5,vv=n0(vm(),vd),vy=function(){var e=rv(vv,{variables:{offset:0,limit:vg},fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error;return l.createElement(vp,{data:t,errorMsg:null==r?void 0:r.message,loading:n})},vw=function(){return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:8},l.createElement(va,null)),l.createElement(d.Z,{item:!0,xs:4},l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12},l.createElement(gY,null)),l.createElement(d.Z,{item:!0,xs:12},l.createElement(vy,null))))),l.createElement(vs,null))},v_=function(){return l.createElement(vw,null)},vE=function(){return l.createElement(v_,null)},vS=n(87239),vk=function(e){switch(e){case"DirectRequestSpec":return"Direct Request";case"FluxMonitorSpec":return"Flux Monitor";default:return e.replace(/Spec$/,"")}},vx=n(5022),vT=n(78718),vM=n.n(vT);function vO(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1?t-1:0),r=1;r1?t-1:0),r=1;re.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&n.map(function(e){return l.createElement(ir.Z,{key:e.id,style:{cursor:"pointer"},onClick:function(){return r.push("/runs/".concat(e.id))}},l.createElement(r7.default,{className:t.idCell,scope:"row"},l.createElement("div",{className:t.runDetails},l.createElement(x.default,{variant:"h5",color:"primary",component:"span"},e.id))),l.createElement(r7.default,{className:t.stampCell},l.createElement(x.default,{variant:"body1",color:"textSecondary",className:t.stamp},"Created ",l.createElement(aO,{tooltip:!0},e.createdAt))),l.createElement(r7.default,{className:t.statusCell,scope:"row"},l.createElement(x.default,{variant:"body1",className:O()(t.status,yh(t,e.status))},e.status.toLowerCase())))})))}),yb=n(16839),ym=n.n(yb);function yg(e){var t=e.replace(/\w+\s*=\s*<([^>]|[\r\n])*>/g,""),n=ym().read(t),r=n.edges();return n.nodes().map(function(e){var t={id:e,parentIds:r.filter(function(t){return t.w===e}).map(function(e){return e.v})};return Object.keys(n.node(e)).length>0&&(t.attributes=n.node(e)),t})}var yv=n(94164),yy=function(e){var t=e.data,n=[];return(null==t?void 0:t.attributes)&&Object.keys(t.attributes).forEach(function(e){var r;n.push(l.createElement("div",{key:e},l.createElement(x.default,{variant:"body1",color:"textSecondary",component:"div"},l.createElement("b",null,e,":")," ",null===(r=t.attributes)||void 0===r?void 0:r[e])))}),l.createElement("div",null,t&&l.createElement(x.default,{variant:"body1",color:"textPrimary"},l.createElement("b",null,t.id)),n)},yw=n(73343),y_=n(3379),yE=n.n(y_);function yS(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nwindow.innerWidth?u-r.getBoundingClientRect().width-a:u+a,n=c+r.getBoundingClientRect().height+i>window.innerHeight?c-r.getBoundingClientRect().height-a:c+a,r.style.opacity=String(1),r.style.top="".concat(n,"px"),r.style.left="".concat(t,"px"),r.style.zIndex=String(1)}},h=function(e){var t=document.getElementById("tooltip-d3-chart-".concat(e));t&&(t.style.opacity=String(0),t.style.zIndex=String(-1))};return l.createElement("div",{style:{fontFamily:"sans-serif",fontWeight:"normal"}},l.createElement(yv.kJ,{id:"task-list-graph-d3",data:i,config:s,onMouseOverNode:d,onMouseOutNode:h},"D3 chart"),n.map(function(e){return l.createElement("div",{key:"d3-tooltip-key-".concat(e.id),id:"tooltip-d3-chart-".concat(e.id),style:{position:"absolute",opacity:"0",border:"1px solid rgba(0, 0, 0, 0.1)",padding:yw.r.spacing.unit,background:"white",borderRadius:5,zIndex:-1,inlineSize:"min-content"}},l.createElement(yy,{data:e}))}))};function yL(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nyY&&l.createElement("div",{className:t.runDetails},l.createElement(aA.Z,{href:"/jobs/".concat(n.id,"/runs"),component:tz},"View more")))),l.createElement(d.Z,{item:!0,xs:12,sm:6},l.createElement(yF,{observationSource:n.observationSource})))});function yH(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&void 0!==arguments[0]?arguments[0]:"";try{return vx.parse(e),!0}catch(t){return!1}})}),wW=function(e){var t=e.initialValues,n=e.onSubmit,r=e.onTOMLChange;return l.createElement(hT,{initialValues:t,validationSchema:wG,onSubmit:n},function(e){var t=e.isSubmitting,n=e.values;return r&&r(n.toml),l.createElement(hR,{"data-testid":"job-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"toml",name:"toml",label:"Job Spec (TOML)",required:!0,fullWidth:!0,multiline:!0,rows:10,rowsMax:25,variant:"outlined",autoComplete:"off",FormHelperTextProps:{"data-testid":"toml-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",disabled:t,size:"large"},"Create Job"))))})},wK=n(50109),wV="persistSpec";function wq(e){var t=e.query,n=new URLSearchParams(t).get("definition");return n?(wK.t8(wV,n),{toml:n}):{toml:wK.U2(wV)||""}}var wZ=function(e){var t=e.onSubmit,n=e.onTOMLChange,r=wq({query:(0,h.TH)().search}),i=function(e){var t=e.replace(/[\u200B-\u200D\uFEFF]/g,"");wK.t8("".concat(wV),t),n&&n(t)};return l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"New Job"}),l.createElement(aW.Z,null,l.createElement(wW,{initialValues:r,onSubmit:t,onTOMLChange:i})))};function wX(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n1&&void 0!==arguments[1]?arguments[1]:{},n=t.start,r=void 0===n?6:n,i=t.end,a=void 0===i?4:i;return e.substring(0,r)+"..."+e.substring(e.length-a)}function _M(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(_W,e)},_V=function(){var e=_K({fetchPolicy:"cache-and-network"}),t=e.data,n=e.loading,r=e.error,i=e.refetch;return l.createElement(_U,{loading:n,data:t,errorMsg:null==r?void 0:r.message,refetch:i})},_q=function(e){var t=e.csaKey;return l.createElement(ir.Z,{hover:!0},l.createElement(r7.default,null,l.createElement(x.default,{variant:"body1"},t.publicKey," ",l.createElement(_x,{data:t.publicKey}))))};function _Z(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function _X(){var e=_Z(["\n fragment CSAKeysPayload_ResultsFields on CSAKey {\n id\n publicKey\n }\n"]);return _X=function(){return e},e}var _J=n0(_X()),_Q=function(e){var t,n,r,i=e.data,a=e.errorMsg,o=e.loading,s=e.onCreate;return l.createElement(r5.Z,null,l.createElement(sl.Z,{action:(null===(t=null==i?void 0:i.csaKeys.results)||void 0===t?void 0:t.length)===0&&l.createElement(ok.default,{variant:"outlined",color:"primary",onClick:s},"New CSA Key"),title:"CSA Key",subheader:"Manage your CSA Key"}),l.createElement(r8.Z,null,l.createElement(ie.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,null,"Public Key"))),l.createElement(r9.Z,null,l.createElement(g$,{visible:o}),l.createElement(gz,{visible:(null===(n=null==i?void 0:i.csaKeys.results)||void 0===n?void 0:n.length)===0}),l.createElement(gU,{msg:a}),null===(r=null==i?void 0:i.csaKeys.results)||void 0===r?void 0:r.map(function(e,t){return l.createElement(_q,{csaKey:e,key:t})}))))};function _1(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(EM,e)};function EA(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(EJ,e)},E3=function(){return oo(EQ)},E4=function(){return oo(E1)},E6=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return rv(E0,e)};function E5(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(SK,e)};function Sq(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function kV(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}var kq=function(e){var t=e.run,n=l.useMemo(function(){var e=t.inputs,n=t.outputs,r=t.taskRuns,i=kK(t,["inputs","outputs","taskRuns"]),a={};try{a=JSON.parse(e)}catch(o){a={}}return kW(kz({},i),{inputs:a,outputs:n,taskRuns:r})},[t]);return l.createElement(r5.Z,null,l.createElement(aW.Z,null,l.createElement(kH,{object:n})))};function kZ(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function kX(e){for(var t=1;t0&&l.createElement(kr,{errors:t.allErrors})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(h.rs,null,l.createElement(h.AW,{path:"".concat(n,"/json")},l.createElement(kq,{run:t})),l.createElement(h.AW,{path:n},t.taskRuns.length>0&&l.createElement(kN,{taskRuns:t.taskRuns,observationSource:t.job.observationSource}))))))))};function k5(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function k8(){var e=k5(["\n ","\n query FetchJobRun($id: ID!) {\n jobRun(id: $id) {\n __typename\n ... on JobRun {\n ...JobRunPayload_Fields\n }\n ... on NotFoundError {\n message\n }\n }\n }\n"]);return k8=function(){return e},e}var k9=n0(k8(),k4),k7=function(){var e=rv(k9,{variables:{id:(0,h.UO)().id}}),t=e.data,n=e.loading,r=e.error;if(n)return l.createElement(iR,null);if(r)return l.createElement(iD,{error:r});var i=null==t?void 0:t.jobRun;switch(null==i?void 0:i.__typename){case"JobRun":return l.createElement(k6,{run:i});case"NotFoundError":return l.createElement(oa,null);default:return null}};function xe(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xt(){var e=xe(["\n fragment JobRunsPayload_ResultsFields on JobRun {\n id\n allErrors\n createdAt\n finishedAt\n status\n job {\n id\n }\n }\n"]);return xt=function(){return e},e}var xn=n0(xt()),xr=function(e){var t=e.loading,n=e.data,r=e.page,i=e.pageSize,a=(0,h.k6)(),o=l.useMemo(function(){return null==n?void 0:n.jobRuns.results.map(function(e){var t,n=e.allErrors,r=e.id,i=e.createdAt;return{id:r,createdAt:i,errors:n,finishedAt:e.finishedAt,status:e.status}})},[n]);return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(iy,null,"Job Runs")),t&&l.createElement(iR,null),n&&o&&l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(yp,{runs:o}),l.createElement(it.Z,{component:"div",count:n.jobRuns.metadata.total,rowsPerPage:i,rowsPerPageOptions:[i],page:r-1,onChangePage:function(e,t){a.push("/runs?page=".concat(t+1,"&per=").concat(i))},onChangeRowsPerPage:function(){},backIconButtonProps:{"aria-label":"prev-page"},nextIconButtonProps:{"aria-label":"next-page"}})))))};function xi(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xa(){var e=xi(["\n ","\n query FetchJobRuns($offset: Int, $limit: Int) {\n jobRuns(offset: $offset, limit: $limit) {\n results {\n ...JobRunsPayload_ResultsFields\n }\n metadata {\n total\n }\n }\n }\n"]);return xa=function(){return e},e}var xo=n0(xa(),xn),xs=function(){var e=ij(),t=parseInt(e.get("page")||"1",10),n=parseInt(e.get("per")||"25",10),r=rv(xo,{variables:{offset:(t-1)*n,limit:n},fetchPolicy:"cache-and-network"}),i=r.data,a=r.loading,o=r.error;return o?l.createElement(iD,{error:o}):l.createElement(xr,{loading:a,data:i,page:t,pageSize:n})},xu=function(){var e=(0,h.$B)().path;return l.createElement(h.rs,null,l.createElement(h.AW,{exact:!0,path:e},l.createElement(xs,null)),l.createElement(h.AW,{path:"".concat(e,"/:id")},l.createElement(k7,null)))};function xc(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function xl(){var e=xc(["\n fragment FetchFeedsManagersPayload_ResultsFields on FeedsManager {\n __typename\n id\n name\n uri\n publicKey\n isConnectionActive\n createdAt\n disabledAt\n }\n query FetchFeedsManagers {\n feedsManagers {\n results {\n ...FetchFeedsManagersPayload_ResultsFields\n }\n }\n }\n"]);return xl=function(){return e},e}var xf=n0(xl()),xd=function(e){return rv(xf,e)},xh=n(47559),xp=n(83165),xb=n(47298),xm=n(81395),xg=function(){return(0,b.createStyles)({root:{display:"flex"},activeIcon:{color:xh.default[500]},inactiveIcon:{color:xp.default[500]},text:{marginLeft:4}})},xv=(0,b.withStyles)(xg)(function(e){var t=e.isActive,n=e.activeText,r=e.inactiveText,i=e.classes;return l.createElement("div",{className:i.root},t?l.createElement(xm.Z,{fontSize:"small",className:i.activeIcon}):l.createElement(xb.Z,{fontSize:"small",className:i.inactiveIcon}),l.createElement(x.default,{variant:"body1",inline:!0,className:i.text},t?n:r))}),xy=(0,b.withStyles)(iu)(function(e){var t=e.jobDistributor,n=e.classes;return l.createElement(ir.Z,{className:n.row,hover:!0},l.createElement(r7.default,{className:n.cell,component:"th",scope:"row"},l.createElement(ih,{className:n.link,href:"/job_distributors/".concat(t.id)},t.name)),l.createElement(r7.default,null,l.createElement(xv,{isActive:t.isConnectionActive,activeText:"Connected",inactiveText:"Disconnected"})),l.createElement(r7.default,null,l.createElement(xv,{isActive:!t.disabledAt,activeText:"Enabled",inactiveText:"Disabled"})),l.createElement(r7.default,null,_T(t.publicKey,{start:6,end:6}),l.createElement(_x,{data:t.publicKey})),l.createElement(r7.default,null,t.uri))}),xw=function(e){var t=e.jobDistributors;return l.createElement(ig,null,l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:9},l.createElement(iy,null,"Job Distributors")),l.createElement(d.Z,{item:!0,xs:3},l.createElement(d.Z,{container:!0,justify:"flex-end"},l.createElement(d.Z,{item:!0},l.createElement(aA.Z,{variant:"secondary",component:tz,href:"/job_distributors/new"},"New Job Distributor")))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(r5.Z,null,l.createElement(r8.Z,null,l.createElement(ie.Z,null,l.createElement(ir.Z,null,l.createElement(r7.default,null,"Name"),l.createElement(r7.default,null,"Connection Status"),l.createElement(r7.default,null,"Status"),l.createElement(r7.default,null,"CSA Public Key"),l.createElement(r7.default,null,"RPC URL"))),l.createElement(r9.Z,null,0===t.length&&l.createElement(ir.Z,null,l.createElement(r7.default,{component:"th",scope:"row",colSpan:3},"Job Distributors have not been registered")),t.map(function(e){return l.createElement(xy,{key:e.id,jobDistributor:e})})))))))},x_=function(){var e,t=xd({fetchPolicy:"cache-and-network"}),n=t.data,r=t.loading,i=t.error;return r?l.createElement(iR,null):i?l.createElement(iD,{error:i}):l.createElement(xw,{jobDistributors:null!==(e=null==n?void 0:n.feedsManagers.results)&&void 0!==e?e:[]})},xE=bv().shape({name:p0().required("Required"),uri:p0().required("Required"),publicKey:p0().required("Required")}),xS=function(e){var t=e.initialValues,n=e.onSubmit;return l.createElement(hT,{initialValues:t,validationSchema:xE,onSubmit:n},function(e){var t=e.isSubmitting,n=e.submitForm;return l.createElement(hR,{"data-testid":"feeds-manager-form"},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"name",name:"name",label:"Name",required:!0,fullWidth:!0,FormHelperTextProps:{"data-testid":"name-helper-text"}})),l.createElement(d.Z,{item:!0,xs:!1,md:6}),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"uri",name:"uri",label:"URI",required:!0,fullWidth:!0,helperText:"Provided by the Job Distributor operator",FormHelperTextProps:{"data-testid":"uri-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"publicKey",name:"publicKey",label:"Public Key",required:!0,fullWidth:!0,helperText:"Provided by the Job Distributor operator",FormHelperTextProps:{"data-testid":"publicKey-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(ok.default,{variant:"contained",color:"primary",disabled:t,onClick:n},"Submit"))))})},xk=function(e){var t=e.data,n=e.onSubmit,r={name:t.name,uri:t.uri,publicKey:t.publicKey};return l.createElement(d.Z,{container:!0},l.createElement(d.Z,{item:!0,xs:12,md:11,lg:9},l.createElement(r5.Z,null,l.createElement(sl.Z,{title:"Edit Job Distributor"}),l.createElement(aW.Z,null,l.createElement(xS,{initialValues:r,onSubmit:n})))))};function xx(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&void 0!==arguments[0]?arguments[0]:{};return rv(xZ,e)},xJ=function(){return(0,b.createStyles)({root:{fontSize:24}})},xQ=(0,b.withStyles)(xJ)(function(e){var t=e.children,n=e.classes;return l.createElement(x.default,{variant:"h2",className:n.root},t)}),x1=n(9290),x0=n(74923);function x2(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function TT(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}function TM(e,t){return Tv(e)||TE(e,t)||TA(e,t)||TS()}function TO(e){return Ty(e)||T_(e)||TA(e)||Tk()}function TA(e,t){if(e){if("string"==typeof e)return Tg(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Tg(e,t)}}var TL=function(e){return"SN_MAIN"===e||"SN_SEPOLIA"===e},TC=bv().shape({chainID:p0().required("Required"),chainType:p0().required("Required"),accountAddr:p0().required("Required"),accountAddrPubKey:p0().nullable(),adminAddr:p0(),ocr1Multiaddr:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&t},then:p0().required("Required").nullable()}).nullable(),ocr1P2PPeerID:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr1KeyBundleID:p0().when(["ocr1Enabled","ocr1IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2Multiaddr:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&t},then:p0().required("Required").nullable()}).nullable(),ocr2P2PPeerID:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2KeyBundleID:p0().when(["ocr2Enabled","ocr2IsBootstrap"],{is:function(e,t){return e&&!t},then:p0().required("Required").nullable()}).nullable(),ocr2CommitPluginEnabled:pV().required("Required"),ocr2ExecutePluginEnabled:pV().required("Required"),ocr2MedianPluginEnabled:pV().required("Required"),ocr2MercuryPluginEnabled:pV().required("Required"),ocr2ForwarderAddress:p0().nullable()}),TI=function(e){return(0,b.createStyles)({supportedJobOptionsPaper:{padding:2*e.spacing.unit}})},TD=function(e){var t=e.addresses,n=Tx(e,["addresses"]),r=h_(),i=r.values,a=i.chainID,o=i.accountAddr,s=r.setFieldValue,u=TM(l.useState(!1),2),c=u[0],f=u[1],d=l.useRef();l.useEffect(function(){d.current=a},[a]),l.useEffect(function(){a!==d.current&&(s(n.name,""),f(!1))},[a,s,n.name]);var h=function(e){var t=e.target.value;"custom"===t?(f(!0),s(n.name,"")):(f(!1),s(n.name,t))};return l.createElement(l.Fragment,null,!TL(a)&&l.createElement(hP,Tw({},n,{select:!0,value:c?"custom":o,onChange:h}),t.map(function(e){return l.createElement(tE.default,{key:e,value:e},e)})),TL(a)&&l.createElement(hP,{component:hX,id:"accountAddr",name:"accountAddr",label:"Enter your account address",inputProps:{"data-testid":"customAccountAddr-input"},helperText:"The account address used for this chain",required:!0,fullWidth:!0}),TL(a)&&l.createElement("div",null,l.createElement(hP,{component:hX,id:"accountAddrPubKey",name:"accountAddrPubKey",label:"Account Address Public Key",required:!0,fullWidth:!0,helperText:"The public key for your account address",FormHelperTextProps:{"data-testid":"accountAddrPubKey-helper-text"}})))},TN=(0,b.withStyles)(TI)(function(e){var t=e.classes,n=e.editing,r=void 0!==n&&n,i=e.innerRef,a=e.initialValues,o=e.onSubmit,s=e.chains,u=void 0===s?[]:s,c=e.accountsEVM,f=void 0===c?[]:c,h=e.accountsNonEvm,p=e.p2pKeys,b=void 0===p?[]:p,m=e.ocrKeys,g=void 0===m?[]:m,v=e.ocr2Keys,y=void 0===v?[]:v,w=e.showSubmit,_=void 0!==w&&w,E=TO(y).sort(function(e,t){var n,r,i;return e.chainType===t.chainType?e.id.localeCompare(t.id):null!==(i=null===(n=e.chainType)||void 0===n?void 0:n.localeCompare(null!==(r=t.chainType)&&void 0!==r?r:""))&&void 0!==i?i:0});return l.createElement(hT,{innerRef:i,initialValues:a,validationSchema:TC,onSubmit:o},function(e){var n,i,a=e.values,o=[];switch(a.chainType){case Tm.EVM:o=f.filter(function(e){return e.chain.id==a.chainID&&!e.isDisabled}).map(function(e){return e.address});break;case Tm.APTOS:o=null!==(n=null==h?void 0:h.aptosKeys.results.map(function(e){return e.account}))&&void 0!==n?n:[];break;case Tm.SOLANA:o=null!==(i=null==h?void 0:h.solanaKeys.results.map(function(e){return e.id}))&&void 0!==i?i:[];break;default:o=[]}var s=u.filter(function(e){return e.network.toUpperCase()===a.chainType});return l.createElement(hR,{"data-testid":"feeds-manager-form",id:"chain-configuration-form",noValidate:!0},l.createElement(d.Z,{container:!0,spacing:16},l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"chainType",name:"chainType",label:"Chain Type",select:!0,required:!0,fullWidth:!0,disabled:r},l.createElement(tE.default,{key:Tm.EVM,value:Tm.EVM},"EVM"),l.createElement(tE.default,{key:Tm.APTOS,value:Tm.APTOS},"APTOS"),l.createElement(tE.default,{key:Tm.SOLANA,value:Tm.SOLANA},"SOLANA"))),l.createElement(d.Z,{item:!0,xs:12,md:6},s.length>0&&!r?l.createElement(hP,{component:hX,id:"chainID",name:"chainID",label:"Chain ID",required:!0,fullWidth:!0,select:!0,disabled:r,inputProps:{"data-testid":"chainID-input"},FormHelperTextProps:{"data-testid":"chainID-helper-text"}},s.map(function(e){return l.createElement(tE.default,{key:e.id,value:e.id},e.id)})):l.createElement(hP,{component:hX,id:"chainID",name:"chainID",label:"Chain ID",required:!0,fullWidth:!0,disabled:r,inputProps:{"data-testid":"chainID-manual-input"},FormHelperTextProps:{"data-testid":"chainID-helper-manual-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},o.length>0?l.createElement(TD,{component:hX,id:"accountAddr",name:"accountAddr",label:"Account Address",inputProps:{"data-testid":"accountAddr-input"},required:!0,fullWidth:!0,select:!0,helperText:"The account address used for this chain",addresses:o,FormHelperTextProps:{"data-testid":"accountAddr-helper-text"}}):l.createElement(hP,{component:hX,id:"accountAddr",name:"accountAddr",label:"Account Address",inputProps:{"data-testid":"accountAddr-manual-input"},required:!0,fullWidth:!0,helperText:"The account address used for this chain",FormHelperTextProps:{"data-testid":"accountAddr-helper-manual-text"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"adminAddr",name:"adminAddr",label:"Admin Address",fullWidth:!0,helperText:"The address used for LINK payments",FormHelperTextProps:{"data-testid":"adminAddr-helper-text"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,null,"Supported Job Types")),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"fluxMonitorEnabled",type:"checkbox",Label:{label:"Flux Monitor"}})),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr1Enabled",type:"checkbox",Label:{label:"OCR"}}),a.ocr1Enabled&&l.createElement(ii.default,{className:t.supportedJobOptionsPaper},l.createElement(d.Z,{container:!0,spacing:8},l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr1IsBootstrap",type:"checkbox",Label:{label:"Is this node running as a bootstrap peer?"}})),a.ocr1IsBootstrap?l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"ocr1Multiaddr",name:"ocr1Multiaddr",label:"Multiaddr",required:!0,fullWidth:!0,helperText:"The OCR Multiaddr which oracles use to query for network information",FormHelperTextProps:{"data-testid":"ocr1Multiaddr-helper-text"}})):l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr1P2PPeerID",name:"ocr1P2PPeerID",label:"Peer ID",select:!0,required:!0,fullWidth:!0,helperText:"The Peer ID used for this chain",FormHelperTextProps:{"data-testid":"ocr1P2PPeerID-helper-text"}},b.map(function(e){return l.createElement(tE.default,{key:e.peerID,value:e.peerID},e.peerID)}))),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr1KeyBundleID",name:"ocr1KeyBundleID",label:"Key Bundle ID",select:!0,required:!0,fullWidth:!0,helperText:"The OCR Key Bundle ID used for this chain",FormHelperTextProps:{"data-testid":"ocr1KeyBundleID-helper-text"}},g.map(function(e){return l.createElement(tE.default,{key:e.id,value:e.id},e.id)})))))))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr2Enabled",type:"checkbox",Label:{label:"OCR2"}}),a.ocr2Enabled&&l.createElement(ii.default,{className:t.supportedJobOptionsPaper},l.createElement(d.Z,{container:!0,spacing:8},l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:h2,name:"ocr2IsBootstrap",type:"checkbox",Label:{label:"Is this node running as a bootstrap peer?"}})),l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr2P2PPeerID",name:"ocr2P2PPeerID",label:"Peer ID",select:!0,required:!a.ocr2IsBootstrap,fullWidth:!0,helperText:"The Peer ID used for this chain",FormHelperTextProps:{"data-testid":"ocr2P2PPeerID-helper-text"}},b.map(function(e){return l.createElement(tE.default,{key:e.peerID,value:e.peerID},e.peerID)}))),a.ocr2IsBootstrap?l.createElement(d.Z,{item:!0,xs:12},l.createElement(hP,{component:hX,id:"ocr2Multiaddr",name:"ocr2Multiaddr",label:"Multiaddr",required:!0,fullWidth:!0,helperText:"The OCR2 Multiaddr which oracles use to query for network information",FormHelperTextProps:{"data-testid":"ocr2Multiaddr-helper-text"}})):l.createElement(l.Fragment,null,l.createElement(d.Z,{item:!0,xs:12,md:6},l.createElement(hP,{component:hX,id:"ocr2KeyBundleID",name:"ocr2KeyBundleID",label:"Key Bundle ID",select:!0,required:!0,fullWidth:!0,helperText:"The OCR2 Key Bundle ID used for this chain",FormHelperTextProps:{"data-testid":"ocr2KeyBundleID-helper-text"}},E.map(function(e){return l.createElement(tE.default,{key:e.id,value:e.id},e.id," (",e.chainType,")")}))),l.createElement(d.Z,{item:!0,xs:12},l.createElement(x.default,null,"Supported Plugins")),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2CommitPluginEnabled",type:"checkbox",Label:{label:"Commit"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2ExecutePluginEnabled",type:"checkbox",Label:{label:"Execute"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2RebalancerPluginEnabled",type:"checkbox",Label:{label:"Rebalancer"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2MedianPluginEnabled",type:"checkbox",Label:{label:"Median"}})),l.createElement(d.Z,{item:!0,xs:6},l.createElement(hP,{component:h2,name:"ocr2MercuryPluginEnabled",type:"checkbox",Label:{label:"Mercury"}})),l.createElement(d.Z,{item:!0,xs:12,md:12},l.createElement(hP,{component:hX,id:"ocr2ForwarderAddress",name:"ocr2ForwarderAddress",label:"Forwarder Address (optional)",fullWidth:!0,helperText:"The forwarder address from the Operator Forwarder Contract",FormHelperTextProps:{"data-testid":"ocr2ForwarderAddress-helper-text"}}))))))),_&&l.createElement(d.Z,{item:!0,xs:12,md:7},l.createElement(ok.default,{variant:"contained",color:"primary",type:"submit",size:"large"},"Submit"))))})});function TP(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function TR(){var e=TP(["\n fragment AptosKeysPayload_ResultsFields on AptosKey {\n account\n id\n }\n"]);return TR=function(){return e},e}function Tj(){var e=TP(["\n fragment SolanaKeysPayload_ResultsFields on SolanaKey {\n id\n }\n"]);return Tj=function(){return e},e}function TF(){var e=TP(["\n ","\n ","\n query FetchNonEvmKeys {\n aptosKeys {\n results {\n ...AptosKeysPayload_ResultsFields\n }\n }\n solanaKeys {\n results {\n ...SolanaKeysPayload_ResultsFields\n }\n }\n }\n"]);return TF=function(){return e},e}var TY=n0(TR()),TB=n0(Tj()),TU=n0(TF(),TY,TB),TH=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return rv(TU,e)},T$=function(e){var t=e.onClose,n=e.open,r=e.onSubmit,i=l.useRef(),a=i$({fetchPolicy:"network-only"}).data,o=_K({fetchPolicy:"cache-and-network"}).data,s=TH({fetchPolicy:"cache-and-network"}).data,u=SV({fetchPolicy:"cache-and-network"}).data,c=EO({fetchPolicy:"cache-and-network"}).data,f=E2({fetchPolicy:"cache-and-network"}).data,d={chainID:"",chainType:Tm.EVM,accountAddr:"",adminAddr:"",accountAddrPubKey:"",fluxMonitorEnabled:!1,ocr1Enabled:!1,ocr1IsBootstrap:!1,ocr1Multiaddr:"",ocr1P2PPeerID:"",ocr1KeyBundleID:"",ocr2Enabled:!1,ocr2IsBootstrap:!1,ocr2Multiaddr:"",ocr2P2PPeerID:"",ocr2KeyBundleID:"",ocr2CommitPluginEnabled:!1,ocr2ExecutePluginEnabled:!1,ocr2MedianPluginEnabled:!1,ocr2MercuryPluginEnabled:!1,ocr2RebalancerPluginEnabled:!1,ocr2ForwarderAddress:""},h=a?a.chains.results:[],p=o?o.ethKeys.results:[],b=u?u.p2pKeys.results:[],m=c?c.ocrKeyBundles.results:[],g=f?f.ocr2KeyBundles.results:[];return l.createElement(aD.Z,{onClose:t,open:n,disableBackdropClick:!0},l.createElement(oO.Z,{disableTypography:!0},l.createElement(x.default,{variant:"body2"},"New Supported Chain")),l.createElement(oT.Z,null,l.createElement(TN,{innerRef:i,initialValues:d,onSubmit:r,chains:h,accountsEVM:p,accountsNonEvm:s,p2pKeys:b,ocrKeys:m,ocr2Keys:g})),l.createElement(ox.Z,null,l.createElement(ok.default,{onClick:t},"Cancel"),l.createElement(ok.default,{color:"primary",type:"submit",form:"chain-configuration-form",variant:"contained"},"Submit")))},Tz=function(e){var t=e.cfg,n=e.onClose,r=e.open,i=e.onSubmit,a=l.useRef(),o=i$({fetchPolicy:"network-only"}).data,s=_K({fetchPolicy:"cache-and-network"}).data,u=TH({fetchPolicy:"cache-and-network"}).data,c=SV({fetchPolicy:"cache-and-network"}).data,f=EO({fetchPolicy:"cache-and-network"}).data,d=E2({fetchPolicy:"cache-and-network"}).data;if(!t)return null;var h={chainID:t.chainID,chainType:t.chainType,accountAddr:t.accountAddr,adminAddr:t.adminAddr,accountAddrPubKey:t.accountAddrPubKey,fluxMonitorEnabled:t.fluxMonitorJobConfig.enabled,ocr1Enabled:t.ocr1JobConfig.enabled,ocr1IsBootstrap:t.ocr1JobConfig.isBootstrap,ocr1Multiaddr:t.ocr1JobConfig.multiaddr,ocr1P2PPeerID:t.ocr1JobConfig.p2pPeerID,ocr1KeyBundleID:t.ocr1JobConfig.keyBundleID,ocr2Enabled:t.ocr2JobConfig.enabled,ocr2IsBootstrap:t.ocr2JobConfig.isBootstrap,ocr2Multiaddr:t.ocr2JobConfig.multiaddr,ocr2P2PPeerID:t.ocr2JobConfig.p2pPeerID,ocr2KeyBundleID:t.ocr2JobConfig.keyBundleID,ocr2CommitPluginEnabled:t.ocr2JobConfig.plugins.commit,ocr2ExecutePluginEnabled:t.ocr2JobConfig.plugins.execute,ocr2MedianPluginEnabled:t.ocr2JobConfig.plugins.median,ocr2MercuryPluginEnabled:t.ocr2JobConfig.plugins.mercury,ocr2RebalancerPluginEnabled:t.ocr2JobConfig.plugins.rebalancer,ocr2ForwarderAddress:t.ocr2JobConfig.forwarderAddress},p=o?o.chains.results:[],b=s?s.ethKeys.results:[],m=c?c.p2pKeys.results:[],g=f?f.ocrKeyBundles.results:[],v=d?d.ocr2KeyBundles.results:[];return l.createElement(aD.Z,{onClose:n,open:r,disableBackdropClick:!0},l.createElement(oO.Z,{disableTypography:!0},l.createElement(x.default,{variant:"body2"},"Edit Supported Chain")),l.createElement(oT.Z,null,l.createElement(TN,{innerRef:a,initialValues:h,onSubmit:i,chains:p,accountsEVM:b,accountsNonEvm:u,p2pKeys:m,ocrKeys:g,ocr2Keys:v,editing:!0})),l.createElement(ox.Z,null,l.createElement(ok.default,{onClick:n},"Cancel"),l.createElement(ok.default,{color:"primary",type:"submit",form:"chain-configuration-form",variant:"contained"},"Submit")))};function TG(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);nt.version?e:t})},[o]),g=l.useMemo(function(){return M1(o).sort(function(e,t){return t.version-e.version})},[o]),v=function(e,t,n){switch(e){case"PENDING":return l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"text",color:"secondary",onClick:function(){return b("reject",t)}},"Reject"),m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status&&l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve"),m.id===t&&"DELETED"===n.status&&n.pendingUpdate&&l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("cancel",t)}},"Cancel"),l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs")));case"APPROVED":return l.createElement(l.Fragment,null,l.createElement(ok.default,{variant:"contained",onClick:function(){return b("cancel",t)}},"Cancel"),"DELETED"===n.status&&n.pendingUpdate&&l.createElement(x.default,{color:"error"},"This proposal was deleted. Cancel the spec to delete any running jobs"));case"CANCELLED":if(m.id===t&&"DELETED"!==n.status&&"REVOKED"!==n.status)return l.createElement(ok.default,{variant:"contained",color:"primary",onClick:function(){return b("approve",t)}},"Approve");return null;default:return null}};return l.createElement("div",null,g.map(function(e,n){return l.createElement(mP.Z,{defaultExpanded:0===n,key:n},l.createElement(mR.Z,{expandIcon:l.createElement(gh.Z,null)},l.createElement(x.default,{className:t.versionText},"Version ",e.version),l.createElement(Es.Z,{label:e.status,color:"APPROVED"===e.status?"primary":"default",variant:"REJECTED"===e.status||"CANCELLED"===e.status?"outlined":"default"}),l.createElement("div",{className:t.proposedAtContainer},l.createElement(x.default,null,"Proposed ",l.createElement(aO,{tooltip:!0},e.createdAt)))),l.createElement(mj.Z,{className:t.expansionPanelDetails},l.createElement("div",{className:t.actions},l.createElement("div",{className:t.editContainer},0===n&&("PENDING"===e.status||"CANCELLED"===e.status)&&"DELETED"!==s.status&&"REVOKED"!==s.status&&l.createElement(ok.default,{variant:"contained",onClick:function(){return p(!0)}},"Edit")),l.createElement("div",{className:t.actionsContainer},v(e.status,e.id,s))),l.createElement(gd,{language:"toml",style:gs,"data-testid":"codeblock"},e.definition)))}),l.createElement(oC,{open:null!=c,title:c?M6[c.action].title:"",body:c?M6[c.action].body:"",onConfirm:function(){if(c){switch(c.action){case"approve":n(c.id);break;case"cancel":r(c.id);break;case"reject":i(c.id)}f(null)}},cancelButtonText:"Cancel",onCancel:function(){return f(null)}}),l.createElement(Mz,{open:h,onClose:function(){return p(!1)},initialValues:{definition:m.definition,id:m.id},onSubmit:a}))});function M8(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function M9(){var e=M8(["\n ","\n fragment JobProposalPayloadFields on JobProposal {\n id\n externalJobID\n remoteUUID\n jobID\n specs {\n ...JobProposal_SpecsFields\n }\n status\n pendingUpdate\n }\n"]);return M9=function(){return e},e}var M7=n0(M9(),M3),Oe=function(e){var t=e.onApprove,n=e.onCancel,r=e.onReject,i=e.onUpdateSpec,a=e.proposal;return l.createElement(ig,null,l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(iy,null,"Job Proposal #",a.id))),l.createElement(MF,{proposal:a}),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:9},l.createElement(xQ,null,"Specs"))),l.createElement(d.Z,{container:!0,spacing:32},l.createElement(d.Z,{item:!0,xs:12},l.createElement(M5,{proposal:a,specs:a.specs,onReject:r,onApprove:t,onCancel:n,onUpdateSpec:i}))))};function Ot(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]e.length)&&(t=e.length);for(var n=0,r=Array(t);ne.length)&&(t=e.length);for(var n=0,r=Array(t);nU,tA:()=>$,KL:()=>H,Iw:()=>V,DQ:()=>W,cB:()=>T,LO:()=>M,t5:()=>k,qt:()=>x,Jc:()=>C,L7:()=>Y,EO:()=>B});var r,i,a=n(66289),o=n(41800),s=n.n(o),u=n(67932);(i=r||(r={})).IN_PROGRESS="in_progress",i.PENDING_INCOMING_CONFIRMATIONS="pending_incoming_confirmations",i.PENDING_CONNECTION="pending_connection",i.PENDING_BRIDGE="pending_bridge",i.PENDING_SLEEP="pending_sleep",i.ERRORED="errored",i.COMPLETED="completed";var c=n(87013),l=n(19084),f=n(34823);function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]j,v2:()=>F});var r=n(66289);function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var a="/sessions",o="/sessions",s=function e(t){var n=this;i(this,e),this.api=t,this.createSession=function(e){return n.create(e)},this.destroySession=function(){return n.destroy()},this.create=this.api.createResource(a),this.destroy=this.api.deleteResource(o)};function u(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var c="/v2/bulk_delete_runs",l=function e(t){var n=this;u(this,e),this.api=t,this.bulkDeleteJobRuns=function(e){return n.destroy(e)},this.destroy=this.api.deleteResource(c)};function f(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var d="/v2/chains/evm",h="".concat(d,"/:id"),p=function e(t){var n=this;f(this,e),this.api=t,this.getChains=function(){return n.index()},this.createChain=function(e){return n.create(e)},this.destroyChain=function(e){return n.destroy(void 0,{id:e})},this.updateChain=function(e,t){return n.update(t,{id:e})},this.index=this.api.fetchResource(d),this.create=this.api.createResource(d),this.destroy=this.api.deleteResource(h),this.update=this.api.updateResource(h)};function b(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var m="/v2/keys/evm/chain",g=function e(t){var n=this;b(this,e),this.api=t,this.chain=function(e){var t=new URLSearchParams;t.append("address",e.address),t.append("evmChainID",e.evmChainID),null!==e.abandon&&t.append("abandon",String(e.abandon)),null!==e.enabled&&t.append("enabled",String(e.enabled));var r=m+"?"+t.toString();return n.api.createResource(r)()}};function v(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var y="/v2/jobs",w="".concat(y,"/:specId/runs"),_=function e(t){var n=this;v(this,e),this.api=t,this.createJobRunV2=function(e,t){return n.post(t,{specId:e})},this.post=this.api.createResource(w,!0)};function E(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var S="/v2/log",k=function e(t){var n=this;E(this,e),this.api=t,this.getLogConfig=function(){return n.show()},this.updateLogConfig=function(e){return n.update(e)},this.show=this.api.fetchResource(S),this.update=this.api.updateResource(S)};function x(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var T="/v2/nodes",M=function e(t){var n=this;x(this,e),this.api=t,this.getNodes=function(){return n.index()},this.createNode=function(e){return n.create(e)},this.index=this.api.fetchResource(T),this.create=this.api.createResource(T)};function O(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var A="/v2/enroll_webauthn",L=function e(t){var n=this;O(this,e),this.api=t,this.beginKeyRegistration=function(e){return n.create(e)},this.finishKeyRegistration=function(e){return n.put(e)},this.create=this.api.fetchResource(A),this.put=this.api.createResource(A)};function C(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var I="/v2/build_info",D=function e(t){var n=this;C(this,e),this.api=t,this.show=function(){return n.api.GET(I)()}};function N(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}var P=function e(t){N(this,e),this.api=t,this.buildInfo=new D(this.api),this.bulkDeleteRuns=new l(this.api),this.chains=new p(this.api),this.logConfig=new k(this.api),this.nodes=new M(this.api),this.jobs=new _(this.api),this.webauthn=new L(this.api),this.evmKeys=new g(this.api)},R=new r.V0({base:void 0}),j=new s(R),F=new P(R)},1398(e,t,n){"use strict";n.d(t,{Z:()=>d});var r=n(67294),i=n(32316),a=n(83638),o=n(94184),s=n.n(o);function u(){return(u=Object.assign||function(e){for(var t=1;tc});var r=n(67294),i=n(32316);function a(){return(a=Object.assign||function(e){for(var t=1;tx,jK:()=>v});var r=n(67294),i=n(37703),a=n(45697),o=n.n(a),s=n(82204),u=n(71426),c=n(94184),l=n.n(c),f=n(32316),d=function(e){var t=e.palette.success||{},n=e.palette.warning||{};return{base:{paddingLeft:5*e.spacing.unit,paddingRight:5*e.spacing.unit},success:{backgroundColor:t.main,color:t.contrastText},error:{backgroundColor:e.palette.error.dark,color:e.palette.error.contrastText},warning:{backgroundColor:n.contrastText,color:n.main}}},h=function(e){var t,n=e.success,r=e.error,i=e.warning,a=e.classes,o=e.className;return n?t=a.success:r?t=a.error:i&&(t=a.warning),l()(a.base,o,t)},p=function(e){return r.createElement(s.Z,{className:h(e),square:!0},r.createElement(u.default,{variant:"body2",color:"inherit",component:"div"},e.children))};p.defaultProps={success:!1,error:!1,warning:!1},p.propTypes={success:o().bool,error:o().bool,warning:o().bool};let b=(0,f.withStyles)(d)(p);var m=function(){return r.createElement(r.Fragment,null,"Unhandled error. Please help us by opening a"," ",r.createElement("a",{href:"https://github.com/smartcontractkit/chainlink/issues/new"},"bug report"))};let g=m;function v(e){return"string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null)}function y(e,t){var n;return n="string"==typeof e?e:e.component?e.component(e.props):r.createElement(g,null),r.createElement("p",{key:t},n)}var w=function(e){var t=e.notifications;return r.createElement(b,{error:!0},t.map(y))},_=function(e){var t=e.notifications;return r.createElement(b,{success:!0},t.map(y))},E=function(e){var t=e.errors,n=e.successes;return r.createElement("div",null,(null==t?void 0:t.length)>0&&r.createElement(w,{notifications:t}),n.length>0&&r.createElement(_,{notifications:n}))},S=function(e){return{errors:e.notifications.errors,successes:e.notifications.successes}},k=(0,i.$j)(S)(E);let x=k},9409(e,t,n){"use strict";n.d(t,{ZP:()=>j});var r=n(67294),i=n(37703),a=n(5977),o=n(32316),s=n(1398),u=n(82204),c=n(30060),l=n(71426),f=n(60520),d=n(39814),h=n(57209),p=n(26842),b=n(3950),m=n(5536),g=n(45697),v=n.n(g);let y=n.p+"9f6d832ef97e8493764e.svg";function w(){return(w=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&_.map(function(e,t){return r.createElement(d.Z,{item:!0,xs:12,key:t},r.createElement(u.Z,{raised:!1,className:v.error},r.createElement(c.Z,null,r.createElement(l.default,{variant:"body1",className:v.errorText},(0,b.jK)(e)))))}),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"email",label:"Email",margin:"normal",value:n,onChange:m("email"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(f.Z,{id:"password",label:"Password",type:"password",autoComplete:"password",margin:"normal",value:h,onChange:m("password"),error:_.length>0,variant:"outlined",fullWidth:!0})),r.createElement(d.Z,{item:!0,xs:12},r.createElement(d.Z,{container:!0,spacing:0,justify:"center"},r.createElement(d.Z,{item:!0},r.createElement(s.Z,{type:"submit",variant:"primary"},"Access Account")))),y&&r.createElement(l.default,{variant:"body1",color:"textSecondary"},"Signing in...")))))))},P=function(e){return{fetching:e.authentication.fetching,authenticated:e.authentication.allowed,errors:e.notifications.errors}},R=(0,i.$j)(P,x({submitSignIn:p.L7}))(N);let j=(0,h.wU)(e)((0,o.withStyles)(D)(R))},16353(e,t,n){"use strict";n.d(t,{ZP:()=>H,rH:()=>U});var r,i=n(37703),a=n(97779),o=n(9541),s=n(19084);function u(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:h,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.Mk.RECEIVE_SIGNOUT_SUCCESS:case s.Mk.RECEIVE_SIGNIN_SUCCESS:var n={allowed:t.authenticated};return o.Ks(n),f(c({},e,n),{errors:[]});case s.Mk.RECEIVE_SIGNIN_FAIL:var r={allowed:!1};return o.Ks(r),f(c({},e,r),{errors:[]});case s.Mk.RECEIVE_SIGNIN_ERROR:case s.Mk.RECEIVE_SIGNOUT_ERROR:var i={allowed:!1};return o.Ks(i),f(c({},e,i),{errors:t.errors||[]});default:return e}};let b=p;function m(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function g(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:_,t=arguments.length>1?arguments[1]:void 0;return t.type?t.type.startsWith(r.REQUEST)?y(g({},e),{count:e.count+1}):t.type.startsWith(r.RECEIVE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type.startsWith(r.RESPONSE)?y(g({},e),{count:Math.max(e.count-1,0)}):t.type===s.di.REDIRECT?y(g({},e),{count:0}):e:e};let S=E;function k(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function x(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:O,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.MATCH_ROUTE:return M(x({},O),{currentUrl:t.pathname});case s.Ih.NOTIFY_SUCCESS:var n={component:t.component,props:t.props};return M(x({},e),{successes:[n],errors:[]});case s.Ih.NOTIFY_SUCCESS_MSG:return M(x({},e),{successes:[t.msg],errors:[]});case s.Ih.NOTIFY_ERROR:var r=t.error.errors,i=null==r?void 0:r.map(function(e){return L(t,e)});return M(x({},e),{successes:[],errors:i});case s.Ih.NOTIFY_ERROR_MSG:return M(x({},e),{successes:[],errors:[t.msg]});case s.Mk.RECEIVE_SIGNIN_FAIL:return M(x({},e),{successes:[],errors:["Your email or password is incorrect. Please try again"]});default:return e}};function L(e,t){return{component:e.component,props:{msg:t.detail}}}let C=A;function I(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function D(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:R,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case s.di.REDIRECT:return P(D({},e),{to:t.to});case s.di.MATCH_ROUTE:return P(D({},e),{to:void 0});default:return e}};let F=j;var Y=n(87013),B=(0,a.UY)({authentication:b,fetching:S,notifications:C,redirect:F,buildInfo:Y.Z});B(void 0,{type:"INITIAL_STATE"});var U=i.v9;let H=B},19084(e,t,n){"use strict";var r,i,a,o,s,u,c,l,f,d;n.d(t,{Ih:()=>i,Mk:()=>a,Y0:()=>s,di:()=>r,jp:()=>o}),n(67294),(u=r||(r={})).REDIRECT="REDIRECT",u.MATCH_ROUTE="MATCH_ROUTE",(c=i||(i={})).NOTIFY_SUCCESS="NOTIFY_SUCCESS",c.NOTIFY_SUCCESS_MSG="NOTIFY_SUCCESS_MSG",c.NOTIFY_ERROR="NOTIFY_ERROR",c.NOTIFY_ERROR_MSG="NOTIFY_ERROR_MSG",(l=a||(a={})).REQUEST_SIGNIN="REQUEST_SIGNIN",l.RECEIVE_SIGNIN_SUCCESS="RECEIVE_SIGNIN_SUCCESS",l.RECEIVE_SIGNIN_FAIL="RECEIVE_SIGNIN_FAIL",l.RECEIVE_SIGNIN_ERROR="RECEIVE_SIGNIN_ERROR",l.RECEIVE_SIGNOUT_SUCCESS="RECEIVE_SIGNOUT_SUCCESS",l.RECEIVE_SIGNOUT_ERROR="RECEIVE_SIGNOUT_ERROR",(f=o||(o={})).RECEIVE_CREATE_ERROR="RECEIVE_CREATE_ERROR",f.RECEIVE_CREATE_SUCCESS="RECEIVE_CREATE_SUCCESS",f.RECEIVE_DELETE_ERROR="RECEIVE_DELETE_ERROR",f.RECEIVE_DELETE_SUCCESS="RECEIVE_DELETE_SUCCESS",f.RECEIVE_UPDATE_ERROR="RECEIVE_UPDATE_ERROR",f.RECEIVE_UPDATE_SUCCESS="RECEIVE_UPDATE_SUCCESS",f.REQUEST_CREATE="REQUEST_CREATE",f.REQUEST_DELETE="REQUEST_DELETE",f.REQUEST_UPDATE="REQUEST_UPDATE",f.UPSERT_CONFIGURATION="UPSERT_CONFIGURATION",f.UPSERT_JOB_RUN="UPSERT_JOB_RUN",f.UPSERT_JOB_RUNS="UPSERT_JOB_RUNS",f.UPSERT_TRANSACTION="UPSERT_TRANSACTION",f.UPSERT_TRANSACTIONS="UPSERT_TRANSACTIONS",f.UPSERT_BUILD_INFO="UPSERT_BUILD_INFO",(d=s||(s={})).FETCH_BUILD_INFO_REQUESTED="FETCH_BUILD_INFO_REQUESTED",d.FETCH_BUILD_INFO_SUCCEEDED="FETCH_BUILD_INFO_SUCCEEDED",d.FETCH_BUILD_INFO_FAILED="FETCH_BUILD_INFO_FAILED"},87013(e,t,n){"use strict";n.d(t,{Y:()=>o,Z:()=>u});var r=n(19084);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:o,t=arguments.length>1?arguments[1]:void 0;return t.type===r.Y0.FETCH_BUILD_INFO_SUCCEEDED?a({},t.buildInfo):e};let u=s},34823(e,t,n){"use strict";n.d(t,{N:()=>r});var r=function(e){return e.buildInfo}},73343(e,t,n){"use strict";n.d(t,{r:()=>u});var r=n(19350),i=n(32316),a=n(59114),o=n(5324),s={props:{MuiGrid:{spacing:3*o.default.unit},MuiCardHeader:{titleTypographyProps:{color:"secondary"}}},palette:{action:{hoverOpacity:.3},primary:{light:"#E5F1FF",main:"#3c40c6",contrastText:"#fff"},secondary:{main:"#3d5170"},success:{light:"#e8faf1",main:r.ek.A700,dark:r.ek[700],contrastText:r.y0.white},warning:{light:"#FFFBF1",main:"#fff6b6",contrastText:"#fad27a"},error:{light:"#ffdada",main:"#f44336",dark:"#d32f2f",contrastText:"#fff"},background:{default:"#f5f6f8",appBar:"#3c40c6"},text:{primary:(0,a.darken)(r.BA.A700,.7),secondary:"#818ea3"},listPendingStatus:{background:"#fef7e5",color:"#fecb4c"},listCompletedStatus:{background:"#e9faf2",color:"#4ed495"}},shape:{borderRadius:o.default.unit},overrides:{MuiButton:{root:{borderRadius:o.default.unit/2,textTransform:"none"},sizeLarge:{padding:void 0,fontSize:void 0,paddingTop:o.default.unit,paddingBottom:o.default.unit,paddingLeft:5*o.default.unit,paddingRight:5*o.default.unit}},MuiTableCell:{body:{fontSize:"1rem"},head:{fontSize:"1rem",fontWeight:400}},MuiCardHeader:{root:{borderBottom:"1px solid rgba(0, 0, 0, 0.12)"},action:{marginTop:-2,marginRight:0,"& >*":{marginLeft:2*o.default.unit}},subheader:{marginTop:.5*o.default.unit}}},typography:{useNextVariants:!0,fontFamily:"-apple-system,BlinkMacSystemFont,Roboto,Helvetica,Arial,sans-serif",button:{textTransform:"none",fontSize:"1.2em"},body1:{fontSize:"1.0rem",fontWeight:400,lineHeight:"1.46429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body2:{fontSize:"1.0rem",fontWeight:500,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},body1Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"1rem",lineHeight:1.5,letterSpacing:-.4},body2Next:{color:"rgb(29, 29, 29)",fontWeight:400,fontSize:"0.875rem",lineHeight:1.5,letterSpacing:-.4},display1:{color:"#818ea3",fontSize:"2.125rem",fontWeight:400,lineHeight:"1.20588em",letterSpacing:-.4},display2:{color:"#818ea3",fontSize:"2.8125rem",fontWeight:400,lineHeight:"1.13333em",marginLeft:"-.02em",letterSpacing:-.4},display3:{color:"#818ea3",fontSize:"3.5rem",fontWeight:400,lineHeight:"1.30357em",marginLeft:"-.02em",letterSpacing:-.4},display4:{fontSize:14,fontWeightLight:300,fontWeightMedium:500,fontWeightRegular:400,letterSpacing:-.4},h1:{color:"rgb(29, 29, 29)",fontSize:"6rem",fontWeight:300,lineHeight:1},h2:{color:"rgb(29, 29, 29)",fontSize:"3.75rem",fontWeight:300,lineHeight:1},h3:{color:"rgb(29, 29, 29)",fontSize:"3rem",fontWeight:400,lineHeight:1.04},h4:{color:"rgb(29, 29, 29)",fontSize:"2.125rem",fontWeight:400,lineHeight:1.17},h5:{color:"rgb(29, 29, 29)",fontSize:"1.5rem",fontWeight:400,lineHeight:1.33,letterSpacing:-.4},h6:{fontSize:"0.8rem",fontWeight:450,lineHeight:"1.71429em",color:"rgba(0, 0, 0, 0.87)",letterSpacing:-.4},subheading:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:"1.5em",letterSpacing:-.4},subtitle1:{color:"rgb(29, 29, 29)",fontSize:"1rem",fontWeight:400,lineHeight:1.75,letterSpacing:-.4},subtitle2:{color:"rgb(29, 29, 29)",fontSize:"0.875rem",fontWeight:500,lineHeight:1.57,letterSpacing:-.4}},shadows:["none","0px 1px 3px 0px rgba(0, 0, 0, 0.1),0px 1px 1px 0px rgba(0, 0, 0, 0.04),0px 2px 1px -1px rgba(0, 0, 0, 0.02)","0px 1px 5px 0px rgba(0, 0, 0, 0.1),0px 2px 2px 0px rgba(0, 0, 0, 0.04),0px 3px 1px -2px rgba(0, 0, 0, 0.02)","0px 1px 8px 0px rgba(0, 0, 0, 0.1),0px 3px 4px 0px rgba(0, 0, 0, 0.04),0px 3px 3px -2px rgba(0, 0, 0, 0.02)","0px 2px 4px -1px rgba(0, 0, 0, 0.1),0px 4px 5px 0px rgba(0, 0, 0, 0.04),0px 1px 10px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 5px 8px 0px rgba(0, 0, 0, 0.04),0px 1px 14px 0px rgba(0, 0, 0, 0.02)","0px 3px 5px -1px rgba(0, 0, 0, 0.1),0px 6px 10px 0px rgba(0, 0, 0, 0.04),0px 1px 18px 0px rgba(0, 0, 0, 0.02)","0px 4px 5px -2px rgba(0, 0, 0, 0.1),0px 7px 10px 1px rgba(0, 0, 0, 0.04),0px 2px 16px 1px rgba(0, 0, 0, 0.02)","0px 5px 5px -3px rgba(0, 0, 0, 0.1),0px 8px 10px 1px rgba(0, 0, 0, 0.04),0px 3px 14px 2px rgba(0, 0, 0, 0.02)","0px 5px 6px -3px rgba(0, 0, 0, 0.1),0px 9px 12px 1px rgba(0, 0, 0, 0.04),0px 3px 16px 2px rgba(0, 0, 0, 0.02)","0px 6px 6px -3px rgba(0, 0, 0, 0.1),0px 10px 14px 1px rgba(0, 0, 0, 0.04),0px 4px 18px 3px rgba(0, 0, 0, 0.02)","0px 6px 7px -4px rgba(0, 0, 0, 0.1),0px 11px 15px 1px rgba(0, 0, 0, 0.04),0px 4px 20px 3px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 12px 17px 2px rgba(0, 0, 0, 0.04),0px 5px 22px 4px rgba(0, 0, 0, 0.02)","0px 7px 8px -4px rgba(0, 0, 0, 0.1),0px 13px 19px 2px rgba(0, 0, 0, 0.04),0px 5px 24px 4px rgba(0, 0, 0, 0.02)","0px 7px 9px -4px rgba(0, 0, 0, 0.1),0px 14px 21px 2px rgba(0, 0, 0, 0.04),0px 5px 26px 4px rgba(0, 0, 0, 0.02)","0px 8px 9px -5px rgba(0, 0, 0, 0.1),0px 15px 22px 2px rgba(0, 0, 0, 0.04),0px 6px 28px 5px rgba(0, 0, 0, 0.02)","0px 8px 10px -5px rgba(0, 0, 0, 0.1),0px 16px 24px 2px rgba(0, 0, 0, 0.04),0px 6px 30px 5px rgba(0, 0, 0, 0.02)","0px 8px 11px -5px rgba(0, 0, 0, 0.1),0px 17px 26px 2px rgba(0, 0, 0, 0.04),0px 6px 32px 5px rgba(0, 0, 0, 0.02)","0px 9px 11px -5px rgba(0, 0, 0, 0.1),0px 18px 28px 2px rgba(0, 0, 0, 0.04),0px 7px 34px 6px rgba(0, 0, 0, 0.02)","0px 9px 12px -6px rgba(0, 0, 0, 0.1),0px 19px 29px 2px rgba(0, 0, 0, 0.04),0px 7px 36px 6px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 20px 31px 3px rgba(0, 0, 0, 0.04),0px 8px 38px 7px rgba(0, 0, 0, 0.02)","0px 10px 13px -6px rgba(0, 0, 0, 0.1),0px 21px 33px 3px rgba(0, 0, 0, 0.04),0px 8px 40px 7px rgba(0, 0, 0, 0.02)","0px 10px 14px -6px rgba(0, 0, 0, 0.1),0px 22px 35px 3px rgba(0, 0, 0, 0.04),0px 8px 42px 7px rgba(0, 0, 0, 0.02)","0px 11px 14px -7px rgba(0, 0, 0, 0.1),0px 23px 36px 3px rgba(0, 0, 0, 0.04),0px 9px 44px 8px rgba(0, 0, 0, 0.02)","0px 11px 15px -7px rgba(0, 0, 0, 0.1),0px 24px 38px 3px rgba(0, 0, 0, 0.04),0px 9px 46px 8px rgba(0, 0, 0, 0.02)",]},u=(0,i.createMuiTheme)(s)},66289(e,t,n){"use strict";function r(e){if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function i(e,t){if(!(e instanceof t))throw TypeError("Cannot call a class as a function")}function a(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}}function o(e,t,n){return(o=a()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var i=new(Function.bind.apply(e,r));return n&&f(i,n.prototype),i}).apply(null,arguments)}function s(e){return(s=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function u(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&f(e,t)}function c(e){return -1!==Function.toString.call(e).indexOf("[native code]")}function l(e,t){return t&&("object"===p(t)||"function"==typeof t)?t:r(e)}function f(e,t){return(f=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}n.d(t,{V0:()=>B,_7:()=>v});var d,h,p=function(e){return e&&"undefined"!=typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};function b(e){var t="function"==typeof Map?new Map:void 0;return(b=function(e){if(null===e||!c(e))return e;if("function"!=typeof e)throw TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return o(e,arguments,s(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),f(n,e)})(e)}function m(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(e){return!1}}function g(e){var t=m();return function(){var n,r=s(e);if(t){var i=s(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return l(this,n)}}var v=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"AuthenticationError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e},],r}return n}(b(Error)),y=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"BadRequestError")).errors=a,r}return n}(b(Error)),w=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnprocessableEntityError")).errors=e,r}return n}(b(Error)),_=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"ServerError")).errors=e,r}return n}(b(Error)),E=function(e){u(n,e);var t=g(n);function n(e){var r,a=e.errors;return i(this,n),(r=t.call(this,"ConflictError")).errors=a,r}return n}(b(Error)),S=function(e){u(n,e);var t=g(n);function n(e){var r;return i(this,n),(r=t.call(this,"UnknownResponseError(".concat(e.statusText,")"))).errors=[{status:e.status,detail:e.statusText},],r}return n}(b(Error));function k(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:2e4;return Promise.race([fetch(e,t),new Promise(function(e,t){return setTimeout(function(){return t(Error("timeout"))},n)}),])}function x(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=200&&e.status<300))return[3,2];return[2,e.json()];case 2:if(400!==e.status)return[3,3];return[2,e.json().then(function(e){throw new y(e)})];case 3:if(401!==e.status)return[3,4];throw new v(e);case 4:if(422!==e.status)return[3,6];return[4,$(e)];case 5:throw n=i.sent(),new w(n);case 6:if(409!==e.status)return[3,7];return[2,e.json().then(function(e){throw new E(e)})];case 7:if(!(e.status>=500))return[3,9];return[4,$(e)];case 8:throw r=i.sent(),new _(r);case 9:throw new S(e);case 10:return[2]}})})).apply(this,arguments)}function $(e){return z.apply(this,arguments)}function z(){return(z=j(function(e){return Y(this,function(t){return[2,e.json().then(function(t){return t.errors?t.errors.map(function(t){return{status:e.status,detail:t.detail}}):G(e)}).catch(function(){return G(e)})]})})).apply(this,arguments)}function G(e){return[{status:e.status,detail:e.statusText},]}},50109(e,t,n){"use strict";n.d(t,{LK:()=>o,U2:()=>i,eT:()=>s,t8:()=>a});var r=n(12795);function i(e){return r.ZP.getItem("chainlink.".concat(e))}function a(e,t){r.ZP.setItem("chainlink.".concat(e),t)}function o(e){var t=i(e),n={};if(t)try{return JSON.parse(t)}catch(r){}return n}function s(e,t){a(e,JSON.stringify(t))}},9541(e,t,n){"use strict";n.d(t,{Ks:()=>u,Tp:()=>a,iR:()=>o,pm:()=>s});var r=n(50109),i="persistURL";function a(){return r.U2(i)||""}function o(e){r.t8(i,e)}function s(){return r.LK("authentication")}function u(e){r.eT("authentication",e)}},67121(e,t,n){"use strict";function r(e){var t,n=e.Symbol;return"function"==typeof n?n.observable?t=n.observable:(t=n("observable"),n.observable=t):t="@@observable",t}n.r(t),n.d(t,{default:()=>o}),e=n.hmd(e),i="undefined"!=typeof self?self:"undefined"!=typeof window?window:void 0!==n.g?n.g:e;var i,a=r(i);let o=a},2177(e,t,n){"use strict";n.d(t,{Z:()=>o});var r=!0,i="Invariant failed";function a(e,t){if(!e){if(r)throw Error(i);throw Error(i+": "+(t||""))}}let o=a},11742(e){e.exports=function(){var e=document.getSelection();if(!e.rangeCount)return function(){};for(var t=document.activeElement,n=[],r=0;ru,ZT:()=>i,_T:()=>o,ev:()=>c,mG:()=>s,pi:()=>a});var r=function(e,t){return(r=Object.setPrototypeOf||({__proto__:[]})instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,t)};function i(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return(a=Object.assign||function(e){for(var t,n=1,r=arguments.length;nt.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,r=Object.getOwnPropertySymbols(e);it.indexOf(r[i])&&Object.prototype.propertyIsEnumerable.call(e,r[i])&&(n[r[i]]=e[r[i]]);return n}function s(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,a){function o(e){try{u(r.next(e))}catch(t){a(t)}}function s(e){try{u(r.throw(e))}catch(t){a(t)}}function u(e){e.done?n(e.value):i(e.value).then(o,s)}u((r=r.apply(e,t||[])).next())})}function u(e,t){var n,r,i,a,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(e){return function(t){return u([e,t])}}function u(a){if(n)throw TypeError("Generator is already executing.");for(;o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!(i=(i=o.trys).length>0&&i[i.length-1])&&(6===a[0]||2===a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]r})},94927(e,t,n){function r(e,t){if(i("noDeprecation"))return e;var n=!1;function r(){if(!n){if(i("throwDeprecation"))throw Error(t);i("traceDeprecation")?console.trace(t):console.warn(t),n=!0}return e.apply(this,arguments)}return r}function i(e){try{if(!n.g.localStorage)return!1}catch(t){return!1}var r=n.g.localStorage[e];return null!=r&&"true"===String(r).toLowerCase()}e.exports=r},42473(e){"use strict";var t=function(){};e.exports=t},84763(e){e.exports=Worker},47529(e){e.exports=n;var t=Object.prototype.hasOwnProperty;function n(){for(var e={},n=0;ne.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}e.exports=i,e.exports.__esModule=!0,e.exports.default=e.exports},7071(e){function t(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},94993(e,t,n){var r=n(18698).default,i=n(66115);function a(e,t){if(t&&("object"===r(t)||"function"==typeof t))return t;if(void 0!==t)throw TypeError("Derived constructors may only return object or undefined");return i(e)}e.exports=a,e.exports.__esModule=!0,e.exports.default=e.exports},6015(e){function t(n,r){return e.exports=t=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},e.exports.__esModule=!0,e.exports.default=e.exports,t(n,r)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},861(e,t,n){var r=n(63405),i=n(79498),a=n(86116),o=n(42281);function s(e){return r(e)||i(e)||a(e)||o()}e.exports=s,e.exports.__esModule=!0,e.exports.default=e.exports},18698(e){function t(n){return e.exports=t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e.exports.__esModule=!0,e.exports.default=e.exports,t(n)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports},86116(e,t,n){var r=n(73897);function i(e,t){if(e){if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return r(e,t)}}e.exports=i,e.exports.__esModule=!0,e.exports.default=e.exports},1644(e,t,n){"use strict";var r,i;function a(e){return!!e&&e<7}n.d(t,{I:()=>r,O:()=>a}),(i=r||(r={}))[i.loading=1]="loading",i[i.setVariables=2]="setVariables",i[i.fetchMore=3]="fetchMore",i[i.refetch=4]="refetch",i[i.poll=6]="poll",i[i.ready=7]="ready",i[i.error=8]="error"},30990(e,t,n){"use strict";n.d(t,{MS:()=>s,YG:()=>a,cA:()=>c,ls:()=>o});var r=n(70655);n(83952);var i=n(13154),a=Symbol();function o(e){return!!e.extensions&&Array.isArray(e.extensions[a])}function s(e){return e.hasOwnProperty("graphQLErrors")}var u=function(e){var t=(0,r.ev)((0,r.ev)((0,r.ev)([],e.graphQLErrors,!0),e.clientErrors,!0),e.protocolErrors,!0);return e.networkError&&t.push(e.networkError),t.map(function(e){return(0,i.s)(e)&&e.message||"Error message not found."}).join("\n")},c=function(e){function t(n){var r=n.graphQLErrors,i=n.protocolErrors,a=n.clientErrors,o=n.networkError,s=n.errorMessage,c=n.extraInfo,l=e.call(this,s)||this;return l.name="ApolloError",l.graphQLErrors=r||[],l.protocolErrors=i||[],l.clientErrors=a||[],l.networkError=o||null,l.message=s||u(l),l.extraInfo=c,l.__proto__=t.prototype,l}return(0,r.ZT)(t,e),t}(Error)},85317(e,t,n){"use strict";n.d(t,{K:()=>a});var r=n(67294),i=n(30320).aS?Symbol.for("__APOLLO_CONTEXT__"):"__APOLLO_CONTEXT__";function a(){var e=r.createContext[i];return e||(Object.defineProperty(r.createContext,i,{value:e=r.createContext({}),enumerable:!1,writable:!1,configurable:!0}),e.displayName="ApolloContext"),e}},21436(e,t,n){"use strict";n.d(t,{O:()=>i,k:()=>r});var r=Array.isArray;function i(e){return Array.isArray(e)&&e.length>0}},30320(e,t,n){"use strict";n.d(t,{DN:()=>s,JC:()=>l,aS:()=>o,mr:()=>i,sy:()=>a});var r=n(83952),i="function"==typeof WeakMap&&"ReactNative"!==(0,r.wY)(function(){return navigator.product}),a="function"==typeof WeakSet,o="function"==typeof Symbol&&"function"==typeof Symbol.for,s=o&&Symbol.asyncIterator,u="function"==typeof(0,r.wY)(function(){return window.document.createElement}),c=(0,r.wY)(function(){return navigator.userAgent.indexOf("jsdom")>=0})||!1,l=u&&!c},53712(e,t,n){"use strict";function r(){for(var e=[],t=0;tr})},10542(e,t,n){"use strict";n.d(t,{J:()=>o}),n(83952);var r=n(13154);function i(e){var t=new Set([e]);return t.forEach(function(e){(0,r.s)(e)&&a(e)===e&&Object.getOwnPropertyNames(e).forEach(function(n){(0,r.s)(e[n])&&t.add(e[n])})}),e}function a(e){if(__DEV__&&!Object.isFrozen(e))try{Object.freeze(e)}catch(t){if(t instanceof TypeError)return null;throw t}return e}function o(e){return __DEV__&&i(e),e}},14012(e,t,n){"use strict";n.d(t,{J:()=>a});var r=n(70655),i=n(53712);function a(e,t){return(0,i.o)(e,t,t.variables&&{variables:(0,r.pi)((0,r.pi)({},e&&e.variables),t.variables)})}},13154(e,t,n){"use strict";function r(e){return null!==e&&"object"==typeof e}n.d(t,{s:()=>r})},83952(e,t,n){"use strict";n.d(t,{ej:()=>u,kG:()=>c,wY:()=>h});var r,i=n(70655),a="Invariant Violation",o=Object.setPrototypeOf,s=void 0===o?function(e,t){return e.__proto__=t,e}:o,u=function(e){function t(n){void 0===n&&(n=a);var r=e.call(this,"number"==typeof n?a+": "+n+" (see https://github.com/apollographql/invariant-packages)":n)||this;return r.framesToPop=1,r.name=a,s(r,t.prototype),r}return(0,i.ZT)(t,e),t}(Error);function c(e,t){if(!e)throw new u(t)}var l=["debug","log","warn","error","silent"],f=l.indexOf("log");function d(e){return function(){if(l.indexOf(e)>=f)return(console[e]||console.log).apply(console,arguments)}}function h(e){try{return e()}catch(t){}}(r=c||(c={})).debug=d("debug"),r.log=d("log"),r.warn=d("warn"),r.error=d("error");let p=h(function(){return globalThis})||h(function(){return window})||h(function(){return self})||h(function(){return global})||h(function(){return h.constructor("return this")()});var b="__",m=[b,b].join("DEV");function g(){try{return Boolean(__DEV__)}catch(e){return Object.defineProperty(p,m,{value:"production"!==h(function(){return"production"}),enumerable:!1,configurable:!0,writable:!0}),p[m]}}let v=g();function y(e){try{return e()}catch(t){}}var w=y(function(){return globalThis})||y(function(){return window})||y(function(){return self})||y(function(){return global})||y(function(){return y.constructor("return this")()}),_=!1;function E(){!w||y(function(){return"production"})||y(function(){return process})||(Object.defineProperty(w,"process",{value:{env:{NODE_ENV:"production"}},configurable:!0,enumerable:!1,writable:!0}),_=!0)}function S(){_&&(delete w.process,_=!1)}E();var k=n(10143);function x(){return k.H,S()}function T(){__DEV__?c("boolean"==typeof v,v):c("boolean"==typeof v,39)}x(),T()},4942(e,t,n){"use strict";function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}n.d(t,{Z:()=>r})},87462(e,t,n){"use strict";function r(){return(r=Object.assign?Object.assign.bind():function(e){for(var t=1;tr})},51721(e,t,n){"use strict";function r(e,t){return(r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e})(e,t)}function i(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{Z:()=>i})},63366(e,t,n){"use strict";function r(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r=0||(i[n]=e[n]);return i}n.d(t,{Z:()=>r})},25821(e,t,n){"use strict";n.d(t,{Z:()=>s});var r=n(45695);function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var a=10,o=2;function s(e){return u(e,[])}function u(e,t){switch(i(e)){case"string":return JSON.stringify(e);case"function":return e.name?"[function ".concat(e.name,"]"):"[function]";case"object":if(null===e)return"null";return c(e,t);default:return String(e)}}function c(e,t){if(-1!==t.indexOf(e))return"[Circular]";var n=[].concat(t,[e]),r=d(e);if(void 0!==r){var i=r.call(e);if(i!==e)return"string"==typeof i?i:u(i,n)}else if(Array.isArray(e))return f(e,n);return l(e,n)}function l(e,t){var n=Object.keys(e);return 0===n.length?"{}":t.length>o?"["+h(e)+"]":"{ "+n.map(function(n){var r=u(e[n],t);return n+": "+r}).join(", ")+" }"}function f(e,t){if(0===e.length)return"[]";if(t.length>o)return"[Array]";for(var n=Math.min(a,e.length),r=e.length-n,i=[],s=0;s1&&i.push("... ".concat(r," more items")),"["+i.join(", ")+"]"}function d(e){var t=e[String(r.Z)];return"function"==typeof t?t:"function"==typeof e.inspect?e.inspect:void 0}function h(e){var t=Object.prototype.toString.call(e).replace(/^\[object /,"").replace(/]$/,"");if("Object"===t&&"function"==typeof e.constructor){var n=e.constructor.name;if("string"==typeof n&&""!==n)return n}return t}},45695(e,t,n){"use strict";n.d(t,{Z:()=>i});var r="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):void 0;let i=r},25217(e,t,n){"use strict";function r(e,t){if(!Boolean(e))throw Error(null!=t?t:"Unexpected invariant triggered.")}n.d(t,{Ye:()=>o,WU:()=>s,UG:()=>u});var i=n(45695);function a(e){var t=e.prototype.toJSON;"function"==typeof t||r(0),e.prototype.inspect=t,i.Z&&(e.prototype[i.Z]=t)}var o=function(){function e(e,t,n){this.start=e.start,this.end=t.end,this.startToken=e,this.endToken=t,this.source=n}return e.prototype.toJSON=function(){return{start:this.start,end:this.end}},e}();a(o);var s=function(){function e(e,t,n,r,i,a,o){this.kind=e,this.start=t,this.end=n,this.line=r,this.column=i,this.value=o,this.prev=a,this.next=null}return e.prototype.toJSON=function(){return{kind:this.kind,value:this.value,line:this.line,column:this.column}},e}();function u(e){return null!=e&&"string"==typeof e.kind}a(s)},87392(e,t,n){"use strict";function r(e){var t=e.split(/\r\n|[\n\r]/g),n=a(e);if(0!==n)for(var r=1;ro&&i(t[s-1]);)--s;return t.slice(o,s).join("\n")}function i(e){for(var t=0;t1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=-1===e.indexOf("\n"),i=" "===e[0]||" "===e[0],a='"'===e[e.length-1],o="\\"===e[e.length-1],s=!r||a||o||n,u="";return s&&!(r&&i)&&(u+="\n"+t),u+=t?e.replace(/\n/g,"\n"+t):e,s&&(u+="\n"),'"""'+u.replace(/"""/g,'\\"""')+'"""'}n.d(t,{LZ:()=>o,W7:()=>r})},97359(e,t,n){"use strict";n.d(t,{h:()=>r});var r=Object.freeze({NAME:"Name",DOCUMENT:"Document",OPERATION_DEFINITION:"OperationDefinition",VARIABLE_DEFINITION:"VariableDefinition",SELECTION_SET:"SelectionSet",FIELD:"Field",ARGUMENT:"Argument",FRAGMENT_SPREAD:"FragmentSpread",INLINE_FRAGMENT:"InlineFragment",FRAGMENT_DEFINITION:"FragmentDefinition",VARIABLE:"Variable",INT:"IntValue",FLOAT:"FloatValue",STRING:"StringValue",BOOLEAN:"BooleanValue",NULL:"NullValue",ENUM:"EnumValue",LIST:"ListValue",OBJECT:"ObjectValue",OBJECT_FIELD:"ObjectField",DIRECTIVE:"Directive",NAMED_TYPE:"NamedType",LIST_TYPE:"ListType",NON_NULL_TYPE:"NonNullType",SCHEMA_DEFINITION:"SchemaDefinition",OPERATION_TYPE_DEFINITION:"OperationTypeDefinition",SCALAR_TYPE_DEFINITION:"ScalarTypeDefinition",OBJECT_TYPE_DEFINITION:"ObjectTypeDefinition",FIELD_DEFINITION:"FieldDefinition",INPUT_VALUE_DEFINITION:"InputValueDefinition",INTERFACE_TYPE_DEFINITION:"InterfaceTypeDefinition",UNION_TYPE_DEFINITION:"UnionTypeDefinition",ENUM_TYPE_DEFINITION:"EnumTypeDefinition",ENUM_VALUE_DEFINITION:"EnumValueDefinition",INPUT_OBJECT_TYPE_DEFINITION:"InputObjectTypeDefinition",DIRECTIVE_DEFINITION:"DirectiveDefinition",SCHEMA_EXTENSION:"SchemaExtension",SCALAR_TYPE_EXTENSION:"ScalarTypeExtension",OBJECT_TYPE_EXTENSION:"ObjectTypeExtension",INTERFACE_TYPE_EXTENSION:"InterfaceTypeExtension",UNION_TYPE_EXTENSION:"UnionTypeExtension",ENUM_TYPE_EXTENSION:"EnumTypeExtension",INPUT_OBJECT_TYPE_EXTENSION:"InputObjectTypeExtension"})},10143(e,t,n){"use strict";n.d(t,{H:()=>c,T:()=>l});var r=n(99763),i=n(25821);function a(e,t){if(!Boolean(e))throw Error(t)}let o=function(e,t){return e instanceof t};function s(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:"GraphQL request",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{line:1,column:1};"string"==typeof e||a(0,"Body must be a string. Received: ".concat((0,i.Z)(e),".")),this.body=e,this.name=t,this.locationOffset=n,this.locationOffset.line>0||a(0,"line in locationOffset is 1-indexed and must be positive."),this.locationOffset.column>0||a(0,"column in locationOffset is 1-indexed and must be positive.")}return u(e,[{key:r.YF,get:function(){return"Source"}}]),e}();function l(e){return o(e,c)}},99763(e,t,n){"use strict";n.d(t,{YF:()=>r});var r="function"==typeof Symbol&&null!=Symbol.toStringTag?Symbol.toStringTag:"@@toStringTag"},37452(e){"use strict";e.exports=JSON.parse('{"AElig":"\xc6","AMP":"&","Aacute":"\xc1","Acirc":"\xc2","Agrave":"\xc0","Aring":"\xc5","Atilde":"\xc3","Auml":"\xc4","COPY":"\xa9","Ccedil":"\xc7","ETH":"\xd0","Eacute":"\xc9","Ecirc":"\xca","Egrave":"\xc8","Euml":"\xcb","GT":">","Iacute":"\xcd","Icirc":"\xce","Igrave":"\xcc","Iuml":"\xcf","LT":"<","Ntilde":"\xd1","Oacute":"\xd3","Ocirc":"\xd4","Ograve":"\xd2","Oslash":"\xd8","Otilde":"\xd5","Ouml":"\xd6","QUOT":"\\"","REG":"\xae","THORN":"\xde","Uacute":"\xda","Ucirc":"\xdb","Ugrave":"\xd9","Uuml":"\xdc","Yacute":"\xdd","aacute":"\xe1","acirc":"\xe2","acute":"\xb4","aelig":"\xe6","agrave":"\xe0","amp":"&","aring":"\xe5","atilde":"\xe3","auml":"\xe4","brvbar":"\xa6","ccedil":"\xe7","cedil":"\xb8","cent":"\xa2","copy":"\xa9","curren":"\xa4","deg":"\xb0","divide":"\xf7","eacute":"\xe9","ecirc":"\xea","egrave":"\xe8","eth":"\xf0","euml":"\xeb","frac12":"\xbd","frac14":"\xbc","frac34":"\xbe","gt":">","iacute":"\xed","icirc":"\xee","iexcl":"\xa1","igrave":"\xec","iquest":"\xbf","iuml":"\xef","laquo":"\xab","lt":"<","macr":"\xaf","micro":"\xb5","middot":"\xb7","nbsp":"\xa0","not":"\xac","ntilde":"\xf1","oacute":"\xf3","ocirc":"\xf4","ograve":"\xf2","ordf":"\xaa","ordm":"\xba","oslash":"\xf8","otilde":"\xf5","ouml":"\xf6","para":"\xb6","plusmn":"\xb1","pound":"\xa3","quot":"\\"","raquo":"\xbb","reg":"\xae","sect":"\xa7","shy":"\xad","sup1":"\xb9","sup2":"\xb2","sup3":"\xb3","szlig":"\xdf","thorn":"\xfe","times":"\xd7","uacute":"\xfa","ucirc":"\xfb","ugrave":"\xf9","uml":"\xa8","uuml":"\xfc","yacute":"\xfd","yen":"\xa5","yuml":"\xff"}')},93580(e){"use strict";e.exports=JSON.parse('{"0":"�","128":"€","130":"‚","131":"ƒ","132":"„","133":"…","134":"†","135":"‡","136":"ˆ","137":"‰","138":"Š","139":"‹","140":"Œ","142":"Ž","145":"‘","146":"’","147":"“","148":"”","149":"•","150":"–","151":"—","152":"˜","153":"™","154":"š","155":"›","156":"œ","158":"ž","159":"Ÿ"}')},67946(e){"use strict";e.exports=JSON.parse('{"locale":"en","long":{"year":{"previous":"last year","current":"this year","next":"next year","past":{"one":"{0} year ago","other":"{0} years ago"},"future":{"one":"in {0} year","other":"in {0} years"}},"quarter":{"previous":"last quarter","current":"this quarter","next":"next quarter","past":{"one":"{0} quarter ago","other":"{0} quarters ago"},"future":{"one":"in {0} quarter","other":"in {0} quarters"}},"month":{"previous":"last month","current":"this month","next":"next month","past":{"one":"{0} month ago","other":"{0} months ago"},"future":{"one":"in {0} month","other":"in {0} months"}},"week":{"previous":"last week","current":"this week","next":"next week","past":{"one":"{0} week ago","other":"{0} weeks ago"},"future":{"one":"in {0} week","other":"in {0} weeks"}},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":{"one":"{0} hour ago","other":"{0} hours ago"},"future":{"one":"in {0} hour","other":"in {0} hours"}},"minute":{"current":"this minute","past":{"one":"{0} minute ago","other":"{0} minutes ago"},"future":{"one":"in {0} minute","other":"in {0} minutes"}},"second":{"current":"now","past":{"one":"{0} second ago","other":"{0} seconds ago"},"future":{"one":"in {0} second","other":"in {0} seconds"}}},"short":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"narrow":{"year":{"previous":"last yr.","current":"this yr.","next":"next yr.","past":"{0} yr. ago","future":"in {0} yr."},"quarter":{"previous":"last qtr.","current":"this qtr.","next":"next qtr.","past":{"one":"{0} qtr. ago","other":"{0} qtrs. ago"},"future":{"one":"in {0} qtr.","other":"in {0} qtrs."}},"month":{"previous":"last mo.","current":"this mo.","next":"next mo.","past":"{0} mo. ago","future":"in {0} mo."},"week":{"previous":"last wk.","current":"this wk.","next":"next wk.","past":"{0} wk. ago","future":"in {0} wk."},"day":{"previous":"yesterday","current":"today","next":"tomorrow","past":{"one":"{0} day ago","other":"{0} days ago"},"future":{"one":"in {0} day","other":"in {0} days"}},"hour":{"current":"this hour","past":"{0} hr. ago","future":"in {0} hr."},"minute":{"current":"this minute","past":"{0} min. ago","future":"in {0} min."},"second":{"current":"now","past":"{0} sec. ago","future":"in {0} sec."}},"now":{"now":{"current":"now","future":"in a moment","past":"just now"}},"mini":{"year":"{0}yr","month":"{0}mo","week":"{0}wk","day":"{0}d","hour":"{0}h","minute":"{0}m","second":"{0}s","now":"now"},"short-time":{"year":"{0} yr.","month":"{0} mo.","week":"{0} wk.","day":{"one":"{0} day","other":"{0} days"},"hour":"{0} hr.","minute":"{0} min.","second":"{0} sec."},"long-time":{"year":{"one":"{0} year","other":"{0} years"},"month":{"one":"{0} month","other":"{0} months"},"week":{"one":"{0} week","other":"{0} weeks"},"day":{"one":"{0} day","other":"{0} days"},"hour":{"one":"{0} hour","other":"{0} hours"},"minute":{"one":"{0} minute","other":"{0} minutes"},"second":{"one":"{0} second","other":"{0} seconds"}}}')}},__webpack_module_cache__={};function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[e]={id:e,loaded:!1,exports:{}};return __webpack_modules__[e].call(n.exports,n,n.exports,__webpack_require__),n.loaded=!0,n.exports}__webpack_require__.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},(()=>{var e,t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__;__webpack_require__.t=function(n,r){if(1&r&&(n=this(n)),8&r||"object"==typeof n&&n&&(4&r&&n.__esModule||16&r&&"function"==typeof n.then))return n;var i=Object.create(null);__webpack_require__.r(i);var a={};e=e||[null,t({}),t([]),t(t)];for(var o=2&r&&n;"object"==typeof o&&!~e.indexOf(o);o=t(o))Object.getOwnPropertyNames(o).forEach(e=>a[e]=()=>n[e]);return a.default=()=>n,__webpack_require__.d(i,a),i}})(),__webpack_require__.d=(e,t)=>{for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.hmd=e=>((e=Object.create(e)).children||(e.children=[]),Object.defineProperty(e,"exports",{enumerable:!0,set(){throw Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+e.id)}}),e),__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},__webpack_require__.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),__webpack_require__.p="/assets/",__webpack_require__.nc=void 0;var __webpack_exports__={};(()=>{"use strict";var e,t,n,r,i=__webpack_require__(32316),a=__webpack_require__(8126),o=__webpack_require__(5690),s=__webpack_require__(30381),u=__webpack_require__.n(s),c=__webpack_require__(67294),l=__webpack_require__(73935),f=__webpack_require__.n(l),d=__webpack_require__(57209),h=__webpack_require__(37703),p=__webpack_require__(97779),b=__webpack_require__(28500);function m(e){return function(t){var n=t.dispatch,r=t.getState;return function(t){return function(i){return"function"==typeof i?i(n,r,e):t(i)}}}}var g=m();g.withExtraArgument=m;let v=g;var y=__webpack_require__(76489);function w(e){return function(t){return function(n){return function(r){n(r);var i=e||document&&document.cookie||"",a=t.getState();if("MATCH_ROUTE"===r.type&&"/signin"!==a.notifications.currentUrl){var o=(0,y.Q)(i);if(o.explorer)try{var s=JSON.parse(o.explorer);if("error"===s.status){var u=_(s.url);n({type:"NOTIFY_ERROR_MSG",msg:u})}}catch(c){n({type:"NOTIFY_ERROR_MSG",msg:"Invalid explorer status"})}}}}}}function _(e){var t="Can't connect to explorer: ".concat(e);return e.match(/^wss?:.+/)?t:"".concat(t,". You must use a websocket.")}var E=__webpack_require__(16353);function S(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function ei(e,t){if(e){if("string"==typeof e)return ea(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return ea(e,t)}}function ea(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n1,i=!1,a=arguments[1],o=a;return new n(function(n){return t.subscribe({next:function(t){var a=!i;if(i=!0,!a||r)try{o=e(o,t)}catch(s){return n.error(s)}else o=t},error:function(e){n.error(e)},complete:function(){if(!i&&!r)return n.error(TypeError("Cannot reduce an empty sequence"));n.next(o),n.complete()}})})},t.concat=function(){for(var e=this,t=arguments.length,n=Array(t),r=0;r=0&&i.splice(e,1),o()}});i.push(s)},error:function(e){r.error(e)},complete:function(){o()}});function o(){a.closed&&0===i.length&&r.complete()}return function(){i.forEach(function(e){return e.unsubscribe()}),a.unsubscribe()}})},t[ed]=function(){return this},e.from=function(t){var n="function"==typeof this?this:e;if(null==t)throw TypeError(t+" is not an object");var r=ep(t,ed);if(r){var i=r.call(t);if(Object(i)!==i)throw TypeError(i+" is not an object");return em(i)&&i.constructor===n?i:new n(function(e){return i.subscribe(e)})}if(ec("iterator")&&(r=ep(t,ef)))return new n(function(e){ev(function(){if(!e.closed){for(var n,i=er(r.call(t));!(n=i()).done;){var a=n.value;if(e.next(a),e.closed)return}e.complete()}})});if(Array.isArray(t))return new n(function(e){ev(function(){if(!e.closed){for(var n=0;n0))return n.connection.key;var r=n.connection.filter?n.connection.filter:[];r.sort();var i={};return r.forEach(function(e){i[e]=t[e]}),"".concat(n.connection.key,"(").concat(eV(i),")")}var a=e;if(t){var o=eV(t);a+="(".concat(o,")")}return n&&Object.keys(n).forEach(function(e){-1===eW.indexOf(e)&&(n[e]&&Object.keys(n[e]).length?a+="@".concat(e,"(").concat(eV(n[e]),")"):a+="@".concat(e))}),a},{setStringify:function(e){var t=eV;return eV=e,t}}),eV=function(e){return JSON.stringify(e,eq)};function eq(e,t){return(0,eO.s)(t)&&!Array.isArray(t)&&(t=Object.keys(t).sort().reduce(function(e,n){return e[n]=t[n],e},{})),t}function eZ(e,t){if(e.arguments&&e.arguments.length){var n={};return e.arguments.forEach(function(e){var r;return ez(n,e.name,e.value,t)}),n}return null}function eX(e){return e.alias?e.alias.value:e.name.value}function eJ(e,t,n){for(var r,i=0,a=t.selections;it.indexOf(i))throw __DEV__?new Q.ej("illegal argument: ".concat(i)):new Q.ej(27)}return e}function tt(e,t){return t?t(e):eT.of()}function tn(e){return"function"==typeof e?new ta(e):e}function tr(e){return e.request.length<=1}var ti=function(e){function t(t,n){var r=e.call(this,t)||this;return r.link=n,r}return(0,en.ZT)(t,e),t}(Error),ta=function(){function e(e){e&&(this.request=e)}return e.empty=function(){return new e(function(){return eT.of()})},e.from=function(t){return 0===t.length?e.empty():t.map(tn).reduce(function(e,t){return e.concat(t)})},e.split=function(t,n,r){var i=tn(n),a=tn(r||new e(tt));return new e(tr(i)&&tr(a)?function(e){return t(e)?i.request(e)||eT.of():a.request(e)||eT.of()}:function(e,n){return t(e)?i.request(e,n)||eT.of():a.request(e,n)||eT.of()})},e.execute=function(e,t){return e.request(eM(t.context,e7(te(t))))||eT.of()},e.concat=function(t,n){var r=tn(t);if(tr(r))return __DEV__&&Q.kG.warn(new ti("You are calling concat on a terminating link, which will have no effect",r)),r;var i=tn(n);return new e(tr(i)?function(e){return r.request(e,function(e){return i.request(e)||eT.of()})||eT.of()}:function(e,t){return r.request(e,function(e){return i.request(e,t)||eT.of()})||eT.of()})},e.prototype.split=function(t,n,r){return this.concat(e.split(t,n,r||new e(tt)))},e.prototype.concat=function(t){return e.concat(this,t)},e.prototype.request=function(e,t){throw __DEV__?new Q.ej("request is not implemented"):new Q.ej(22)},e.prototype.onError=function(e,t){if(t&&t.error)return t.error(e),!1;throw e},e.prototype.setOnError=function(e){return this.onError=e,this},e}(),to=__webpack_require__(25821),ts=__webpack_require__(25217),tu={Name:[],Document:["definitions"],OperationDefinition:["name","variableDefinitions","directives","selectionSet"],VariableDefinition:["variable","type","defaultValue","directives"],Variable:["name"],SelectionSet:["selections"],Field:["alias","name","arguments","directives","selectionSet"],Argument:["name","value"],FragmentSpread:["name","directives"],InlineFragment:["typeCondition","directives","selectionSet"],FragmentDefinition:["name","variableDefinitions","typeCondition","directives","selectionSet"],IntValue:[],FloatValue:[],StringValue:[],BooleanValue:[],NullValue:[],EnumValue:[],ListValue:["values"],ObjectValue:["fields"],ObjectField:["name","value"],Directive:["name","arguments"],NamedType:["name"],ListType:["type"],NonNullType:["type"],SchemaDefinition:["description","directives","operationTypes"],OperationTypeDefinition:["type"],ScalarTypeDefinition:["description","name","directives"],ObjectTypeDefinition:["description","name","interfaces","directives","fields"],FieldDefinition:["description","name","arguments","type","directives"],InputValueDefinition:["description","name","type","defaultValue","directives"],InterfaceTypeDefinition:["description","name","interfaces","directives","fields"],UnionTypeDefinition:["description","name","directives","types"],EnumTypeDefinition:["description","name","directives","values"],EnumValueDefinition:["description","name","directives"],InputObjectTypeDefinition:["description","name","directives","fields"],DirectiveDefinition:["description","name","arguments","locations"],SchemaExtension:["directives","operationTypes"],ScalarTypeExtension:["name","directives"],ObjectTypeExtension:["name","interfaces","directives","fields"],InterfaceTypeExtension:["name","interfaces","directives","fields"],UnionTypeExtension:["name","directives","types"],EnumTypeExtension:["name","directives","values"],InputObjectTypeExtension:["name","directives","fields"]},tc=Object.freeze({});function tl(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:tu,r=void 0,i=Array.isArray(e),a=[e],o=-1,s=[],u=void 0,c=void 0,l=void 0,f=[],d=[],h=e;do{var p,b=++o===a.length,m=b&&0!==s.length;if(b){if(c=0===d.length?void 0:f[f.length-1],u=l,l=d.pop(),m){if(i)u=u.slice();else{for(var g={},v=0,y=Object.keys(u);v1)for(var r=new tB,i=1;i=0;--a){var o=i[a],s=isNaN(+o)?{}:[];s[o]=t,t=s}n=r.merge(n,t)}),n}var tW=Object.prototype.hasOwnProperty;function tK(e,t){var n,r,i,a,o;return(0,en.mG)(this,void 0,void 0,function(){var s,u,c,l,f,d,h,p,b,m,g,v,y,w,_,E,S,k,x,T,M,O,A;return(0,en.Jh)(this,function(L){switch(L.label){case 0:if(void 0===TextDecoder)throw Error("TextDecoder must be defined in the environment: please import a polyfill.");s=new TextDecoder("utf-8"),u=null===(n=e.headers)||void 0===n?void 0:n.get("content-type"),c="boundary=",l=(null==u?void 0:u.includes(c))?null==u?void 0:u.substring((null==u?void 0:u.indexOf(c))+c.length).replace(/['"]/g,"").replace(/\;(.*)/gm,"").trim():"-",f="\r\n--".concat(l),d="",h=tI(e),p=!0,L.label=1;case 1:if(!p)return[3,3];return[4,h.next()];case 2:for(m=(b=L.sent()).value,g=b.done,v="string"==typeof m?m:s.decode(m),y=d.length-f.length+1,p=!g,d+=v,w=d.indexOf(f,y);w>-1;){if(_=void 0,_=(O=[d.slice(0,w),d.slice(w+f.length),])[0],d=O[1],E=_.indexOf("\r\n\r\n"),(k=(S=tV(_.slice(0,E)))["content-type"])&&-1===k.toLowerCase().indexOf("application/json"))throw Error("Unsupported patch content type: application/json is required.");if(x=_.slice(E))try{T=tq(e,x),Object.keys(T).length>1||"data"in T||"incremental"in T||"errors"in T||"payload"in T?tz(T)?(M={},"payload"in T&&(M=(0,en.pi)({},T.payload)),"errors"in T&&(M=(0,en.pi)((0,en.pi)({},M),{extensions:(0,en.pi)((0,en.pi)({},"extensions"in M?M.extensions:null),((A={})[tN.YG]=T.errors,A))})),null===(r=t.next)||void 0===r||r.call(t,M)):null===(i=t.next)||void 0===i||i.call(t,T):1===Object.keys(T).length&&"hasNext"in T&&!T.hasNext&&(null===(a=t.complete)||void 0===a||a.call(t))}catch(C){tZ(C,t)}w=d.indexOf(f)}return[3,1];case 3:return null===(o=t.complete)||void 0===o||o.call(t),[2]}})})}function tV(e){var t={};return e.split("\n").forEach(function(e){var n=e.indexOf(":");if(n>-1){var r=e.slice(0,n).trim().toLowerCase(),i=e.slice(n+1).trim();t[r]=i}}),t}function tq(e,t){e.status>=300&&tD(e,function(){try{return JSON.parse(t)}catch(e){return t}}(),"Response not successful: Received status code ".concat(e.status));try{return JSON.parse(t)}catch(n){var r=n;throw r.name="ServerParseError",r.response=e,r.statusCode=e.status,r.bodyText=t,r}}function tZ(e,t){var n,r;"AbortError"!==e.name&&(e.result&&e.result.errors&&e.result.data&&(null===(n=t.next)||void 0===n||n.call(t,e.result)),null===(r=t.error)||void 0===r||r.call(t,e))}function tX(e,t,n){tJ(t)(e).then(function(e){var t,r;null===(t=n.next)||void 0===t||t.call(n,e),null===(r=n.complete)||void 0===r||r.call(n)}).catch(function(e){return tZ(e,n)})}function tJ(e){return function(t){return t.text().then(function(e){return tq(t,e)}).then(function(n){return t.status>=300&&tD(t,n,"Response not successful: Received status code ".concat(t.status)),Array.isArray(n)||tW.call(n,"data")||tW.call(n,"errors")||tD(t,n,"Server response was missing for query '".concat(Array.isArray(e)?e.map(function(e){return e.operationName}):e.operationName,"'.")),n})}}var tQ=function(e){if(!e&&"undefined"==typeof fetch)throw __DEV__?new Q.ej("\n\"fetch\" has not been found globally and no fetcher has been configured. To fix this, install a fetch package (like https://www.npmjs.com/package/cross-fetch), instantiate the fetcher, and pass it into your HttpLink constructor. For example:\n\nimport fetch from 'cross-fetch';\nimport { ApolloClient, HttpLink } from '@apollo/client';\nconst client = new ApolloClient({\n link: new HttpLink({ uri: '/graphql', fetch })\n});\n "):new Q.ej(23)},t1=__webpack_require__(87392);function t0(e){return tl(e,{leave:t3})}var t2=80,t3={Name:function(e){return e.value},Variable:function(e){return"$"+e.name},Document:function(e){return t6(e.definitions,"\n\n")+"\n"},OperationDefinition:function(e){var t=e.operation,n=e.name,r=t8("(",t6(e.variableDefinitions,", "),")"),i=t6(e.directives," "),a=e.selectionSet;return n||i||r||"query"!==t?t6([t,t6([n,r]),i,a]," "):a},VariableDefinition:function(e){var t=e.variable,n=e.type,r=e.defaultValue,i=e.directives;return t+": "+n+t8(" = ",r)+t8(" ",t6(i," "))},SelectionSet:function(e){return t5(e.selections)},Field:function(e){var t=e.alias,n=e.name,r=e.arguments,i=e.directives,a=e.selectionSet,o=t8("",t,": ")+n,s=o+t8("(",t6(r,", "),")");return s.length>t2&&(s=o+t8("(\n",t9(t6(r,"\n")),"\n)")),t6([s,t6(i," "),a]," ")},Argument:function(e){var t;return e.name+": "+e.value},FragmentSpread:function(e){var t;return"..."+e.name+t8(" ",t6(e.directives," "))},InlineFragment:function(e){var t=e.typeCondition,n=e.directives,r=e.selectionSet;return t6(["...",t8("on ",t),t6(n," "),r]," ")},FragmentDefinition:function(e){var t=e.name,n=e.typeCondition,r=e.variableDefinitions,i=e.directives,a=e.selectionSet;return"fragment ".concat(t).concat(t8("(",t6(r,", "),")")," ")+"on ".concat(n," ").concat(t8("",t6(i," ")," "))+a},IntValue:function(e){return e.value},FloatValue:function(e){return e.value},StringValue:function(e,t){var n=e.value;return e.block?(0,t1.LZ)(n,"description"===t?"":" "):JSON.stringify(n)},BooleanValue:function(e){return e.value?"true":"false"},NullValue:function(){return"null"},EnumValue:function(e){return e.value},ListValue:function(e){return"["+t6(e.values,", ")+"]"},ObjectValue:function(e){return"{"+t6(e.fields,", ")+"}"},ObjectField:function(e){var t;return e.name+": "+e.value},Directive:function(e){var t;return"@"+e.name+t8("(",t6(e.arguments,", "),")")},NamedType:function(e){return e.name},ListType:function(e){return"["+e.type+"]"},NonNullType:function(e){return e.type+"!"},SchemaDefinition:t4(function(e){var t=e.directives,n=e.operationTypes;return t6(["schema",t6(t," "),t5(n)]," ")}),OperationTypeDefinition:function(e){var t;return e.operation+": "+e.type},ScalarTypeDefinition:t4(function(e){var t;return t6(["scalar",e.name,t6(e.directives," ")]," ")}),ObjectTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["type",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")}),FieldDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.type,i=e.directives;return t+(ne(n)?t8("(\n",t9(t6(n,"\n")),"\n)"):t8("(",t6(n,", "),")"))+": "+r+t8(" ",t6(i," "))}),InputValueDefinition:t4(function(e){var t=e.name,n=e.type,r=e.defaultValue,i=e.directives;return t6([t+": "+n,t8("= ",r),t6(i," ")]," ")}),InterfaceTypeDefinition:t4(function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["interface",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")}),UnionTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.types;return t6(["union",t,t6(n," "),r&&0!==r.length?"= "+t6(r," | "):""]," ")}),EnumTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.values;return t6(["enum",t,t6(n," "),t5(r)]," ")}),EnumValueDefinition:t4(function(e){var t;return t6([e.name,t6(e.directives," ")]," ")}),InputObjectTypeDefinition:t4(function(e){var t=e.name,n=e.directives,r=e.fields;return t6(["input",t,t6(n," "),t5(r)]," ")}),DirectiveDefinition:t4(function(e){var t=e.name,n=e.arguments,r=e.repeatable,i=e.locations;return"directive @"+t+(ne(n)?t8("(\n",t9(t6(n,"\n")),"\n)"):t8("(",t6(n,", "),")"))+(r?" repeatable":"")+" on "+t6(i," | ")}),SchemaExtension:function(e){var t=e.directives,n=e.operationTypes;return t6(["extend schema",t6(t," "),t5(n)]," ")},ScalarTypeExtension:function(e){var t;return t6(["extend scalar",e.name,t6(e.directives," ")]," ")},ObjectTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["extend type",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")},InterfaceTypeExtension:function(e){var t=e.name,n=e.interfaces,r=e.directives,i=e.fields;return t6(["extend interface",t,t8("implements ",t6(n," & ")),t6(r," "),t5(i)]," ")},UnionTypeExtension:function(e){var t=e.name,n=e.directives,r=e.types;return t6(["extend union",t,t6(n," "),r&&0!==r.length?"= "+t6(r," | "):""]," ")},EnumTypeExtension:function(e){var t=e.name,n=e.directives,r=e.values;return t6(["extend enum",t,t6(n," "),t5(r)]," ")},InputObjectTypeExtension:function(e){var t=e.name,n=e.directives,r=e.fields;return t6(["extend input",t,t6(n," "),t5(r)]," ")}};function t4(e){return function(t){return t6([t.description,e(t)],"\n")}}function t6(e){var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return null!==(t=null==e?void 0:e.filter(function(e){return e}).join(n))&&void 0!==t?t:""}function t5(e){return t8("{\n",t9(t6(e,"\n")),"\n}")}function t8(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return null!=t&&""!==t?e+t+n:""}function t9(e){return t8(" ",e.replace(/\n/g,"\n "))}function t7(e){return -1!==e.indexOf("\n")}function ne(e){return null!=e&&e.some(t7)}var nt,nn,nr,ni={http:{includeQuery:!0,includeExtensions:!1,preserveHeaderCase:!1},headers:{accept:"*/*","content-type":"application/json"},options:{method:"POST"}},na=function(e,t){return t(e)};function no(e,t){for(var n=[],r=2;rObject.create(null),{forEach:nv,slice:ny}=Array.prototype,{hasOwnProperty:nw}=Object.prototype;class n_{constructor(e=!0,t=ng){this.weakness=e,this.makeData=t}lookup(...e){return this.lookupArray(e)}lookupArray(e){let t=this;return nv.call(e,e=>t=t.getChildTrie(e)),nw.call(t,"data")?t.data:t.data=this.makeData(ny.call(e))}peek(...e){return this.peekArray(e)}peekArray(e){let t=this;for(let n=0,r=e.length;t&&n=0;--o)t.definitions[o].kind===nL.h.OPERATION_DEFINITION&&++a;var s=nN(e),u=e.some(function(e){return e.remove}),c=function(e){return u&&e&&e.some(s)},l=new Map,f=!1,d={enter:function(e){if(c(e.directives))return f=!0,null}},h=tl(t,{Field:d,InlineFragment:d,VariableDefinition:{enter:function(){return!1}},Variable:{enter:function(e,t,n,r,a){var o=i(a);o&&o.variables.add(e.name.value)}},FragmentSpread:{enter:function(e,t,n,r,a){if(c(e.directives))return f=!0,null;var o=i(a);o&&o.fragmentSpreads.add(e.name.value)}},FragmentDefinition:{enter:function(e,t,n,r){l.set(JSON.stringify(r),e)},leave:function(e,t,n,i){return e===l.get(JSON.stringify(i))?e:a>0&&e.selectionSet.selections.every(function(e){return e.kind===nL.h.FIELD&&"__typename"===e.name.value})?(r(e.name.value).removed=!0,f=!0,null):void 0}},Directive:{leave:function(e){if(s(e))return f=!0,null}}});if(!f)return t;var p=function(e){return e.transitiveVars||(e.transitiveVars=new Set(e.variables),e.removed||e.fragmentSpreads.forEach(function(t){p(r(t)).transitiveVars.forEach(function(t){e.transitiveVars.add(t)})})),e},b=new Set;h.definitions.forEach(function(e){e.kind===nL.h.OPERATION_DEFINITION?p(n(e.name&&e.name.value)).fragmentSpreads.forEach(function(e){b.add(e)}):e.kind!==nL.h.FRAGMENT_DEFINITION||0!==a||r(e.name.value).removed||b.add(e.name.value)}),b.forEach(function(e){p(r(e)).fragmentSpreads.forEach(function(e){b.add(e)})});var m=function(e){return!!(!b.has(e)||r(e).removed)},g={enter:function(e){if(m(e.name.value))return null}};return nD(tl(h,{FragmentSpread:g,FragmentDefinition:g,OperationDefinition:{leave:function(e){if(e.variableDefinitions){var t=p(n(e.name&&e.name.value)).transitiveVars;if(t.size0},t.prototype.tearDownQuery=function(){this.isTornDown||(this.concast&&this.observer&&(this.concast.removeObserver(this.observer),delete this.concast,delete this.observer),this.stopPolling(),this.subscriptions.forEach(function(e){return e.unsubscribe()}),this.subscriptions.clear(),this.queryManager.stopQuery(this.queryId),this.observers.clear(),this.isTornDown=!0)},t}(eT);function n4(e){var t=e.options,n=t.fetchPolicy,r=t.nextFetchPolicy;return"cache-and-network"===n||"network-only"===n?e.reobserve({fetchPolicy:"cache-first",nextFetchPolicy:function(){return(this.nextFetchPolicy=r,"function"==typeof r)?r.apply(this,arguments):n}}):e.reobserve()}function n6(e){__DEV__&&Q.kG.error("Unhandled error",e.message,e.stack)}function n5(e){__DEV__&&e&&__DEV__&&Q.kG.debug("Missing cache result fields: ".concat(JSON.stringify(e)),e)}function n8(e){return"network-only"===e||"no-cache"===e||"standby"===e}nK(n3);function n9(e){return e.kind===nL.h.FIELD||e.kind===nL.h.FRAGMENT_SPREAD||e.kind===nL.h.INLINE_FRAGMENT}function n7(e){return e.kind===Kind.SCALAR_TYPE_DEFINITION||e.kind===Kind.OBJECT_TYPE_DEFINITION||e.kind===Kind.INTERFACE_TYPE_DEFINITION||e.kind===Kind.UNION_TYPE_DEFINITION||e.kind===Kind.ENUM_TYPE_DEFINITION||e.kind===Kind.INPUT_OBJECT_TYPE_DEFINITION}function re(e){return e.kind===Kind.SCALAR_TYPE_EXTENSION||e.kind===Kind.OBJECT_TYPE_EXTENSION||e.kind===Kind.INTERFACE_TYPE_EXTENSION||e.kind===Kind.UNION_TYPE_EXTENSION||e.kind===Kind.ENUM_TYPE_EXTENSION||e.kind===Kind.INPUT_OBJECT_TYPE_EXTENSION}var rt=function(){return Object.create(null)},rn=Array.prototype,rr=rn.forEach,ri=rn.slice,ra=function(){function e(e,t){void 0===e&&(e=!0),void 0===t&&(t=rt),this.weakness=e,this.makeData=t}return e.prototype.lookup=function(){for(var e=[],t=0;tclass{constructor(){this.id=["slot",rc++,Date.now(),Math.random().toString(36).slice(2),].join(":")}hasValue(){for(let e=rs;e;e=e.parent)if(this.id in e.slots){let t=e.slots[this.id];if(t===ru)break;return e!==rs&&(rs.slots[this.id]=t),!0}return rs&&(rs.slots[this.id]=ru),!1}getValue(){if(this.hasValue())return rs.slots[this.id]}withValue(e,t,n,r){let i={__proto__:null,[this.id]:e},a=rs;rs={parent:a,slots:i};try{return t.apply(r,n)}finally{rs=a}}static bind(e){let t=rs;return function(){let n=rs;try{return rs=t,e.apply(this,arguments)}finally{rs=n}}}static noContext(e,t,n){if(!rs)return e.apply(n,t);{let r=rs;try{return rs=null,e.apply(n,t)}finally{rs=r}}}};function rf(e){try{return e()}catch(t){}}let rd="@wry/context:Slot",rh=rf(()=>globalThis)||rf(()=>global)||Object.create(null),rp=rh,rb=rp[rd]||Array[rd]||function(e){try{Object.defineProperty(rp,rd,{value:e,enumerable:!1,writable:!1,configurable:!0})}finally{return e}}(rl()),{bind:rm,noContext:rg}=rb;function rv(){}var ry=function(){function e(e,t){void 0===e&&(e=1/0),void 0===t&&(t=rv),this.max=e,this.dispose=t,this.map=new Map,this.newest=null,this.oldest=null}return e.prototype.has=function(e){return this.map.has(e)},e.prototype.get=function(e){var t=this.getNode(e);return t&&t.value},e.prototype.getNode=function(e){var t=this.map.get(e);if(t&&t!==this.newest){var n=t.older,r=t.newer;r&&(r.older=n),n&&(n.newer=r),t.older=this.newest,t.older.newer=t,t.newer=null,this.newest=t,t===this.oldest&&(this.oldest=r)}return t},e.prototype.set=function(e,t){var n=this.getNode(e);return n?n.value=t:(n={key:e,value:t,newer:null,older:this.newest},this.newest&&(this.newest.newer=n),this.newest=n,this.oldest=this.oldest||n,this.map.set(e,n),n.value)},e.prototype.clean=function(){for(;this.oldest&&this.map.size>this.max;)this.delete(this.oldest.key)},e.prototype.delete=function(e){var t=this.map.get(e);return!!t&&(t===this.newest&&(this.newest=t.older),t===this.oldest&&(this.oldest=t.newer),t.newer&&(t.newer.older=t.older),t.older&&(t.older.newer=t.newer),this.map.delete(e),this.dispose(t.value,e),!0)},e}(),rw=new rb,r_=Object.prototype.hasOwnProperty,rE=void 0===(n=Array.from)?function(e){var t=[];return e.forEach(function(e){return t.push(e)}),t}:n;function rS(e){var t=e.unsubscribe;"function"==typeof t&&(e.unsubscribe=void 0,t())}var rk=[],rx=100;function rT(e,t){if(!e)throw Error(t||"assertion failure")}function rM(e,t){var n=e.length;return n>0&&n===t.length&&e[n-1]===t[n-1]}function rO(e){switch(e.length){case 0:throw Error("unknown value");case 1:return e[0];case 2:throw e[1]}}function rA(e){return e.slice(0)}var rL=function(){function e(t){this.fn=t,this.parents=new Set,this.childValues=new Map,this.dirtyChildren=null,this.dirty=!0,this.recomputing=!1,this.value=[],this.deps=null,++e.count}return e.prototype.peek=function(){if(1===this.value.length&&!rN(this))return rC(this),this.value[0]},e.prototype.recompute=function(e){return rT(!this.recomputing,"already recomputing"),rC(this),rN(this)?rI(this,e):rO(this.value)},e.prototype.setDirty=function(){this.dirty||(this.dirty=!0,this.value.length=0,rR(this),rS(this))},e.prototype.dispose=function(){var e=this;this.setDirty(),rH(this),rF(this,function(t,n){t.setDirty(),r$(t,e)})},e.prototype.forget=function(){this.dispose()},e.prototype.dependOn=function(e){e.add(this),this.deps||(this.deps=rk.pop()||new Set),this.deps.add(e)},e.prototype.forgetDeps=function(){var e=this;this.deps&&(rE(this.deps).forEach(function(t){return t.delete(e)}),this.deps.clear(),rk.push(this.deps),this.deps=null)},e.count=0,e}();function rC(e){var t=rw.getValue();if(t)return e.parents.add(t),t.childValues.has(e)||t.childValues.set(e,[]),rN(e)?rY(t,e):rB(t,e),t}function rI(e,t){return rH(e),rw.withValue(e,rD,[e,t]),rz(e,t)&&rP(e),rO(e.value)}function rD(e,t){e.recomputing=!0,e.value.length=0;try{e.value[0]=e.fn.apply(null,t)}catch(n){e.value[1]=n}e.recomputing=!1}function rN(e){return e.dirty||!!(e.dirtyChildren&&e.dirtyChildren.size)}function rP(e){e.dirty=!1,!rN(e)&&rj(e)}function rR(e){rF(e,rY)}function rj(e){rF(e,rB)}function rF(e,t){var n=e.parents.size;if(n)for(var r=rE(e.parents),i=0;i0&&e.childValues.forEach(function(t,n){r$(e,n)}),e.forgetDeps(),rT(null===e.dirtyChildren)}function r$(e,t){t.parents.delete(e),e.childValues.delete(t),rU(e,t)}function rz(e,t){if("function"==typeof e.subscribe)try{rS(e),e.unsubscribe=e.subscribe.apply(null,t)}catch(n){return e.setDirty(),!1}return!0}var rG={setDirty:!0,dispose:!0,forget:!0};function rW(e){var t=new Map,n=e&&e.subscribe;function r(e){var r=rw.getValue();if(r){var i=t.get(e);i||t.set(e,i=new Set),r.dependOn(i),"function"==typeof n&&(rS(i),i.unsubscribe=n(e))}}return r.dirty=function(e,n){var r=t.get(e);if(r){var i=n&&r_.call(rG,n)?n:"setDirty";rE(r).forEach(function(e){return e[i]()}),t.delete(e),rS(r)}},r}function rK(){var e=new ra("function"==typeof WeakMap);return function(){return e.lookupArray(arguments)}}var rV=rK(),rq=new Set;function rZ(e,t){void 0===t&&(t=Object.create(null));var n=new ry(t.max||65536,function(e){return e.dispose()}),r=t.keyArgs,i=t.makeCacheKey||rK(),a=function(){var a=i.apply(null,r?r.apply(null,arguments):arguments);if(void 0===a)return e.apply(null,arguments);var o=n.get(a);o||(n.set(a,o=new rL(e)),o.subscribe=t.subscribe,o.forget=function(){return n.delete(a)});var s=o.recompute(Array.prototype.slice.call(arguments));return n.set(a,o),rq.add(n),rw.hasValue()||(rq.forEach(function(e){return e.clean()}),rq.clear()),s};function o(e){var t=n.get(e);t&&t.setDirty()}function s(e){var t=n.get(e);if(t)return t.peek()}function u(e){return n.delete(e)}return Object.defineProperty(a,"size",{get:function(){return n.map.size},configurable:!1,enumerable:!1}),a.dirtyKey=o,a.dirty=function(){o(i.apply(null,arguments))},a.peekKey=s,a.peek=function(){return s(i.apply(null,arguments))},a.forgetKey=u,a.forget=function(){return u(i.apply(null,arguments))},a.makeCacheKey=i,a.getKey=r?function(){return i.apply(null,r.apply(null,arguments))}:i,Object.freeze(a)}var rX=new rb,rJ=new WeakMap;function rQ(e){var t=rJ.get(e);return t||rJ.set(e,t={vars:new Set,dep:rW()}),t}function r1(e){rQ(e).vars.forEach(function(t){return t.forgetCache(e)})}function r0(e){rQ(e).vars.forEach(function(t){return t.attachCache(e)})}function r2(e){var t=new Set,n=new Set,r=function(a){if(arguments.length>0){if(e!==a){e=a,t.forEach(function(e){rQ(e).dep.dirty(r),r3(e)});var o=Array.from(n);n.clear(),o.forEach(function(t){return t(e)})}}else{var s=rX.getValue();s&&(i(s),rQ(s).dep(r))}return e};r.onNextChange=function(e){return n.add(e),function(){n.delete(e)}};var i=r.attachCache=function(e){return t.add(e),rQ(e).vars.add(r),r};return r.forgetCache=function(e){return t.delete(e)},r}function r3(e){e.broadcastWatches&&e.broadcastWatches()}var r4=function(){function e(e){var t=e.cache,n=e.client,r=e.resolvers,i=e.fragmentMatcher;this.selectionsToResolveCache=new WeakMap,this.cache=t,n&&(this.client=n),r&&this.addResolvers(r),i&&this.setFragmentMatcher(i)}return e.prototype.addResolvers=function(e){var t=this;this.resolvers=this.resolvers||{},Array.isArray(e)?e.forEach(function(e){t.resolvers=tj(t.resolvers,e)}):this.resolvers=tj(this.resolvers,e)},e.prototype.setResolvers=function(e){this.resolvers={},this.addResolvers(e)},e.prototype.getResolvers=function(){return this.resolvers||{}},e.prototype.runResolvers=function(e){var t=e.document,n=e.remoteResult,r=e.context,i=e.variables,a=e.onlyRunForcedResolvers,o=void 0!==a&&a;return(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(e){return t?[2,this.resolveDocument(t,n.data,r,i,this.fragmentMatcher,o).then(function(e){return(0,en.pi)((0,en.pi)({},n),{data:e.result})})]:[2,n]})})},e.prototype.setFragmentMatcher=function(e){this.fragmentMatcher=e},e.prototype.getFragmentMatcher=function(){return this.fragmentMatcher},e.prototype.clientQuery=function(e){return tb(["client"],e)&&this.resolvers?e:null},e.prototype.serverQuery=function(e){return n$(e)},e.prototype.prepareContext=function(e){var t=this.cache;return(0,en.pi)((0,en.pi)({},e),{cache:t,getCacheKey:function(e){return t.identify(e)}})},e.prototype.addExportedVariables=function(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),(0,en.mG)(this,void 0,void 0,function(){return(0,en.Jh)(this,function(r){return e?[2,this.resolveDocument(e,this.buildRootValueFromCache(e,t)||{},this.prepareContext(n),t).then(function(e){return(0,en.pi)((0,en.pi)({},t),e.exportedVariables)})]:[2,(0,en.pi)({},t)]})})},e.prototype.shouldForceResolvers=function(e){var t=!1;return tl(e,{Directive:{enter:function(e){if("client"===e.name.value&&e.arguments&&(t=e.arguments.some(function(e){return"always"===e.name.value&&"BooleanValue"===e.value.kind&&!0===e.value.value})))return tc}}}),t},e.prototype.buildRootValueFromCache=function(e,t){return this.cache.diff({query:nH(e),variables:t,returnPartialData:!0,optimistic:!1}).result},e.prototype.resolveDocument=function(e,t,n,r,i,a){return void 0===n&&(n={}),void 0===r&&(r={}),void 0===i&&(i=function(){return!0}),void 0===a&&(a=!1),(0,en.mG)(this,void 0,void 0,function(){var o,s,u,c,l,f,d,h,p,b,m;return(0,en.Jh)(this,function(g){return o=e8(e),s=e4(e),u=eL(s),c=this.collectSelectionsToResolve(o,u),f=(l=o.operation)?l.charAt(0).toUpperCase()+l.slice(1):"Query",d=this,h=d.cache,p=d.client,b={fragmentMap:u,context:(0,en.pi)((0,en.pi)({},n),{cache:h,client:p}),variables:r,fragmentMatcher:i,defaultOperationType:f,exportedVariables:{},selectionsToResolve:c,onlyRunForcedResolvers:a},m=!1,[2,this.resolveSelectionSet(o.selectionSet,m,t,b).then(function(e){return{result:e,exportedVariables:b.exportedVariables}})]})})},e.prototype.resolveSelectionSet=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c=this;return(0,en.Jh)(this,function(l){return i=r.fragmentMap,a=r.context,o=r.variables,s=[n],u=function(e){return(0,en.mG)(c,void 0,void 0,function(){var u,c;return(0,en.Jh)(this,function(l){return(t||r.selectionsToResolve.has(e))&&td(e,o)?eQ(e)?[2,this.resolveField(e,t,n,r).then(function(t){var n;void 0!==t&&s.push(((n={})[eX(e)]=t,n))})]:(e1(e)?u=e:(u=i[e.name.value],__DEV__?(0,Q.kG)(u,"No fragment named ".concat(e.name.value)):(0,Q.kG)(u,11)),u&&u.typeCondition&&(c=u.typeCondition.name.value,r.fragmentMatcher(n,c,a)))?[2,this.resolveSelectionSet(u.selectionSet,t,n,r).then(function(e){s.push(e)})]:[2]:[2]})})},[2,Promise.all(e.selections.map(u)).then(function(){return tF(s)})]})})},e.prototype.resolveField=function(e,t,n,r){return(0,en.mG)(this,void 0,void 0,function(){var i,a,o,s,u,c,l,f,d,h=this;return(0,en.Jh)(this,function(p){return n?(i=r.variables,a=e.name.value,o=eX(e),s=a!==o,c=Promise.resolve(u=n[o]||n[a]),(!r.onlyRunForcedResolvers||this.shouldForceResolvers(e))&&(l=n.__typename||r.defaultOperationType,(f=this.resolvers&&this.resolvers[l])&&(d=f[s?a:o])&&(c=Promise.resolve(rX.withValue(this.cache,d,[n,eZ(e,i),r.context,{field:e,fragmentMap:r.fragmentMap},])))),[2,c.then(function(n){if(void 0===n&&(n=u),e.directives&&e.directives.forEach(function(e){"export"===e.name.value&&e.arguments&&e.arguments.forEach(function(e){"as"===e.name.value&&"StringValue"===e.value.kind&&(r.exportedVariables[e.value.value]=n)})}),!e.selectionSet||null==n)return n;var i,a,o=null!==(a=null===(i=e.directives)||void 0===i?void 0:i.some(function(e){return"client"===e.name.value}))&&void 0!==a&&a;return Array.isArray(n)?h.resolveSubSelectedArray(e,t||o,n,r):e.selectionSet?h.resolveSelectionSet(e.selectionSet,t||o,n,r):void 0})]):[2,null]})})},e.prototype.resolveSubSelectedArray=function(e,t,n,r){var i=this;return Promise.all(n.map(function(n){return null===n?null:Array.isArray(n)?i.resolveSubSelectedArray(e,t,n,r):e.selectionSet?i.resolveSelectionSet(e.selectionSet,t,n,r):void 0}))},e.prototype.collectSelectionsToResolve=function(e,t){var n=function(e){return!Array.isArray(e)},r=this.selectionsToResolveCache;function i(e){if(!r.has(e)){var a=new Set;r.set(e,a),tl(e,{Directive:function(e,t,r,i,o){"client"===e.name.value&&o.forEach(function(e){n(e)&&n9(e)&&a.add(e)})},FragmentSpread:function(e,r,o,s,u){var c=t[e.name.value];__DEV__?(0,Q.kG)(c,"No fragment named ".concat(e.name.value)):(0,Q.kG)(c,12);var l=i(c);l.size>0&&(u.forEach(function(e){n(e)&&n9(e)&&a.add(e)}),a.add(e),l.forEach(function(e){a.add(e)}))}})}return r.get(e)}return i(e)},e}(),r6=new(t_.mr?WeakMap:Map);function r5(e,t){var n=e[t];"function"==typeof n&&(e[t]=function(){return r6.set(e,(r6.get(e)+1)%1e15),n.apply(this,arguments)})}function r8(e){e.notifyTimeout&&(clearTimeout(e.notifyTimeout),e.notifyTimeout=void 0)}var r9=function(){function e(e,t){void 0===t&&(t=e.generateQueryId()),this.queryId=t,this.listeners=new Set,this.document=null,this.lastRequestId=1,this.subscriptions=new Set,this.stopped=!1,this.dirty=!1,this.observableQuery=null;var n=this.cache=e.cache;r6.has(n)||(r6.set(n,0),r5(n,"evict"),r5(n,"modify"),r5(n,"reset"))}return e.prototype.init=function(e){var t=e.networkStatus||nZ.I.loading;return this.variables&&this.networkStatus!==nZ.I.loading&&!(0,nm.D)(this.variables,e.variables)&&(t=nZ.I.setVariables),(0,nm.D)(e.variables,this.variables)||(this.lastDiff=void 0),Object.assign(this,{document:e.document,variables:e.variables,networkError:null,graphQLErrors:this.graphQLErrors||[],networkStatus:t}),e.observableQuery&&this.setObservableQuery(e.observableQuery),e.lastRequestId&&(this.lastRequestId=e.lastRequestId),this},e.prototype.reset=function(){r8(this),this.dirty=!1},e.prototype.getDiff=function(e){void 0===e&&(e=this.variables);var t=this.getDiffOptions(e);if(this.lastDiff&&(0,nm.D)(t,this.lastDiff.options))return this.lastDiff.diff;this.updateWatch(this.variables=e);var n=this.observableQuery;if(n&&"no-cache"===n.options.fetchPolicy)return{complete:!1};var r=this.cache.diff(t);return this.updateLastDiff(r,t),r},e.prototype.updateLastDiff=function(e,t){this.lastDiff=e?{diff:e,options:t||this.getDiffOptions()}:void 0},e.prototype.getDiffOptions=function(e){var t;return void 0===e&&(e=this.variables),{query:this.document,variables:e,returnPartialData:!0,optimistic:!0,canonizeResults:null===(t=this.observableQuery)||void 0===t?void 0:t.options.canonizeResults}},e.prototype.setDiff=function(e){var t=this,n=this.lastDiff&&this.lastDiff.diff;this.updateLastDiff(e),this.dirty||(0,nm.D)(n&&n.result,e&&e.result)||(this.dirty=!0,this.notifyTimeout||(this.notifyTimeout=setTimeout(function(){return t.notify()},0)))},e.prototype.setObservableQuery=function(e){var t=this;e!==this.observableQuery&&(this.oqListener&&this.listeners.delete(this.oqListener),this.observableQuery=e,e?(e.queryInfo=this,this.listeners.add(this.oqListener=function(){t.getDiff().fromOptimisticTransaction?e.observe():n4(e)})):delete this.oqListener)},e.prototype.notify=function(){var e=this;r8(this),this.shouldNotify()&&this.listeners.forEach(function(t){return t(e)}),this.dirty=!1},e.prototype.shouldNotify=function(){if(!this.dirty||!this.listeners.size)return!1;if((0,nZ.O)(this.networkStatus)&&this.observableQuery){var e=this.observableQuery.options.fetchPolicy;if("cache-only"!==e&&"cache-and-network"!==e)return!1}return!0},e.prototype.stop=function(){if(!this.stopped){this.stopped=!0,this.reset(),this.cancel(),this.cancel=e.prototype.cancel,this.subscriptions.forEach(function(e){return e.unsubscribe()});var t=this.observableQuery;t&&t.stopPolling()}},e.prototype.cancel=function(){},e.prototype.updateWatch=function(e){var t=this;void 0===e&&(e=this.variables);var n=this.observableQuery;if(!n||"no-cache"!==n.options.fetchPolicy){var r=(0,en.pi)((0,en.pi)({},this.getDiffOptions(e)),{watcher:this,callback:function(e){return t.setDiff(e)}});this.lastWatch&&(0,nm.D)(r,this.lastWatch)||(this.cancel(),this.cancel=this.cache.watch(this.lastWatch=r))}},e.prototype.resetLastWrite=function(){this.lastWrite=void 0},e.prototype.shouldWrite=function(e,t){var n=this.lastWrite;return!(n&&n.dmCount===r6.get(this.cache)&&(0,nm.D)(t,n.variables)&&(0,nm.D)(e.data,n.result.data))},e.prototype.markResult=function(e,t,n,r){var i=this,a=new tB,o=(0,tP.O)(e.errors)?e.errors.slice(0):[];if(this.reset(),"incremental"in e&&(0,tP.O)(e.incremental)){var s=tG(this.getDiff().result,e);e.data=s}else if("hasNext"in e&&e.hasNext){var u=this.getDiff();e.data=a.merge(u.result,e.data)}this.graphQLErrors=o,"no-cache"===n.fetchPolicy?this.updateLastDiff({result:e.data,complete:!0},this.getDiffOptions(n.variables)):0!==r&&(r7(e,n.errorPolicy)?this.cache.performTransaction(function(a){if(i.shouldWrite(e,n.variables))a.writeQuery({query:t,data:e.data,variables:n.variables,overwrite:1===r}),i.lastWrite={result:e,variables:n.variables,dmCount:r6.get(i.cache)};else if(i.lastDiff&&i.lastDiff.diff.complete){e.data=i.lastDiff.diff.result;return}var o=i.getDiffOptions(n.variables),s=a.diff(o);i.stopped||i.updateWatch(n.variables),i.updateLastDiff(s,o),s.complete&&(e.data=s.result)}):this.lastWrite=void 0)},e.prototype.markReady=function(){return this.networkError=null,this.networkStatus=nZ.I.ready},e.prototype.markError=function(e){return this.networkStatus=nZ.I.error,this.lastWrite=void 0,this.reset(),e.graphQLErrors&&(this.graphQLErrors=e.graphQLErrors),e.networkError&&(this.networkError=e.networkError),e},e}();function r7(e,t){void 0===t&&(t="none");var n="ignore"===t||"all"===t,r=!nO(e);return!r&&n&&e.data&&(r=!0),r}var ie=Object.prototype.hasOwnProperty,it=function(){function e(e){var t=e.cache,n=e.link,r=e.defaultOptions,i=e.queryDeduplication,a=void 0!==i&&i,o=e.onBroadcast,s=e.ssrMode,u=void 0!==s&&s,c=e.clientAwareness,l=void 0===c?{}:c,f=e.localState,d=e.assumeImmutableResults;this.clientAwareness={},this.queries=new Map,this.fetchCancelFns=new Map,this.transformCache=new(t_.mr?WeakMap:Map),this.queryIdCounter=1,this.requestIdCounter=1,this.mutationIdCounter=1,this.inFlightLinkObservables=new Map,this.cache=t,this.link=n,this.defaultOptions=r||Object.create(null),this.queryDeduplication=a,this.clientAwareness=l,this.localState=f||new r4({cache:t}),this.ssrMode=u,this.assumeImmutableResults=!!d,(this.onBroadcast=o)&&(this.mutationStore=Object.create(null))}return e.prototype.stop=function(){var e=this;this.queries.forEach(function(t,n){e.stopQueryNoBroadcast(n)}),this.cancelPendingFetches(__DEV__?new Q.ej("QueryManager stopped while query was in flight"):new Q.ej(14))},e.prototype.cancelPendingFetches=function(e){this.fetchCancelFns.forEach(function(t){return t(e)}),this.fetchCancelFns.clear()},e.prototype.mutate=function(e){var t,n,r=e.mutation,i=e.variables,a=e.optimisticResponse,o=e.updateQueries,s=e.refetchQueries,u=void 0===s?[]:s,c=e.awaitRefetchQueries,l=void 0!==c&&c,f=e.update,d=e.onQueryUpdated,h=e.fetchPolicy,p=void 0===h?(null===(t=this.defaultOptions.mutate)||void 0===t?void 0:t.fetchPolicy)||"network-only":h,b=e.errorPolicy,m=void 0===b?(null===(n=this.defaultOptions.mutate)||void 0===n?void 0:n.errorPolicy)||"none":b,g=e.keepRootFields,v=e.context;return(0,en.mG)(this,void 0,void 0,function(){var e,t,n,s,c,h;return(0,en.Jh)(this,function(b){switch(b.label){case 0:if(__DEV__?(0,Q.kG)(r,"mutation option is required. You must specify your GraphQL document in the mutation option."):(0,Q.kG)(r,15),__DEV__?(0,Q.kG)("network-only"===p||"no-cache"===p,"Mutations support only 'network-only' or 'no-cache' fetchPolicy strings. The default `network-only` behavior automatically writes mutation results to the cache. Passing `no-cache` skips the cache write."):(0,Q.kG)("network-only"===p||"no-cache"===p,16),e=this.generateMutationId(),n=(t=this.transform(r)).document,s=t.hasClientExports,r=this.cache.transformForLink(n),i=this.getVariables(r,i),!s)return[3,2];return[4,this.localState.addExportedVariables(r,i,v)];case 1:i=b.sent(),b.label=2;case 2:return c=this.mutationStore&&(this.mutationStore[e]={mutation:r,variables:i,loading:!0,error:null}),a&&this.markMutationOptimistic(a,{mutationId:e,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,updateQueries:o,update:f,keepRootFields:g}),this.broadcastQueries(),h=this,[2,new Promise(function(t,n){return nM(h.getObservableFromLink(r,(0,en.pi)((0,en.pi)({},v),{optimisticResponse:a}),i,!1),function(t){if(nO(t)&&"none"===m)throw new tN.cA({graphQLErrors:nA(t)});c&&(c.loading=!1,c.error=null);var n=(0,en.pi)({},t);return"function"==typeof u&&(u=u(n)),"ignore"===m&&nO(n)&&delete n.errors,h.markMutationResult({mutationId:e,result:n,document:r,variables:i,fetchPolicy:p,errorPolicy:m,context:v,update:f,updateQueries:o,awaitRefetchQueries:l,refetchQueries:u,removeOptimistic:a?e:void 0,onQueryUpdated:d,keepRootFields:g})}).subscribe({next:function(e){h.broadcastQueries(),"hasNext"in e&&!1!==e.hasNext||t(e)},error:function(t){c&&(c.loading=!1,c.error=t),a&&h.cache.removeOptimistic(e),h.broadcastQueries(),n(t instanceof tN.cA?t:new tN.cA({networkError:t}))}})})]}})})},e.prototype.markMutationResult=function(e,t){var n=this;void 0===t&&(t=this.cache);var r=e.result,i=[],a="no-cache"===e.fetchPolicy;if(!a&&r7(r,e.errorPolicy)){if(tU(r)||i.push({result:r.data,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}),tU(r)&&(0,tP.O)(r.incremental)){var o=t.diff({id:"ROOT_MUTATION",query:this.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0}),s=void 0;o.result&&(s=tG(o.result,r)),void 0!==s&&(r.data=s,i.push({result:s,dataId:"ROOT_MUTATION",query:e.document,variables:e.variables}))}var u=e.updateQueries;u&&this.queries.forEach(function(e,a){var o=e.observableQuery,s=o&&o.queryName;if(s&&ie.call(u,s)){var c,l=u[s],f=n.queries.get(a),d=f.document,h=f.variables,p=t.diff({query:d,variables:h,returnPartialData:!0,optimistic:!1}),b=p.result;if(p.complete&&b){var m=l(b,{mutationResult:r,queryName:d&&e3(d)||void 0,queryVariables:h});m&&i.push({result:m,dataId:"ROOT_QUERY",query:d,variables:h})}}})}if(i.length>0||e.refetchQueries||e.update||e.onQueryUpdated||e.removeOptimistic){var c=[];if(this.refetchQueries({updateCache:function(t){a||i.forEach(function(e){return t.write(e)});var o=e.update,s=!t$(r)||tU(r)&&!r.hasNext;if(o){if(!a){var u=t.diff({id:"ROOT_MUTATION",query:n.transform(e.document).asQuery,variables:e.variables,optimistic:!1,returnPartialData:!0});u.complete&&("incremental"in(r=(0,en.pi)((0,en.pi)({},r),{data:u.result}))&&delete r.incremental,"hasNext"in r&&delete r.hasNext)}s&&o(t,r,{context:e.context,variables:e.variables})}a||e.keepRootFields||!s||t.modify({id:"ROOT_MUTATION",fields:function(e,t){var n=t.fieldName,r=t.DELETE;return"__typename"===n?e:r}})},include:e.refetchQueries,optimistic:!1,removeOptimistic:e.removeOptimistic,onQueryUpdated:e.onQueryUpdated||null}).forEach(function(e){return c.push(e)}),e.awaitRefetchQueries||e.onQueryUpdated)return Promise.all(c).then(function(){return r})}return Promise.resolve(r)},e.prototype.markMutationOptimistic=function(e,t){var n=this,r="function"==typeof e?e(t.variables):e;return this.cache.recordOptimisticTransaction(function(e){try{n.markMutationResult((0,en.pi)((0,en.pi)({},t),{result:{data:r}}),e)}catch(i){__DEV__&&Q.kG.error(i)}},t.mutationId)},e.prototype.fetchQuery=function(e,t,n){return this.fetchQueryObservable(e,t,n).promise},e.prototype.getQueryStore=function(){var e=Object.create(null);return this.queries.forEach(function(t,n){e[n]={variables:t.variables,networkStatus:t.networkStatus,networkError:t.networkError,graphQLErrors:t.graphQLErrors}}),e},e.prototype.resetErrors=function(e){var t=this.queries.get(e);t&&(t.networkError=void 0,t.graphQLErrors=[])},e.prototype.transform=function(e){var t=this.transformCache;if(!t.has(e)){var n=this.cache.transformDocument(e),r=nY(n),i=this.localState.clientQuery(n),a=r&&this.localState.serverQuery(r),o={document:n,hasClientExports:tm(n),hasForcedResolvers:this.localState.shouldForceResolvers(n),clientQuery:i,serverQuery:a,defaultVars:e9(e2(n)),asQuery:(0,en.pi)((0,en.pi)({},n),{definitions:n.definitions.map(function(e){return"OperationDefinition"===e.kind&&"query"!==e.operation?(0,en.pi)((0,en.pi)({},e),{operation:"query"}):e})})},s=function(e){e&&!t.has(e)&&t.set(e,o)};s(e),s(n),s(i),s(a)}return t.get(e)},e.prototype.getVariables=function(e,t){return(0,en.pi)((0,en.pi)({},this.transform(e).defaultVars),t)},e.prototype.watchQuery=function(e){void 0===(e=(0,en.pi)((0,en.pi)({},e),{variables:this.getVariables(e.query,e.variables)})).notifyOnNetworkStatusChange&&(e.notifyOnNetworkStatusChange=!1);var t=new r9(this),n=new n3({queryManager:this,queryInfo:t,options:e});return this.queries.set(n.queryId,t),t.init({document:n.query,observableQuery:n,variables:n.variables}),n},e.prototype.query=function(e,t){var n=this;return void 0===t&&(t=this.generateQueryId()),__DEV__?(0,Q.kG)(e.query,"query option is required. You must specify your GraphQL document in the query option."):(0,Q.kG)(e.query,17),__DEV__?(0,Q.kG)("Document"===e.query.kind,'You must wrap the query string in a "gql" tag.'):(0,Q.kG)("Document"===e.query.kind,18),__DEV__?(0,Q.kG)(!e.returnPartialData,"returnPartialData option only supported on watchQuery."):(0,Q.kG)(!e.returnPartialData,19),__DEV__?(0,Q.kG)(!e.pollInterval,"pollInterval option only supported on watchQuery."):(0,Q.kG)(!e.pollInterval,20),this.fetchQuery(t,e).finally(function(){return n.stopQuery(t)})},e.prototype.generateQueryId=function(){return String(this.queryIdCounter++)},e.prototype.generateRequestId=function(){return this.requestIdCounter++},e.prototype.generateMutationId=function(){return String(this.mutationIdCounter++)},e.prototype.stopQueryInStore=function(e){this.stopQueryInStoreNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryInStoreNoBroadcast=function(e){var t=this.queries.get(e);t&&t.stop()},e.prototype.clearStore=function(e){return void 0===e&&(e={discardWatches:!0}),this.cancelPendingFetches(__DEV__?new Q.ej("Store reset while query was in flight (not completed in link chain)"):new Q.ej(21)),this.queries.forEach(function(e){e.observableQuery?e.networkStatus=nZ.I.loading:e.stop()}),this.mutationStore&&(this.mutationStore=Object.create(null)),this.cache.reset(e)},e.prototype.getObservableQueries=function(e){var t=this;void 0===e&&(e="active");var n=new Map,r=new Map,i=new Set;return Array.isArray(e)&&e.forEach(function(e){"string"==typeof e?r.set(e,!1):eN(e)?r.set(t.transform(e).document,!1):(0,eO.s)(e)&&e.query&&i.add(e)}),this.queries.forEach(function(t,i){var a=t.observableQuery,o=t.document;if(a){if("all"===e){n.set(i,a);return}var s=a.queryName;if("standby"===a.options.fetchPolicy||"active"===e&&!a.hasObservers())return;("active"===e||s&&r.has(s)||o&&r.has(o))&&(n.set(i,a),s&&r.set(s,!0),o&&r.set(o,!0))}}),i.size&&i.forEach(function(e){var r=nG("legacyOneTimeQuery"),i=t.getQuery(r).init({document:e.query,variables:e.variables}),a=new n3({queryManager:t,queryInfo:i,options:(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"network-only"})});(0,Q.kG)(a.queryId===r),i.setObservableQuery(a),n.set(r,a)}),__DEV__&&r.size&&r.forEach(function(e,t){!e&&__DEV__&&Q.kG.warn("Unknown query ".concat("string"==typeof t?"named ":"").concat(JSON.stringify(t,null,2)," requested in refetchQueries options.include array"))}),n},e.prototype.reFetchObservableQueries=function(e){var t=this;void 0===e&&(e=!1);var n=[];return this.getObservableQueries(e?"all":"active").forEach(function(r,i){var a=r.options.fetchPolicy;r.resetLastResults(),(e||"standby"!==a&&"cache-only"!==a)&&n.push(r.refetch()),t.getQuery(i).setDiff(null)}),this.broadcastQueries(),Promise.all(n)},e.prototype.setObservableQuery=function(e){this.getQuery(e.queryId).setObservableQuery(e)},e.prototype.startGraphQLSubscription=function(e){var t=this,n=e.query,r=e.fetchPolicy,i=e.errorPolicy,a=e.variables,o=e.context,s=void 0===o?{}:o;n=this.transform(n).document,a=this.getVariables(n,a);var u=function(e){return t.getObservableFromLink(n,s,e).map(function(a){"no-cache"!==r&&(r7(a,i)&&t.cache.write({query:n,result:a.data,dataId:"ROOT_SUBSCRIPTION",variables:e}),t.broadcastQueries());var o=nO(a),s=(0,tN.ls)(a);if(o||s){var u={};throw o&&(u.graphQLErrors=a.errors),s&&(u.protocolErrors=a.extensions[tN.YG]),new tN.cA(u)}return a})};if(this.transform(n).hasClientExports){var c=this.localState.addExportedVariables(n,a,s).then(u);return new eT(function(e){var t=null;return c.then(function(n){return t=n.subscribe(e)},e.error),function(){return t&&t.unsubscribe()}})}return u(a)},e.prototype.stopQuery=function(e){this.stopQueryNoBroadcast(e),this.broadcastQueries()},e.prototype.stopQueryNoBroadcast=function(e){this.stopQueryInStoreNoBroadcast(e),this.removeQuery(e)},e.prototype.removeQuery=function(e){this.fetchCancelFns.delete(e),this.queries.has(e)&&(this.getQuery(e).stop(),this.queries.delete(e))},e.prototype.broadcastQueries=function(){this.onBroadcast&&this.onBroadcast(),this.queries.forEach(function(e){return e.notify()})},e.prototype.getLocalState=function(){return this.localState},e.prototype.getObservableFromLink=function(e,t,n,r){var i,a,o=this;void 0===r&&(r=null!==(i=null==t?void 0:t.queryDeduplication)&&void 0!==i?i:this.queryDeduplication);var s=this.transform(e).serverQuery;if(s){var u=this,c=u.inFlightLinkObservables,l=u.link,f={query:s,variables:n,operationName:e3(s)||void 0,context:this.prepareContext((0,en.pi)((0,en.pi)({},t),{forceFetch:!r}))};if(t=f.context,r){var d=c.get(s)||new Map;c.set(s,d);var h=nx(n);if(!(a=d.get(h))){var p=new nq([np(l,f)]);d.set(h,a=p),p.beforeNext(function(){d.delete(h)&&d.size<1&&c.delete(s)})}}else a=new nq([np(l,f)])}else a=new nq([eT.of({data:{}})]),t=this.prepareContext(t);var b=this.transform(e).clientQuery;return b&&(a=nM(a,function(e){return o.localState.runResolvers({document:b,remoteResult:e,context:t,variables:n})})),a},e.prototype.getResultsFromLink=function(e,t,n){var r=e.lastRequestId=this.generateRequestId(),i=this.cache.transformForLink(this.transform(e.document).document);return nM(this.getObservableFromLink(i,n.context,n.variables),function(a){var o=nA(a),s=o.length>0;if(r>=e.lastRequestId){if(s&&"none"===n.errorPolicy)throw e.markError(new tN.cA({graphQLErrors:o}));e.markResult(a,i,n,t),e.markReady()}var u={data:a.data,loading:!1,networkStatus:nZ.I.ready};return s&&"ignore"!==n.errorPolicy&&(u.errors=o,u.networkStatus=nZ.I.error),u},function(t){var n=(0,tN.MS)(t)?t:new tN.cA({networkError:t});throw r>=e.lastRequestId&&e.markError(n),n})},e.prototype.fetchQueryObservable=function(e,t,n){return this.fetchConcastWithInfo(e,t,n).concast},e.prototype.fetchConcastWithInfo=function(e,t,n){var r,i,a=this;void 0===n&&(n=nZ.I.loading);var o=this.transform(t.query).document,s=this.getVariables(o,t.variables),u=this.getQuery(e),c=this.defaultOptions.watchQuery,l=t.fetchPolicy,f=void 0===l?c&&c.fetchPolicy||"cache-first":l,d=t.errorPolicy,h=void 0===d?c&&c.errorPolicy||"none":d,p=t.returnPartialData,b=void 0!==p&&p,m=t.notifyOnNetworkStatusChange,g=void 0!==m&&m,v=t.context,y=void 0===v?{}:v,w=Object.assign({},t,{query:o,variables:s,fetchPolicy:f,errorPolicy:h,returnPartialData:b,notifyOnNetworkStatusChange:g,context:y}),_=function(e){w.variables=e;var r=a.fetchQueryByPolicy(u,w,n);return"standby"!==w.fetchPolicy&&r.sources.length>0&&u.observableQuery&&u.observableQuery.applyNextFetchPolicy("after-fetch",t),r},E=function(){return a.fetchCancelFns.delete(e)};if(this.fetchCancelFns.set(e,function(e){E(),setTimeout(function(){return r.cancel(e)})}),this.transform(w.query).hasClientExports)r=new nq(this.localState.addExportedVariables(w.query,w.variables,w.context).then(_).then(function(e){return e.sources})),i=!0;else{var S=_(w.variables);i=S.fromLink,r=new nq(S.sources)}return r.promise.then(E,E),{concast:r,fromLink:i}},e.prototype.refetchQueries=function(e){var t=this,n=e.updateCache,r=e.include,i=e.optimistic,a=void 0!==i&&i,o=e.removeOptimistic,s=void 0===o?a?nG("refetchQueries"):void 0:o,u=e.onQueryUpdated,c=new Map;r&&this.getObservableQueries(r).forEach(function(e,n){c.set(n,{oq:e,lastDiff:t.getQuery(n).getDiff()})});var l=new Map;return n&&this.cache.batch({update:n,optimistic:a&&s||!1,removeOptimistic:s,onWatchUpdated:function(e,t,n){var r=e.watcher instanceof r9&&e.watcher.observableQuery;if(r){if(u){c.delete(r.queryId);var i=u(r,t,n);return!0===i&&(i=r.refetch()),!1!==i&&l.set(r,i),i}null!==u&&c.set(r.queryId,{oq:r,lastDiff:n,diff:t})}}}),c.size&&c.forEach(function(e,n){var r,i=e.oq,a=e.lastDiff,o=e.diff;if(u){if(!o){var s=i.queryInfo;s.reset(),o=s.getDiff()}r=u(i,o,a)}u&&!0!==r||(r=i.refetch()),!1!==r&&l.set(i,r),n.indexOf("legacyOneTimeQuery")>=0&&t.stopQueryNoBroadcast(n)}),s&&this.cache.removeOptimistic(s),l},e.prototype.fetchQueryByPolicy=function(e,t,n){var r=this,i=t.query,a=t.variables,o=t.fetchPolicy,s=t.refetchWritePolicy,u=t.errorPolicy,c=t.returnPartialData,l=t.context,f=t.notifyOnNetworkStatusChange,d=e.networkStatus;e.init({document:this.transform(i).document,variables:a,networkStatus:n});var h=function(){return e.getDiff(a)},p=function(t,n){void 0===n&&(n=e.networkStatus||nZ.I.loading);var o=t.result;!__DEV__||c||(0,nm.D)(o,{})||n5(t.missing);var s=function(e){return eT.of((0,en.pi)({data:e,loading:(0,nZ.O)(n),networkStatus:n},t.complete?null:{partial:!0}))};return o&&r.transform(i).hasForcedResolvers?r.localState.runResolvers({document:i,remoteResult:{data:o},context:l,variables:a,onlyRunForcedResolvers:!0}).then(function(e){return s(e.data||void 0)}):"none"===u&&n===nZ.I.refetch&&Array.isArray(t.missing)?s(void 0):s(o)},b="no-cache"===o?0:n===nZ.I.refetch&&"merge"!==s?1:2,m=function(){return r.getResultsFromLink(e,b,{variables:a,context:l,fetchPolicy:o,errorPolicy:u})},g=f&&"number"==typeof d&&d!==n&&(0,nZ.O)(n);switch(o){default:case"cache-first":var v=h();if(v.complete)return{fromLink:!1,sources:[p(v,e.markReady())]};if(c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-and-network":var v=h();if(v.complete||c||g)return{fromLink:!0,sources:[p(v),m()]};return{fromLink:!0,sources:[m()]};case"cache-only":return{fromLink:!1,sources:[p(h(),e.markReady())]};case"network-only":if(g)return{fromLink:!0,sources:[p(h()),m()]};return{fromLink:!0,sources:[m()]};case"no-cache":if(g)return{fromLink:!0,sources:[p(e.getDiff()),m(),]};return{fromLink:!0,sources:[m()]};case"standby":return{fromLink:!1,sources:[]}}},e.prototype.getQuery=function(e){return e&&!this.queries.has(e)&&this.queries.set(e,new r9(this,e)),this.queries.get(e)},e.prototype.prepareContext=function(e){void 0===e&&(e={});var t=this.localState.prepareContext(e);return(0,en.pi)((0,en.pi)({},t),{clientAwareness:this.clientAwareness})},e}(),ir=__webpack_require__(14012),ii=!1,ia=function(){function e(e){var t=this;this.resetStoreCallbacks=[],this.clearStoreCallbacks=[];var n=e.uri,r=e.credentials,i=e.headers,a=e.cache,o=e.ssrMode,s=void 0!==o&&o,u=e.ssrForceFetchDelay,c=void 0===u?0:u,l=e.connectToDevTools,f=void 0===l?"object"==typeof window&&!window.__APOLLO_CLIENT__&&__DEV__:l,d=e.queryDeduplication,h=void 0===d||d,p=e.defaultOptions,b=e.assumeImmutableResults,m=void 0!==b&&b,g=e.resolvers,v=e.typeDefs,y=e.fragmentMatcher,w=e.name,_=e.version,E=e.link;if(E||(E=n?new nh({uri:n,credentials:r,headers:i}):ta.empty()),!a)throw __DEV__?new Q.ej("To initialize Apollo Client, you must specify a 'cache' property in the options object. \nFor more information, please visit: https://go.apollo.dev/c/docs"):new Q.ej(9);if(this.link=E,this.cache=a,this.disableNetworkFetches=s||c>0,this.queryDeduplication=h,this.defaultOptions=p||Object.create(null),this.typeDefs=v,c&&setTimeout(function(){return t.disableNetworkFetches=!1},c),this.watchQuery=this.watchQuery.bind(this),this.query=this.query.bind(this),this.mutate=this.mutate.bind(this),this.resetStore=this.resetStore.bind(this),this.reFetchObservableQueries=this.reFetchObservableQueries.bind(this),f&&"object"==typeof window&&(window.__APOLLO_CLIENT__=this),!ii&&f&&__DEV__&&(ii=!0,"undefined"!=typeof window&&window.document&&window.top===window.self&&!window.__APOLLO_DEVTOOLS_GLOBAL_HOOK__)){var S=window.navigator,k=S&&S.userAgent,x=void 0;"string"==typeof k&&(k.indexOf("Chrome/")>-1?x="https://chrome.google.com/webstore/detail/apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm":k.indexOf("Firefox/")>-1&&(x="https://addons.mozilla.org/en-US/firefox/addon/apollo-developer-tools/")),x&&__DEV__&&Q.kG.log("Download the Apollo DevTools for a better development experience: "+x)}this.version=nb,this.localState=new r4({cache:a,client:this,resolvers:g,fragmentMatcher:y}),this.queryManager=new it({cache:this.cache,link:this.link,defaultOptions:this.defaultOptions,queryDeduplication:h,ssrMode:s,clientAwareness:{name:w,version:_},localState:this.localState,assumeImmutableResults:m,onBroadcast:f?function(){t.devToolsHookCb&&t.devToolsHookCb({action:{},state:{queries:t.queryManager.getQueryStore(),mutations:t.queryManager.mutationStore||{}},dataWithOptimisticResults:t.cache.extract(!0)})}:void 0})}return e.prototype.stop=function(){this.queryManager.stop()},e.prototype.watchQuery=function(e){return this.defaultOptions.watchQuery&&(e=(0,ir.J)(this.defaultOptions.watchQuery,e)),this.disableNetworkFetches&&("network-only"===e.fetchPolicy||"cache-and-network"===e.fetchPolicy)&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.watchQuery(e)},e.prototype.query=function(e){return this.defaultOptions.query&&(e=(0,ir.J)(this.defaultOptions.query,e)),__DEV__?(0,Q.kG)("cache-and-network"!==e.fetchPolicy,"The cache-and-network fetchPolicy does not work with client.query, because client.query can only return a single result. Please use client.watchQuery to receive multiple results from the cache and the network, or consider using a different fetchPolicy, such as cache-first or network-only."):(0,Q.kG)("cache-and-network"!==e.fetchPolicy,10),this.disableNetworkFetches&&"network-only"===e.fetchPolicy&&(e=(0,en.pi)((0,en.pi)({},e),{fetchPolicy:"cache-first"})),this.queryManager.query(e)},e.prototype.mutate=function(e){return this.defaultOptions.mutate&&(e=(0,ir.J)(this.defaultOptions.mutate,e)),this.queryManager.mutate(e)},e.prototype.subscribe=function(e){return this.queryManager.startGraphQLSubscription(e)},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!1),this.cache.readQuery(e,t)},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!1),this.cache.readFragment(e,t)},e.prototype.writeQuery=function(e){var t=this.cache.writeQuery(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.writeFragment=function(e){var t=this.cache.writeFragment(e);return!1!==e.broadcast&&this.queryManager.broadcastQueries(),t},e.prototype.__actionHookForDevTools=function(e){this.devToolsHookCb=e},e.prototype.__requestRaw=function(e){return np(this.link,e)},e.prototype.resetStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!1})}).then(function(){return Promise.all(e.resetStoreCallbacks.map(function(e){return e()}))}).then(function(){return e.reFetchObservableQueries()})},e.prototype.clearStore=function(){var e=this;return Promise.resolve().then(function(){return e.queryManager.clearStore({discardWatches:!0})}).then(function(){return Promise.all(e.clearStoreCallbacks.map(function(e){return e()}))})},e.prototype.onResetStore=function(e){var t=this;return this.resetStoreCallbacks.push(e),function(){t.resetStoreCallbacks=t.resetStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.onClearStore=function(e){var t=this;return this.clearStoreCallbacks.push(e),function(){t.clearStoreCallbacks=t.clearStoreCallbacks.filter(function(t){return t!==e})}},e.prototype.reFetchObservableQueries=function(e){return this.queryManager.reFetchObservableQueries(e)},e.prototype.refetchQueries=function(e){var t=this.queryManager.refetchQueries(e),n=[],r=[];t.forEach(function(e,t){n.push(t),r.push(e)});var i=Promise.all(r);return i.queries=n,i.results=r,i.catch(function(e){__DEV__&&Q.kG.debug("In client.refetchQueries, Promise.all promise rejected with error ".concat(e))}),i},e.prototype.getObservableQueries=function(e){return void 0===e&&(e="active"),this.queryManager.getObservableQueries(e)},e.prototype.extract=function(e){return this.cache.extract(e)},e.prototype.restore=function(e){return this.cache.restore(e)},e.prototype.addResolvers=function(e){this.localState.addResolvers(e)},e.prototype.setResolvers=function(e){this.localState.setResolvers(e)},e.prototype.getResolvers=function(){return this.localState.getResolvers()},e.prototype.setLocalStateFragmentMatcher=function(e){this.localState.setFragmentMatcher(e)},e.prototype.setLink=function(e){this.link=this.queryManager.link=e},e}(),io=function(){function e(){this.getFragmentDoc=rZ(eA)}return e.prototype.batch=function(e){var t,n=this,r="string"==typeof e.optimistic?e.optimistic:!1===e.optimistic?null:void 0;return this.performTransaction(function(){return t=e.update(n)},r),t},e.prototype.recordOptimisticTransaction=function(e,t){this.performTransaction(e,t)},e.prototype.transformDocument=function(e){return e},e.prototype.transformForLink=function(e){return e},e.prototype.identify=function(e){},e.prototype.gc=function(){return[]},e.prototype.modify=function(e){return!1},e.prototype.readQuery=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{rootId:e.id||"ROOT_QUERY",optimistic:t}))},e.prototype.readFragment=function(e,t){return void 0===t&&(t=!!e.optimistic),this.read((0,en.pi)((0,en.pi)({},e),{query:this.getFragmentDoc(e.fragment,e.fragmentName),rootId:e.id,optimistic:t}))},e.prototype.writeQuery=function(e){var t=e.id,n=e.data,r=(0,en._T)(e,["id","data"]);return this.write(Object.assign(r,{dataId:t||"ROOT_QUERY",result:n}))},e.prototype.writeFragment=function(e){var t=e.id,n=e.data,r=e.fragment,i=e.fragmentName,a=(0,en._T)(e,["id","data","fragment","fragmentName"]);return this.write(Object.assign(a,{query:this.getFragmentDoc(r,i),dataId:t,result:n}))},e.prototype.updateQuery=function(e,t){return this.batch({update:function(n){var r=n.readQuery(e),i=t(r);return null==i?r:(n.writeQuery((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e.prototype.updateFragment=function(e,t){return this.batch({update:function(n){var r=n.readFragment(e),i=t(r);return null==i?r:(n.writeFragment((0,en.pi)((0,en.pi)({},e),{data:i})),i)}})},e}(),is=function(e){function t(n,r,i,a){var o,s=e.call(this,n)||this;if(s.message=n,s.path=r,s.query=i,s.variables=a,Array.isArray(s.path)){s.missing=s.message;for(var u=s.path.length-1;u>=0;--u)s.missing=((o={})[s.path[u]]=s.missing,o)}else s.missing=s.path;return s.__proto__=t.prototype,s}return(0,en.ZT)(t,e),t}(Error),iu=__webpack_require__(10542),ic=Object.prototype.hasOwnProperty;function il(e){return null==e}function id(e,t){var n=e.__typename,r=e.id,i=e._id;if("string"==typeof n&&(t&&(t.keyObject=il(r)?il(i)?void 0:{_id:i}:{id:r}),il(r)&&!il(i)&&(r=i),!il(r)))return"".concat(n,":").concat("number"==typeof r||"string"==typeof r?r:JSON.stringify(r))}var ih={dataIdFromObject:id,addTypename:!0,resultCaching:!0,canonizeResults:!1};function ip(e){return(0,n1.o)(ih,e)}function ib(e){var t=e.canonizeResults;return void 0===t?ih.canonizeResults:t}function im(e,t){return eD(t)?e.get(t.__ref,"__typename"):t&&t.__typename}var ig=/^[_a-z][_0-9a-z]*/i;function iv(e){var t=e.match(ig);return t?t[0]:e}function iy(e,t,n){return!!(0,eO.s)(t)&&((0,tP.k)(t)?t.every(function(t){return iy(e,t,n)}):e.selections.every(function(e){if(eQ(e)&&td(e,n)){var r=eX(e);return ic.call(t,r)&&(!e.selectionSet||iy(e.selectionSet,t[r],n))}return!0}))}function iw(e){return(0,eO.s)(e)&&!eD(e)&&!(0,tP.k)(e)}function i_(){return new tB}function iE(e,t){var n=eL(e4(e));return{fragmentMap:n,lookupFragment:function(e){var r=n[e];return!r&&t&&(r=t.lookup(e)),r||null}}}var iS=Object.create(null),ik=function(){return iS},ix=Object.create(null),iT=function(){function e(e,t){var n=this;this.policies=e,this.group=t,this.data=Object.create(null),this.rootIds=Object.create(null),this.refs=Object.create(null),this.getFieldValue=function(e,t){return(0,iu.J)(eD(e)?n.get(e.__ref,t):e&&e[t])},this.canRead=function(e){return eD(e)?n.has(e.__ref):"object"==typeof e},this.toReference=function(e,t){if("string"==typeof e)return eI(e);if(eD(e))return e;var r=n.policies.identify(e)[0];if(r){var i=eI(r);return t&&n.merge(r,e),i}}}return e.prototype.toObject=function(){return(0,en.pi)({},this.data)},e.prototype.has=function(e){return void 0!==this.lookup(e,!0)},e.prototype.get=function(e,t){if(this.group.depend(e,t),ic.call(this.data,e)){var n=this.data[e];if(n&&ic.call(n,t))return n[t]}return"__typename"===t&&ic.call(this.policies.rootTypenamesById,e)?this.policies.rootTypenamesById[e]:this instanceof iL?this.parent.get(e,t):void 0},e.prototype.lookup=function(e,t){return(t&&this.group.depend(e,"__exists"),ic.call(this.data,e))?this.data[e]:this instanceof iL?this.parent.lookup(e,t):this.policies.rootTypenamesById[e]?Object.create(null):void 0},e.prototype.merge=function(e,t){var n,r=this;eD(e)&&(e=e.__ref),eD(t)&&(t=t.__ref);var i="string"==typeof e?this.lookup(n=e):e,a="string"==typeof t?this.lookup(n=t):t;if(a){__DEV__?(0,Q.kG)("string"==typeof n,"store.merge expects a string ID"):(0,Q.kG)("string"==typeof n,1);var o=new tB(iI).merge(i,a);if(this.data[n]=o,o!==i&&(delete this.refs[n],this.group.caching)){var s=Object.create(null);i||(s.__exists=1),Object.keys(a).forEach(function(e){if(!i||i[e]!==o[e]){s[e]=1;var t=iv(e);t===e||r.policies.hasKeyArgs(o.__typename,t)||(s[t]=1),void 0!==o[e]||r instanceof iL||delete o[e]}}),s.__typename&&!(i&&i.__typename)&&this.policies.rootTypenamesById[n]===o.__typename&&delete s.__typename,Object.keys(s).forEach(function(e){return r.group.dirty(n,e)})}}},e.prototype.modify=function(e,t){var n=this,r=this.lookup(e);if(r){var i=Object.create(null),a=!1,o=!0,s={DELETE:iS,INVALIDATE:ix,isReference:eD,toReference:this.toReference,canRead:this.canRead,readField:function(t,r){return n.policies.readField("string"==typeof t?{fieldName:t,from:r||eI(e)}:t,{store:n})}};if(Object.keys(r).forEach(function(u){var c=iv(u),l=r[u];if(void 0!==l){var f="function"==typeof t?t:t[u]||t[c];if(f){var d=f===ik?iS:f((0,iu.J)(l),(0,en.pi)((0,en.pi)({},s),{fieldName:c,storeFieldName:u,storage:n.getStorage(e,u)}));d===ix?n.group.dirty(e,u):(d===iS&&(d=void 0),d!==l&&(i[u]=d,a=!0,l=d))}void 0!==l&&(o=!1)}}),a)return this.merge(e,i),o&&(this instanceof iL?this.data[e]=void 0:delete this.data[e],this.group.dirty(e,"__exists")),!0}return!1},e.prototype.delete=function(e,t,n){var r,i=this.lookup(e);if(i){var a=this.getFieldValue(i,"__typename"),o=t&&n?this.policies.getStoreFieldName({typename:a,fieldName:t,args:n}):t;return this.modify(e,o?((r={})[o]=ik,r):ik)}return!1},e.prototype.evict=function(e,t){var n=!1;return e.id&&(ic.call(this.data,e.id)&&(n=this.delete(e.id,e.fieldName,e.args)),this instanceof iL&&this!==t&&(n=this.parent.evict(e,t)||n),(e.fieldName||n)&&this.group.dirty(e.id,e.fieldName||"__exists")),n},e.prototype.clear=function(){this.replace(null)},e.prototype.extract=function(){var e=this,t=this.toObject(),n=[];return this.getRootIdSet().forEach(function(t){ic.call(e.policies.rootTypenamesById,t)||n.push(t)}),n.length&&(t.__META={extraRootIds:n.sort()}),t},e.prototype.replace=function(e){var t=this;if(Object.keys(this.data).forEach(function(n){e&&ic.call(e,n)||t.delete(n)}),e){var n=e.__META,r=(0,en._T)(e,["__META"]);Object.keys(r).forEach(function(e){t.merge(e,r[e])}),n&&n.extraRootIds.forEach(this.retain,this)}},e.prototype.retain=function(e){return this.rootIds[e]=(this.rootIds[e]||0)+1},e.prototype.release=function(e){if(this.rootIds[e]>0){var t=--this.rootIds[e];return t||delete this.rootIds[e],t}return 0},e.prototype.getRootIdSet=function(e){return void 0===e&&(e=new Set),Object.keys(this.rootIds).forEach(e.add,e),this instanceof iL?this.parent.getRootIdSet(e):Object.keys(this.policies.rootTypenamesById).forEach(e.add,e),e},e.prototype.gc=function(){var e=this,t=this.getRootIdSet(),n=this.toObject();t.forEach(function(r){ic.call(n,r)&&(Object.keys(e.findChildRefIds(r)).forEach(t.add,t),delete n[r])});var r=Object.keys(n);if(r.length){for(var i=this;i instanceof iL;)i=i.parent;r.forEach(function(e){return i.delete(e)})}return r},e.prototype.findChildRefIds=function(e){if(!ic.call(this.refs,e)){var t=this.refs[e]=Object.create(null),n=this.data[e];if(!n)return t;var r=new Set([n]);r.forEach(function(e){eD(e)&&(t[e.__ref]=!0),(0,eO.s)(e)&&Object.keys(e).forEach(function(t){var n=e[t];(0,eO.s)(n)&&r.add(n)})})}return this.refs[e]},e.prototype.makeCacheKey=function(){return this.group.keyMaker.lookupArray(arguments)},e}(),iM=function(){function e(e,t){void 0===t&&(t=null),this.caching=e,this.parent=t,this.d=null,this.resetCaching()}return e.prototype.resetCaching=function(){this.d=this.caching?rW():null,this.keyMaker=new n_(t_.mr)},e.prototype.depend=function(e,t){if(this.d){this.d(iO(e,t));var n=iv(t);n!==t&&this.d(iO(e,n)),this.parent&&this.parent.depend(e,t)}},e.prototype.dirty=function(e,t){this.d&&this.d.dirty(iO(e,t),"__exists"===t?"forget":"setDirty")},e}();function iO(e,t){return t+"#"+e}function iA(e,t){iD(e)&&e.group.depend(t,"__exists")}!function(e){var t=function(e){function t(t){var n=t.policies,r=t.resultCaching,i=void 0===r||r,a=t.seed,o=e.call(this,n,new iM(i))||this;return o.stump=new iC(o),o.storageTrie=new n_(t_.mr),a&&o.replace(a),o}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,t){return this.stump.addLayer(e,t)},t.prototype.removeLayer=function(){return this},t.prototype.getStorage=function(){return this.storageTrie.lookupArray(arguments)},t}(e);e.Root=t}(iT||(iT={}));var iL=function(e){function t(t,n,r,i){var a=e.call(this,n.policies,i)||this;return a.id=t,a.parent=n,a.replay=r,a.group=i,r(a),a}return(0,en.ZT)(t,e),t.prototype.addLayer=function(e,n){return new t(e,this,n,this.group)},t.prototype.removeLayer=function(e){var t=this,n=this.parent.removeLayer(e);return e===this.id?(this.group.caching&&Object.keys(this.data).forEach(function(e){var r=t.data[e],i=n.lookup(e);i?r?r!==i&&Object.keys(r).forEach(function(n){(0,nm.D)(r[n],i[n])||t.group.dirty(e,n)}):(t.group.dirty(e,"__exists"),Object.keys(i).forEach(function(n){t.group.dirty(e,n)})):t.delete(e)}),n):n===this.parent?this:n.addLayer(this.id,this.replay)},t.prototype.toObject=function(){return(0,en.pi)((0,en.pi)({},this.parent.toObject()),this.data)},t.prototype.findChildRefIds=function(t){var n=this.parent.findChildRefIds(t);return ic.call(this.data,t)?(0,en.pi)((0,en.pi)({},n),e.prototype.findChildRefIds.call(this,t)):n},t.prototype.getStorage=function(){for(var e=this.parent;e.parent;)e=e.parent;return e.getStorage.apply(e,arguments)},t}(iT),iC=function(e){function t(t){return e.call(this,"EntityStore.Stump",t,function(){},new iM(t.group.caching,t.group))||this}return(0,en.ZT)(t,e),t.prototype.removeLayer=function(){return this},t.prototype.merge=function(){return this.parent.merge.apply(this.parent,arguments)},t}(iL);function iI(e,t,n){var r=e[n],i=t[n];return(0,nm.D)(r,i)?r:i}function iD(e){return!!(e instanceof iT&&e.group.caching)}function iN(e){return[e.selectionSet,e.objectOrReference,e.context,e.context.canonizeResults,]}var iP=function(){function e(e){var t=this;this.knownResults=new(t_.mr?WeakMap:Map),this.config=(0,n1.o)(e,{addTypename:!1!==e.addTypename,canonizeResults:ib(e)}),this.canon=e.canon||new nk,this.executeSelectionSet=rZ(function(e){var n,r=e.context.canonizeResults,i=iN(e);i[3]=!r;var a=(n=t.executeSelectionSet).peek.apply(n,i);return a?r?(0,en.pi)((0,en.pi)({},a),{result:t.canon.admit(a.result)}):a:(iA(e.context.store,e.enclosingRef.__ref),t.execSelectionSetImpl(e))},{max:this.config.resultCacheMaxSize,keyArgs:iN,makeCacheKey:function(e,t,n,r){if(iD(n.store))return n.store.makeCacheKey(e,eD(t)?t.__ref:t,n.varString,r)}}),this.executeSubSelectedArray=rZ(function(e){return iA(e.context.store,e.enclosingRef.__ref),t.execSubSelectedArrayImpl(e)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var t=e.field,n=e.array,r=e.context;if(iD(r.store))return r.store.makeCacheKey(t,n,r.varString)}})}return e.prototype.resetCanon=function(){this.canon=new nk},e.prototype.diffQueryAgainstStore=function(e){var t,n=e.store,r=e.query,i=e.rootId,a=void 0===i?"ROOT_QUERY":i,o=e.variables,s=e.returnPartialData,u=void 0===s||s,c=e.canonizeResults,l=void 0===c?this.config.canonizeResults:c,f=this.config.cache.policies;o=(0,en.pi)((0,en.pi)({},e9(e6(r))),o);var d=eI(a),h=this.executeSelectionSet({selectionSet:e8(r).selectionSet,objectOrReference:d,enclosingRef:d,context:(0,en.pi)({store:n,query:r,policies:f,variables:o,varString:nx(o),canonizeResults:l},iE(r,this.config.fragments))});if(h.missing&&(t=[new is(iR(h.missing),h.missing,r,o)],!u))throw t[0];return{result:h.result,complete:!t,missing:t}},e.prototype.isFresh=function(e,t,n,r){if(iD(r.store)&&this.knownResults.get(e)===n){var i=this.executeSelectionSet.peek(n,t,r,this.canon.isKnown(e));if(i&&e===i.result)return!0}return!1},e.prototype.execSelectionSetImpl=function(e){var t,n=this,r=e.selectionSet,i=e.objectOrReference,a=e.enclosingRef,o=e.context;if(eD(i)&&!o.policies.rootTypenamesById[i.__ref]&&!o.store.has(i.__ref))return{result:this.canon.empty,missing:"Dangling reference to missing ".concat(i.__ref," object")};var s=o.variables,u=o.policies,c=o.store.getFieldValue(i,"__typename"),l=[],f=new tB;function d(e,n){var r;return e.missing&&(t=f.merge(t,((r={})[n]=e.missing,r))),e.result}this.config.addTypename&&"string"==typeof c&&!u.rootIdsByTypename[c]&&l.push({__typename:c});var h=new Set(r.selections);h.forEach(function(e){var r,p;if(td(e,s)){if(eQ(e)){var b=u.readField({fieldName:e.name.value,field:e,variables:o.variables,from:i},o),m=eX(e);void 0===b?nj.added(e)||(t=f.merge(t,((r={})[m]="Can't find field '".concat(e.name.value,"' on ").concat(eD(i)?i.__ref+" object":"object "+JSON.stringify(i,null,2)),r))):(0,tP.k)(b)?b=d(n.executeSubSelectedArray({field:e,array:b,enclosingRef:a,context:o}),m):e.selectionSet?null!=b&&(b=d(n.executeSelectionSet({selectionSet:e.selectionSet,objectOrReference:b,enclosingRef:eD(b)?b:a,context:o}),m)):o.canonizeResults&&(b=n.canon.pass(b)),void 0!==b&&l.push(((p={})[m]=b,p))}else{var g=eC(e,o.lookupFragment);if(!g&&e.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(e.name.value)):new Q.ej(5);g&&u.fragmentMatches(g,c)&&g.selectionSet.selections.forEach(h.add,h)}}});var p={result:tF(l),missing:t},b=o.canonizeResults?this.canon.admit(p):(0,iu.J)(p);return b.result&&this.knownResults.set(b.result,r),b},e.prototype.execSubSelectedArrayImpl=function(e){var t,n=this,r=e.field,i=e.array,a=e.enclosingRef,o=e.context,s=new tB;function u(e,n){var r;return e.missing&&(t=s.merge(t,((r={})[n]=e.missing,r))),e.result}return r.selectionSet&&(i=i.filter(o.store.canRead)),i=i.map(function(e,t){return null===e?null:(0,tP.k)(e)?u(n.executeSubSelectedArray({field:r,array:e,enclosingRef:a,context:o}),t):r.selectionSet?u(n.executeSelectionSet({selectionSet:r.selectionSet,objectOrReference:e,enclosingRef:eD(e)?e:a,context:o}),t):(__DEV__&&ij(o.store,r,e),e)}),{result:o.canonizeResults?this.canon.admit(i):i,missing:t}},e}();function iR(e){try{JSON.stringify(e,function(e,t){if("string"==typeof t)throw t;return t})}catch(t){return t}}function ij(e,t,n){if(!t.selectionSet){var r=new Set([n]);r.forEach(function(n){(0,eO.s)(n)&&(__DEV__?(0,Q.kG)(!eD(n),"Missing selection set for object of type ".concat(im(e,n)," returned for query field ").concat(t.name.value)):(0,Q.kG)(!eD(n),6),Object.values(n).forEach(r.add,r))})}}function iF(e){var t=nG("stringifyForDisplay");return JSON.stringify(e,function(e,n){return void 0===n?t:n}).split(JSON.stringify(t)).join("")}var iY=Object.create(null);function iB(e){var t=JSON.stringify(e);return iY[t]||(iY[t]=Object.create(null))}function iU(e){var t=iB(e);return t.keyFieldsFn||(t.keyFieldsFn=function(t,n){var r=function(e,t){return n.readField(t,e)},i=n.keyObject=i$(e,function(e){var i=iW(n.storeObject,e,r);return void 0===i&&t!==n.storeObject&&ic.call(t,e[0])&&(i=iW(t,e,iG)),__DEV__?(0,Q.kG)(void 0!==i,"Missing field '".concat(e.join("."),"' while extracting keyFields from ").concat(JSON.stringify(t))):(0,Q.kG)(void 0!==i,2),i});return"".concat(n.typename,":").concat(JSON.stringify(i))})}function iH(e){var t=iB(e);return t.keyArgsFn||(t.keyArgsFn=function(t,n){var r=n.field,i=n.variables,a=n.fieldName,o=JSON.stringify(i$(e,function(e){var n=e[0],a=n.charAt(0);if("@"===a){if(r&&(0,tP.O)(r.directives)){var o=n.slice(1),s=r.directives.find(function(e){return e.name.value===o}),u=s&&eZ(s,i);return u&&iW(u,e.slice(1))}return}if("$"===a){var c=n.slice(1);if(i&&ic.call(i,c)){var l=e.slice(0);return l[0]=c,iW(i,l)}return}if(t)return iW(t,e)}));return(t||"{}"!==o)&&(a+=":"+o),a})}function i$(e,t){var n=new tB;return iz(e).reduce(function(e,r){var i,a=t(r);if(void 0!==a){for(var o=r.length-1;o>=0;--o)a=((i={})[r[o]]=a,i);e=n.merge(e,a)}return e},Object.create(null))}function iz(e){var t=iB(e);if(!t.paths){var n=t.paths=[],r=[];e.forEach(function(t,i){(0,tP.k)(t)?(iz(t).forEach(function(e){return n.push(r.concat(e))}),r.length=0):(r.push(t),(0,tP.k)(e[i+1])||(n.push(r.slice(0)),r.length=0))})}return t.paths}function iG(e,t){return e[t]}function iW(e,t,n){return n=n||iG,iK(t.reduce(function e(t,r){return(0,tP.k)(t)?t.map(function(t){return e(t,r)}):t&&n(t,r)},e))}function iK(e){return(0,eO.s)(e)?(0,tP.k)(e)?e.map(iK):i$(Object.keys(e).sort(),function(t){return iW(e,t)}):e}function iV(e){return void 0!==e.args?e.args:e.field?eZ(e.field,e.variables):null}eK.setStringify(nx);var iq=function(){},iZ=function(e,t){return t.fieldName},iX=function(e,t,n){return(0,n.mergeObjects)(e,t)},iJ=function(e,t){return t},iQ=function(){function e(e){this.config=e,this.typePolicies=Object.create(null),this.toBeAdded=Object.create(null),this.supertypeMap=new Map,this.fuzzySubtypes=new Map,this.rootIdsByTypename=Object.create(null),this.rootTypenamesById=Object.create(null),this.usingPossibleTypes=!1,this.config=(0,en.pi)({dataIdFromObject:id},e),this.cache=this.config.cache,this.setRootTypename("Query"),this.setRootTypename("Mutation"),this.setRootTypename("Subscription"),e.possibleTypes&&this.addPossibleTypes(e.possibleTypes),e.typePolicies&&this.addTypePolicies(e.typePolicies)}return e.prototype.identify=function(e,t){var n,r,i=this,a=t&&(t.typename||(null===(n=t.storeObject)||void 0===n?void 0:n.__typename))||e.__typename;if(a===this.rootTypenamesById.ROOT_QUERY)return["ROOT_QUERY"];for(var o=t&&t.storeObject||e,s=(0,en.pi)((0,en.pi)({},t),{typename:a,storeObject:o,readField:t&&t.readField||function(){var e=i0(arguments,o);return i.readField(e,{store:i.cache.data,variables:e.variables})}}),u=a&&this.getTypePolicy(a),c=u&&u.keyFn||this.config.dataIdFromObject;c;){var l=c((0,en.pi)((0,en.pi)({},e),o),s);if((0,tP.k)(l))c=iU(l);else{r=l;break}}return r=r?String(r):void 0,s.keyObject?[r,s.keyObject]:[r]},e.prototype.addTypePolicies=function(e){var t=this;Object.keys(e).forEach(function(n){var r=e[n],i=r.queryType,a=r.mutationType,o=r.subscriptionType,s=(0,en._T)(r,["queryType","mutationType","subscriptionType"]);i&&t.setRootTypename("Query",n),a&&t.setRootTypename("Mutation",n),o&&t.setRootTypename("Subscription",n),ic.call(t.toBeAdded,n)?t.toBeAdded[n].push(s):t.toBeAdded[n]=[s]})},e.prototype.updateTypePolicy=function(e,t){var n=this,r=this.getTypePolicy(e),i=t.keyFields,a=t.fields;function o(e,t){e.merge="function"==typeof t?t:!0===t?iX:!1===t?iJ:e.merge}o(r,t.merge),r.keyFn=!1===i?iq:(0,tP.k)(i)?iU(i):"function"==typeof i?i:r.keyFn,a&&Object.keys(a).forEach(function(t){var r=n.getFieldPolicy(e,t,!0),i=a[t];if("function"==typeof i)r.read=i;else{var s=i.keyArgs,u=i.read,c=i.merge;r.keyFn=!1===s?iZ:(0,tP.k)(s)?iH(s):"function"==typeof s?s:r.keyFn,"function"==typeof u&&(r.read=u),o(r,c)}r.read&&r.merge&&(r.keyFn=r.keyFn||iZ)})},e.prototype.setRootTypename=function(e,t){void 0===t&&(t=e);var n="ROOT_"+e.toUpperCase(),r=this.rootTypenamesById[n];t!==r&&(__DEV__?(0,Q.kG)(!r||r===e,"Cannot change root ".concat(e," __typename more than once")):(0,Q.kG)(!r||r===e,3),r&&delete this.rootIdsByTypename[r],this.rootIdsByTypename[t]=n,this.rootTypenamesById[n]=t)},e.prototype.addPossibleTypes=function(e){var t=this;this.usingPossibleTypes=!0,Object.keys(e).forEach(function(n){t.getSupertypeSet(n,!0),e[n].forEach(function(e){t.getSupertypeSet(e,!0).add(n);var r=e.match(ig);r&&r[0]===e||t.fuzzySubtypes.set(e,RegExp(e))})})},e.prototype.getTypePolicy=function(e){var t=this;if(!ic.call(this.typePolicies,e)){var n=this.typePolicies[e]=Object.create(null);n.fields=Object.create(null);var r=this.supertypeMap.get(e);r&&r.size&&r.forEach(function(e){var r=t.getTypePolicy(e),i=r.fields;Object.assign(n,(0,en._T)(r,["fields"])),Object.assign(n.fields,i)})}var i=this.toBeAdded[e];return i&&i.length&&i.splice(0).forEach(function(n){t.updateTypePolicy(e,n)}),this.typePolicies[e]},e.prototype.getFieldPolicy=function(e,t,n){if(e){var r=this.getTypePolicy(e).fields;return r[t]||n&&(r[t]=Object.create(null))}},e.prototype.getSupertypeSet=function(e,t){var n=this.supertypeMap.get(e);return!n&&t&&this.supertypeMap.set(e,n=new Set),n},e.prototype.fragmentMatches=function(e,t,n,r){var i=this;if(!e.typeCondition)return!0;if(!t)return!1;var a=e.typeCondition.name.value;if(t===a)return!0;if(this.usingPossibleTypes&&this.supertypeMap.has(a))for(var o=this.getSupertypeSet(t,!0),s=[o],u=function(e){var t=i.getSupertypeSet(e,!1);t&&t.size&&0>s.indexOf(t)&&s.push(t)},c=!!(n&&this.fuzzySubtypes.size),l=!1,f=0;f1?a:t}:(r=(0,en.pi)({},i),ic.call(r,"from")||(r.from=t)),__DEV__&&void 0===r.from&&__DEV__&&Q.kG.warn("Undefined 'from' passed to readField with arguments ".concat(iF(Array.from(e)))),void 0===r.variables&&(r.variables=n),r}function i2(e){return function(t,n){if((0,tP.k)(t)||(0,tP.k)(n))throw __DEV__?new Q.ej("Cannot automatically merge arrays"):new Q.ej(4);if((0,eO.s)(t)&&(0,eO.s)(n)){var r=e.getFieldValue(t,"__typename"),i=e.getFieldValue(n,"__typename");if(r&&i&&r!==i)return n;if(eD(t)&&iw(n))return e.merge(t.__ref,n),t;if(iw(t)&&eD(n))return e.merge(t,n.__ref),n;if(iw(t)&&iw(n))return(0,en.pi)((0,en.pi)({},t),n)}return n}}function i3(e,t,n){var r="".concat(t).concat(n),i=e.flavors.get(r);return i||e.flavors.set(r,i=e.clientOnly===t&&e.deferred===n?e:(0,en.pi)((0,en.pi)({},e),{clientOnly:t,deferred:n})),i}var i4=function(){function e(e,t,n){this.cache=e,this.reader=t,this.fragments=n}return e.prototype.writeToStore=function(e,t){var n=this,r=t.query,i=t.result,a=t.dataId,o=t.variables,s=t.overwrite,u=e2(r),c=i_();o=(0,en.pi)((0,en.pi)({},e9(u)),o);var l=(0,en.pi)((0,en.pi)({store:e,written:Object.create(null),merge:function(e,t){return c.merge(e,t)},variables:o,varString:nx(o)},iE(r,this.fragments)),{overwrite:!!s,incomingById:new Map,clientOnly:!1,deferred:!1,flavors:new Map}),f=this.processSelectionSet({result:i||Object.create(null),dataId:a,selectionSet:u.selectionSet,mergeTree:{map:new Map},context:l});if(!eD(f))throw __DEV__?new Q.ej("Could not identify object ".concat(JSON.stringify(i))):new Q.ej(7);return l.incomingById.forEach(function(t,r){var i=t.storeObject,a=t.mergeTree,o=t.fieldNodeSet,s=eI(r);if(a&&a.map.size){var u=n.applyMerges(a,s,i,l);if(eD(u))return;i=u}if(__DEV__&&!l.overwrite){var c=Object.create(null);o.forEach(function(e){e.selectionSet&&(c[e.name.value]=!0)});var f=function(e){return!0===c[iv(e)]},d=function(e){var t=a&&a.map.get(e);return Boolean(t&&t.info&&t.info.merge)};Object.keys(i).forEach(function(e){f(e)&&!d(e)&&at(s,i,e,l.store)})}e.merge(r,i)}),e.retain(f.__ref),f},e.prototype.processSelectionSet=function(e){var t=this,n=e.dataId,r=e.result,i=e.selectionSet,a=e.context,o=e.mergeTree,s=this.cache.policies,u=Object.create(null),c=n&&s.rootTypenamesById[n]||eJ(r,i,a.fragmentMap)||n&&a.store.get(n,"__typename");"string"==typeof c&&(u.__typename=c);var l=function(){var e=i0(arguments,u,a.variables);if(eD(e.from)){var t=a.incomingById.get(e.from.__ref);if(t){var n=s.readField((0,en.pi)((0,en.pi)({},e),{from:t.storeObject}),a);if(void 0!==n)return n}}return s.readField(e,a)},f=new Set;this.flattenFields(i,r,a,c).forEach(function(e,n){var i,a=r[eX(n)];if(f.add(n),void 0!==a){var d=s.getStoreFieldName({typename:c,fieldName:n.name.value,field:n,variables:e.variables}),h=i5(o,d),p=t.processFieldValue(a,n,n.selectionSet?i3(e,!1,!1):e,h),b=void 0;n.selectionSet&&(eD(p)||iw(p))&&(b=l("__typename",p));var m=s.getMergeFunction(c,n.name.value,b);m?h.info={field:n,typename:c,merge:m}:i7(o,d),u=e.merge(u,((i={})[d]=p,i))}else __DEV__&&!e.clientOnly&&!e.deferred&&!nj.added(n)&&!s.getReadFunction(c,n.name.value)&&__DEV__&&Q.kG.error("Missing field '".concat(eX(n),"' while writing result ").concat(JSON.stringify(r,null,2)).substring(0,1e3))});try{var d=s.identify(r,{typename:c,selectionSet:i,fragmentMap:a.fragmentMap,storeObject:u,readField:l}),h=d[0],p=d[1];n=n||h,p&&(u=a.merge(u,p))}catch(b){if(!n)throw b}if("string"==typeof n){var m=eI(n),g=a.written[n]||(a.written[n]=[]);if(g.indexOf(i)>=0||(g.push(i),this.reader&&this.reader.isFresh(r,m,i,a)))return m;var v=a.incomingById.get(n);return v?(v.storeObject=a.merge(v.storeObject,u),v.mergeTree=i8(v.mergeTree,o),f.forEach(function(e){return v.fieldNodeSet.add(e)})):a.incomingById.set(n,{storeObject:u,mergeTree:i9(o)?void 0:o,fieldNodeSet:f}),m}return u},e.prototype.processFieldValue=function(e,t,n,r){var i=this;return t.selectionSet&&null!==e?(0,tP.k)(e)?e.map(function(e,a){var o=i.processFieldValue(e,t,n,i5(r,a));return i7(r,a),o}):this.processSelectionSet({result:e,selectionSet:t.selectionSet,context:n,mergeTree:r}):__DEV__?nJ(e):e},e.prototype.flattenFields=function(e,t,n,r){void 0===r&&(r=eJ(t,e,n.fragmentMap));var i=new Map,a=this.cache.policies,o=new n_(!1);return function e(s,u){var c=o.lookup(s,u.clientOnly,u.deferred);c.visited||(c.visited=!0,s.selections.forEach(function(o){if(td(o,n.variables)){var s=u.clientOnly,c=u.deferred;if(!(s&&c)&&(0,tP.O)(o.directives)&&o.directives.forEach(function(e){var t=e.name.value;if("client"===t&&(s=!0),"defer"===t){var r=eZ(e,n.variables);r&&!1===r.if||(c=!0)}}),eQ(o)){var l=i.get(o);l&&(s=s&&l.clientOnly,c=c&&l.deferred),i.set(o,i3(n,s,c))}else{var f=eC(o,n.lookupFragment);if(!f&&o.kind===nL.h.FRAGMENT_SPREAD)throw __DEV__?new Q.ej("No fragment named ".concat(o.name.value)):new Q.ej(8);f&&a.fragmentMatches(f,r,t,n.variables)&&e(f.selectionSet,i3(n,s,c))}}}))}(e,n),i},e.prototype.applyMerges=function(e,t,n,r,i){var a=this;if(e.map.size&&!eD(n)){var o,s,u=!(0,tP.k)(n)&&(eD(t)||iw(t))?t:void 0,c=n;u&&!i&&(i=[eD(u)?u.__ref:u]);var l=function(e,t){return(0,tP.k)(e)?"number"==typeof t?e[t]:void 0:r.store.getFieldValue(e,String(t))};e.map.forEach(function(e,t){var n=l(u,t),o=l(c,t);if(void 0!==o){i&&i.push(t);var f=a.applyMerges(e,n,o,r,i);f!==o&&(s=s||new Map).set(t,f),i&&(0,Q.kG)(i.pop()===t)}}),s&&(n=(0,tP.k)(c)?c.slice(0):(0,en.pi)({},c),s.forEach(function(e,t){n[t]=e}))}return e.info?this.cache.policies.runMergeFunction(t,n,e.info,r,i&&(o=r.store).getStorage.apply(o,i)):n},e}(),i6=[];function i5(e,t){var n=e.map;return n.has(t)||n.set(t,i6.pop()||{map:new Map}),n.get(t)}function i8(e,t){if(e===t||!t||i9(t))return e;if(!e||i9(e))return t;var n=e.info&&t.info?(0,en.pi)((0,en.pi)({},e.info),t.info):e.info||t.info,r=e.map.size&&t.map.size,i=r?new Map:e.map.size?e.map:t.map,a={info:n,map:i};if(r){var o=new Set(t.map.keys());e.map.forEach(function(e,n){a.map.set(n,i8(e,t.map.get(n))),o.delete(n)}),o.forEach(function(n){a.map.set(n,i8(t.map.get(n),e.map.get(n)))})}return a}function i9(e){return!e||!(e.info||e.map.size)}function i7(e,t){var n=e.map,r=n.get(t);r&&i9(r)&&(i6.push(r),n.delete(t))}var ae=new Set;function at(e,t,n,r){var i=function(e){var t=r.getFieldValue(e,n);return"object"==typeof t&&t},a=i(e);if(a){var o=i(t);if(!(!o||eD(a)||(0,nm.D)(a,o)||Object.keys(a).every(function(e){return void 0!==r.getFieldValue(o,e)}))){var s=r.getFieldValue(e,"__typename")||r.getFieldValue(t,"__typename"),u=iv(n),c="".concat(s,".").concat(u);if(!ae.has(c)){ae.add(c);var l=[];(0,tP.k)(a)||(0,tP.k)(o)||[a,o].forEach(function(e){var t=r.getFieldValue(e,"__typename");"string"!=typeof t||l.includes(t)||l.push(t)}),__DEV__&&Q.kG.warn("Cache data may be lost when replacing the ".concat(u," field of a ").concat(s," object.\n\nThis could cause additional (usually avoidable) network requests to fetch data that were otherwise cached.\n\nTo address this problem (which is not a bug in Apollo Client), ").concat(l.length?"either ensure all objects of type "+l.join(" and ")+" have an ID or a custom merge function, or ":"","define a custom merge function for the ").concat(c," field, so InMemoryCache can safely merge these objects:\n\n existing: ").concat(JSON.stringify(a).slice(0,1e3),"\n incoming: ").concat(JSON.stringify(o).slice(0,1e3),"\n\nFor more information about these options, please refer to the documentation:\n\n * Ensuring entity objects have IDs: https://go.apollo.dev/c/generating-unique-identifiers\n * Defining custom merge functions: https://go.apollo.dev/c/merging-non-normalized-objects\n"))}}}}var an=function(e){function t(t){void 0===t&&(t={});var n=e.call(this)||this;return n.watches=new Set,n.typenameDocumentCache=new Map,n.makeVar=r2,n.txCount=0,n.config=ip(t),n.addTypename=!!n.config.addTypename,n.policies=new iQ({cache:n,dataIdFromObject:n.config.dataIdFromObject,possibleTypes:n.config.possibleTypes,typePolicies:n.config.typePolicies}),n.init(),n}return(0,en.ZT)(t,e),t.prototype.init=function(){var e=this.data=new iT.Root({policies:this.policies,resultCaching:this.config.resultCaching});this.optimisticData=e.stump,this.resetResultCache()},t.prototype.resetResultCache=function(e){var t=this,n=this.storeReader,r=this.config.fragments;this.storeWriter=new i4(this,this.storeReader=new iP({cache:this,addTypename:this.addTypename,resultCacheMaxSize:this.config.resultCacheMaxSize,canonizeResults:ib(this.config),canon:e?void 0:n&&n.canon,fragments:r}),r),this.maybeBroadcastWatch=rZ(function(e,n){return t.broadcastWatch(e,n)},{max:this.config.resultCacheMaxSize,makeCacheKey:function(e){var n=e.optimistic?t.optimisticData:t.data;if(iD(n)){var r=e.optimistic,i=e.id,a=e.variables;return n.makeCacheKey(e.query,e.callback,nx({optimistic:r,id:i,variables:a}))}}}),new Set([this.data.group,this.optimisticData.group,]).forEach(function(e){return e.resetCaching()})},t.prototype.restore=function(e){return this.init(),e&&this.data.replace(e),this},t.prototype.extract=function(e){return void 0===e&&(e=!1),(e?this.optimisticData:this.data).extract()},t.prototype.read=function(e){var t=e.returnPartialData,n=void 0!==t&&t;try{return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,config:this.config,returnPartialData:n})).result||null}catch(r){if(r instanceof is)return null;throw r}},t.prototype.write=function(e){try{return++this.txCount,this.storeWriter.writeToStore(this.data,e)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.modify=function(e){if(ic.call(e,"id")&&!e.id)return!1;var t=e.optimistic?this.optimisticData:this.data;try{return++this.txCount,t.modify(e.id||"ROOT_QUERY",e.fields)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.diff=function(e){return this.storeReader.diffQueryAgainstStore((0,en.pi)((0,en.pi)({},e),{store:e.optimistic?this.optimisticData:this.data,rootId:e.id||"ROOT_QUERY",config:this.config}))},t.prototype.watch=function(e){var t=this;return this.watches.size||r0(this),this.watches.add(e),e.immediate&&this.maybeBroadcastWatch(e),function(){t.watches.delete(e)&&!t.watches.size&&r1(t),t.maybeBroadcastWatch.forget(e)}},t.prototype.gc=function(e){nx.reset();var t=this.optimisticData.gc();return e&&!this.txCount&&(e.resetResultCache?this.resetResultCache(e.resetResultIdentities):e.resetResultIdentities&&this.storeReader.resetCanon()),t},t.prototype.retain=function(e,t){return(t?this.optimisticData:this.data).retain(e)},t.prototype.release=function(e,t){return(t?this.optimisticData:this.data).release(e)},t.prototype.identify=function(e){if(eD(e))return e.__ref;try{return this.policies.identify(e)[0]}catch(t){__DEV__&&Q.kG.warn(t)}},t.prototype.evict=function(e){if(!e.id){if(ic.call(e,"id"))return!1;e=(0,en.pi)((0,en.pi)({},e),{id:"ROOT_QUERY"})}try{return++this.txCount,this.optimisticData.evict(e,this.data)}finally{--this.txCount||!1===e.broadcast||this.broadcastWatches()}},t.prototype.reset=function(e){var t=this;return this.init(),nx.reset(),e&&e.discardWatches?(this.watches.forEach(function(e){return t.maybeBroadcastWatch.forget(e)}),this.watches.clear(),r1(this)):this.broadcastWatches(),Promise.resolve()},t.prototype.removeOptimistic=function(e){var t=this.optimisticData.removeLayer(e);t!==this.optimisticData&&(this.optimisticData=t,this.broadcastWatches())},t.prototype.batch=function(e){var t,n=this,r=e.update,i=e.optimistic,a=void 0===i||i,o=e.removeOptimistic,s=e.onWatchUpdated,u=function(e){var i=n,a=i.data,o=i.optimisticData;++n.txCount,e&&(n.data=n.optimisticData=e);try{return t=r(n)}finally{--n.txCount,n.data=a,n.optimisticData=o}},c=new Set;return s&&!this.txCount&&this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e){return c.add(e),!1}})),"string"==typeof a?this.optimisticData=this.optimisticData.addLayer(a,u):!1===a?u(this.data):u(),"string"==typeof o&&(this.optimisticData=this.optimisticData.removeLayer(o)),s&&c.size?(this.broadcastWatches((0,en.pi)((0,en.pi)({},e),{onWatchUpdated:function(e,t){var n=s.call(this,e,t);return!1!==n&&c.delete(e),n}})),c.size&&c.forEach(function(e){return n.maybeBroadcastWatch.dirty(e)})):this.broadcastWatches(e),t},t.prototype.performTransaction=function(e,t){return this.batch({update:e,optimistic:t||null!==t})},t.prototype.transformDocument=function(e){if(this.addTypename){var t=this.typenameDocumentCache.get(e);return t||(t=nj(e),this.typenameDocumentCache.set(e,t),this.typenameDocumentCache.set(t,t)),t}return e},t.prototype.transformForLink=function(e){var t=this.config.fragments;return t?t.transform(e):e},t.prototype.broadcastWatches=function(e){var t=this;this.txCount||this.watches.forEach(function(n){return t.maybeBroadcastWatch(n,e)})},t.prototype.broadcastWatch=function(e,t){var n=e.lastDiff,r=this.diff(e);(!t||(e.optimistic&&"string"==typeof t.optimistic&&(r.fromOptimisticTransaction=!0),!t.onWatchUpdated||!1!==t.onWatchUpdated.call(this,e,r,n)))&&(n&&(0,nm.D)(n.result,r.result)||e.callback(e.lastDiff=r,n))},t}(io),ar={possibleTypes:{ApproveJobProposalSpecPayload:["ApproveJobProposalSpecSuccess","JobAlreadyExistsError","NotFoundError"],BridgePayload:["Bridge","NotFoundError"],CancelJobProposalSpecPayload:["CancelJobProposalSpecSuccess","NotFoundError"],ChainPayload:["Chain","NotFoundError"],CreateAPITokenPayload:["CreateAPITokenSuccess","InputErrors"],CreateBridgePayload:["CreateBridgeSuccess"],CreateCSAKeyPayload:["CSAKeyExistsError","CreateCSAKeySuccess"],CreateFeedsManagerChainConfigPayload:["CreateFeedsManagerChainConfigSuccess","InputErrors","NotFoundError"],CreateFeedsManagerPayload:["CreateFeedsManagerSuccess","DuplicateFeedsManagerError","InputErrors","NotFoundError","SingleFeedsManagerError"],CreateJobPayload:["CreateJobSuccess","InputErrors"],CreateOCR2KeyBundlePayload:["CreateOCR2KeyBundleSuccess"],CreateOCRKeyBundlePayload:["CreateOCRKeyBundleSuccess"],CreateP2PKeyPayload:["CreateP2PKeySuccess"],DeleteAPITokenPayload:["DeleteAPITokenSuccess","InputErrors"],DeleteBridgePayload:["DeleteBridgeConflictError","DeleteBridgeInvalidNameError","DeleteBridgeSuccess","NotFoundError"],DeleteCSAKeyPayload:["DeleteCSAKeySuccess","NotFoundError"],DeleteFeedsManagerChainConfigPayload:["DeleteFeedsManagerChainConfigSuccess","NotFoundError"],DeleteJobPayload:["DeleteJobSuccess","NotFoundError"],DeleteOCR2KeyBundlePayload:["DeleteOCR2KeyBundleSuccess","NotFoundError"],DeleteOCRKeyBundlePayload:["DeleteOCRKeyBundleSuccess","NotFoundError"],DeleteP2PKeyPayload:["DeleteP2PKeySuccess","NotFoundError"],DeleteVRFKeyPayload:["DeleteVRFKeySuccess","NotFoundError"],DisableFeedsManagerPayload:["DisableFeedsManagerSuccess","NotFoundError"],DismissJobErrorPayload:["DismissJobErrorSuccess","NotFoundError"],EnableFeedsManagerPayload:["EnableFeedsManagerSuccess","NotFoundError"],Error:["CSAKeyExistsError","DeleteBridgeConflictError","DeleteBridgeInvalidNameError","DuplicateFeedsManagerError","InputError","JobAlreadyExistsError","NotFoundError","RunJobCannotRunError","SingleFeedsManagerError"],EthTransactionPayload:["EthTransaction","NotFoundError"],FeaturesPayload:["Features"],FeedsManagerPayload:["FeedsManager","NotFoundError"],GetSQLLoggingPayload:["SQLLogging"],GlobalLogLevelPayload:["GlobalLogLevel"],JobPayload:["Job","NotFoundError"],JobProposalPayload:["JobProposal","NotFoundError"],JobRunPayload:["JobRun","NotFoundError"],JobSpec:["BlockHeaderFeederSpec","BlockhashStoreSpec","BootstrapSpec","CronSpec","DirectRequestSpec","FluxMonitorSpec","GatewaySpec","KeeperSpec","OCR2Spec","OCRSpec","StandardCapabilitiesSpec","StreamSpec","VRFSpec","WebhookSpec","WorkflowSpec"],NodePayload:["Node","NotFoundError"],PaginatedPayload:["BridgesPayload","ChainsPayload","EthTransactionAttemptsPayload","EthTransactionsPayload","JobRunsPayload","JobsPayload","NodesPayload"],RejectJobProposalSpecPayload:["NotFoundError","RejectJobProposalSpecSuccess"],RunJobPayload:["NotFoundError","RunJobCannotRunError","RunJobSuccess"],SetGlobalLogLevelPayload:["InputErrors","SetGlobalLogLevelSuccess"],SetSQLLoggingPayload:["SetSQLLoggingSuccess"],SetServicesLogLevelsPayload:["InputErrors","SetServicesLogLevelsSuccess"],UpdateBridgePayload:["NotFoundError","UpdateBridgeSuccess"],UpdateFeedsManagerChainConfigPayload:["InputErrors","NotFoundError","UpdateFeedsManagerChainConfigSuccess"],UpdateFeedsManagerPayload:["InputErrors","NotFoundError","UpdateFeedsManagerSuccess"],UpdateJobProposalSpecDefinitionPayload:["NotFoundError","UpdateJobProposalSpecDefinitionSuccess"],UpdatePasswordPayload:["InputErrors","UpdatePasswordSuccess"],VRFKeyPayload:["NotFoundError","VRFKeySuccess"]}};let ai=ar;var aa=(r=void 0,location.origin),ao=new nh({uri:"".concat(aa,"/query"),credentials:"include"}),as=new ia({cache:new an({possibleTypes:ai.possibleTypes,dataIdFromObject:function(e){if("Chain"===e.__typename){if(!e.network)throw Error("Due to Chain ID not being unique across chain, ensure network is fetched too");return"Chain:".concat(e.network,":").concat(e.id)}return id(e)}}),link:ao});if(a.Z.locale(o),u().defaultFormat="YYYY-MM-DD h:mm:ss A","undefined"!=typeof document){var au,ac,al=f().hydrate;ac=X,al(c.createElement(et,{client:as},c.createElement(d.zj,null,c.createElement(i.MuiThemeProvider,{theme:J.r},c.createElement(ac,null)))),document.getElementById("root"))}})()})(); \ No newline at end of file diff --git a/core/web/assets/main.ec7b7e88c8c965c1e482.js.gz b/core/web/assets/main.008c37495ba29761321d.js.gz similarity index 92% rename from core/web/assets/main.ec7b7e88c8c965c1e482.js.gz rename to core/web/assets/main.008c37495ba29761321d.js.gz index 446f5f6ece1..c5cb981d005 100644 Binary files a/core/web/assets/main.ec7b7e88c8c965c1e482.js.gz and b/core/web/assets/main.008c37495ba29761321d.js.gz differ diff --git a/deployment/ccip/changeset/accept_ownership_test.go b/deployment/ccip/changeset/accept_ownership_test.go index 796db6aed09..1dbef8e7a0b 100644 --- a/deployment/ccip/changeset/accept_ownership_test.go +++ b/deployment/ccip/changeset/accept_ownership_test.go @@ -4,24 +4,17 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" - "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" - - commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" - "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/stretchr/testify/require" "golang.org/x/exp/maps" - "github.com/smartcontractkit/chainlink/v2/core/logger" + commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" ) func Test_NewAcceptOwnershipChangeset(t *testing.T) { - e := NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), memory.MemoryEnvironmentConfig{ - Chains: 2, - NumOfUsersPerChain: 1, - Nodes: 4, - Bootstraps: 1, - }, &TestConfigs{}) + t.Parallel() + e := NewMemoryEnvironment(t) state, err := LoadOnchainState(e.Env) require.NoError(t, err) @@ -29,9 +22,15 @@ func Test_NewAcceptOwnershipChangeset(t *testing.T) { source := allChains[0] dest := allChains[1] - timelocks := map[uint64]*gethwrappers.RBACTimelock{ - source: state.Chains[source].Timelock, - dest: state.Chains[dest].Timelock, + timelockContracts := map[uint64]*proposalutils.TimelockExecutionContracts{ + source: &proposalutils.TimelockExecutionContracts{ + Timelock: state.Chains[source].Timelock, + CallProxy: state.Chains[source].CallProxy, + }, + dest: &proposalutils.TimelockExecutionContracts{ + Timelock: state.Chains[dest].Timelock, + CallProxy: state.Chains[dest].CallProxy, + }, } // at this point we have the initial deploys done, now we need to transfer ownership @@ -40,7 +39,7 @@ func Test_NewAcceptOwnershipChangeset(t *testing.T) { require.NoError(t, err) // compose the transfer ownership and accept ownership changesets - _, err = commonchangeset.ApplyChangesets(t, e.Env, timelocks, []commonchangeset.ChangesetApplication{ + _, err = commonchangeset.ApplyChangesets(t, e.Env, timelockContracts, []commonchangeset.ChangesetApplication{ // note this doesn't have proposals. { Changeset: commonchangeset.WrapChangeSet(commonchangeset.TransferToMCMSWithTimelock), diff --git a/deployment/ccip/changeset/cs_add_chain.go b/deployment/ccip/changeset/cs_add_chain.go index d589d16b779..b3d0df04c93 100644 --- a/deployment/ccip/changeset/cs_add_chain.go +++ b/deployment/ccip/changeset/cs_add_chain.go @@ -169,21 +169,14 @@ func (a AddDonAndSetCandidateChangesetConfig) Validate(e deployment.Environment, } // check that chain config is set up for the new chain - // TODO: feels like we should just have a getter for a particular chain, this pagination - // logic seems a bit out of place here. - allConfigs, err := state.Chains[a.HomeChainSelector].CCIPHome.GetAllChainConfigs(nil, big.NewInt(0), big.NewInt(100)) + chainConfig, err := state.Chains[a.HomeChainSelector].CCIPHome.GetChainConfig(nil, a.NewChainSelector) if err != nil { return nil, fmt.Errorf("get all chain configs: %w", err) } - var found bool - for _, chainConfig := range allConfigs { - if chainConfig.ChainSelector == a.NewChainSelector { - found = true - break - } - } - if !found { - return nil, fmt.Errorf("chain config not set for chain %d", a.NewChainSelector) + + // FChain should never be zero if a chain config is set in CCIPHome + if chainConfig.FChain == 0 { + return nil, fmt.Errorf("chain config not set up for new chain %d", a.NewChainSelector) } err = a.CCIPOCRParams.Validate() diff --git a/deployment/ccip/changeset/cs_add_chain_test.go b/deployment/ccip/changeset/cs_add_chain_test.go index c8d872236c2..96b77f1bd7d 100644 --- a/deployment/ccip/changeset/cs_add_chain_test.go +++ b/deployment/ccip/changeset/cs_add_chain_test.go @@ -1,16 +1,13 @@ package changeset import ( - "math/big" "testing" "time" - "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" - "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" - "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" "github.com/ethereum/go-ethereum/common" @@ -33,13 +30,12 @@ import ( ) func TestAddChainInbound(t *testing.T) { + t.Parallel() // 4 chains where the 4th is added after initial deployment. - e := NewMemoryEnvironmentWithJobs(t, logger.TestLogger(t), memory.MemoryEnvironmentConfig{ - Chains: 4, - NumOfUsersPerChain: 1, - Nodes: 4, - Bootstraps: 1, - }) + e := NewMemoryEnvironment(t, + WithChains(4), + WithJobsOnly(), + ) state, err := LoadOnchainState(e.Env) require.NoError(t, err) // Take first non-home chain as the new chain. @@ -51,13 +47,7 @@ func TestAddChainInbound(t *testing.T) { require.NoError(t, err) require.NoError(t, e.Env.ExistingAddresses.Merge(newAddresses)) - cfg := commontypes.MCMSWithTimelockConfig{ - Canceller: commonchangeset.SingleGroupMCMS(t), - Bypasser: commonchangeset.SingleGroupMCMS(t), - Proposer: commonchangeset.SingleGroupMCMS(t), - TimelockExecutors: e.Env.AllDeployerKeys(), - TimelockMinDelay: big.NewInt(0), - } + cfg := proposalutils.SingleGroupTimelockConfig(t) e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, nil, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(commonchangeset.DeployLinkToken), @@ -80,10 +70,23 @@ func TestAddChainInbound(t *testing.T) { for _, chain := range initialDeploy { chainConfig[chain] = DefaultOCRParams(e.FeedChainSel, nil, nil) } - err = deployCCIPContracts(e.Env, newAddresses, NewChainsConfig{ + newChainCfg := NewChainsConfig{ HomeChainSel: e.HomeChainSel, FeedChainSel: e.FeedChainSel, ChainConfigByChain: chainConfig, + } + e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, nil, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(DeployChainContracts), + Config: DeployChainContractsConfig{ + ChainSelectors: newChainCfg.Chains(), + HomeChainSelector: newChainCfg.HomeChainSel, + }, + }, + { + Changeset: commonchangeset.WrapChangeSet(ConfigureNewChains), + Config: newChainCfg, + }, }) require.NoError(t, err) @@ -145,10 +148,19 @@ func TestAddChainInbound(t *testing.T) { } // transfer ownership to timelock - _, err = commonchangeset.ApplyChangesets(t, e.Env, map[uint64]*gethwrappers.RBACTimelock{ - initialDeploy[0]: state.Chains[initialDeploy[0]].Timelock, - initialDeploy[1]: state.Chains[initialDeploy[1]].Timelock, - initialDeploy[2]: state.Chains[initialDeploy[2]].Timelock, + _, err = commonchangeset.ApplyChangesets(t, e.Env, map[uint64]*proposalutils.TimelockExecutionContracts{ + initialDeploy[0]: { + Timelock: state.Chains[initialDeploy[0]].Timelock, + CallProxy: state.Chains[initialDeploy[0]].CallProxy, + }, + initialDeploy[1]: { + Timelock: state.Chains[initialDeploy[1]].Timelock, + CallProxy: state.Chains[initialDeploy[1]].CallProxy, + }, + initialDeploy[2]: { + Timelock: state.Chains[initialDeploy[2]].Timelock, + CallProxy: state.Chains[initialDeploy[2]].CallProxy, + }, }, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(commonchangeset.TransferToMCMSWithTimelock), @@ -178,9 +190,15 @@ func TestAddChainInbound(t *testing.T) { nodeIDs = append(nodeIDs, node.NodeID) } - _, err = commonchangeset.ApplyChangesets(t, e.Env, map[uint64]*gethwrappers.RBACTimelock{ - e.HomeChainSel: state.Chains[e.HomeChainSel].Timelock, - newChain: state.Chains[newChain].Timelock, + _, err = commonchangeset.ApplyChangesets(t, e.Env, map[uint64]*proposalutils.TimelockExecutionContracts{ + e.HomeChainSel: { + Timelock: state.Chains[e.HomeChainSel].Timelock, + CallProxy: state.Chains[e.HomeChainSel].CallProxy, + }, + newChain: { + Timelock: state.Chains[newChain].Timelock, + CallProxy: state.Chains[newChain].CallProxy, + }, }, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(AddDonAndSetCandidateChangeset), @@ -216,8 +234,11 @@ func TestAddChainInbound(t *testing.T) { Changeset: commonchangeset.WrapChangeSet(PromoteAllCandidatesChangeset), Config: PromoteAllCandidatesChangesetConfig{ HomeChainSelector: e.HomeChainSel, - NewChainSelector: newChain, + DONChainSelector: newChain, NodeIDs: nodeIDs, + MCMS: &MCMSConfig{ + MinDelay: 0, + }, }, }, }) diff --git a/deployment/ccip/changeset/cs_add_lane_test.go b/deployment/ccip/changeset/cs_add_lane_test.go index fbceeaa8472..5c324c975ef 100644 --- a/deployment/ccip/changeset/cs_add_lane_test.go +++ b/deployment/ccip/changeset/cs_add_lane_test.go @@ -11,18 +11,13 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/deployment" - "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) func TestAddLanesWithTestRouter(t *testing.T) { - e := NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), memory.MemoryEnvironmentConfig{ - Chains: 2, - Nodes: 4, - Bootstraps: 1, - }, nil) + t.Parallel() + e := NewMemoryEnvironment(t) // Here we have CR + nodes set up, but no CCIP contracts deployed. state, err := LoadOnchainState(e.Env) require.NoError(t, err) @@ -72,11 +67,7 @@ func TestAddLane(t *testing.T) { t.Parallel() // We add more chains to the chainlink nodes than the number of chains where CCIP is deployed. - e := NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), memory.MemoryEnvironmentConfig{ - Chains: 2, - Nodes: 4, - Bootstraps: 1, - }, nil) + e := NewMemoryEnvironment(t) // Here we have CR + nodes set up, but no CCIP contracts deployed. state, err := LoadOnchainState(e.Env) require.NoError(t, err) diff --git a/deployment/ccip/changeset/cs_active_candidate.go b/deployment/ccip/changeset/cs_ccip_home.go similarity index 69% rename from deployment/ccip/changeset/cs_active_candidate.go rename to deployment/ccip/changeset/cs_ccip_home.go index ecd87e2d399..202d4216b60 100644 --- a/deployment/ccip/changeset/cs_active_candidate.go +++ b/deployment/ccip/changeset/cs_ccip_home.go @@ -1,9 +1,11 @@ package changeset import ( + "context" "fmt" "math/big" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" @@ -24,20 +26,29 @@ var ( type PromoteAllCandidatesChangesetConfig struct { HomeChainSelector uint64 - NewChainSelector uint64 - NodeIDs []string + // DONChainSelector is the chain selector of the DON that we want to promote the candidate config of. + // Note that each (chain, ccip capability version) pair has a unique DON ID. + DONChainSelector uint64 + NodeIDs []string + MCMS *MCMSConfig } func (p PromoteAllCandidatesChangesetConfig) Validate(e deployment.Environment, state CCIPOnChainState) (deployment.Nodes, error) { - if p.HomeChainSelector == 0 { - return nil, fmt.Errorf("HomeChainSelector must be set") + if err := deployment.IsValidChainSelector(p.HomeChainSelector); err != nil { + return nil, fmt.Errorf("home chain selector invalid: %w", err) } - if p.NewChainSelector == 0 { - return nil, fmt.Errorf("NewChainSelector must be set") + if err := deployment.IsValidChainSelector(p.DONChainSelector); err != nil { + return nil, fmt.Errorf("don chain selector invalid: %w", err) } if len(p.NodeIDs) == 0 { return nil, fmt.Errorf("NodeIDs must be set") } + if state.Chains[p.HomeChainSelector].CCIPHome == nil { + return nil, fmt.Errorf("CCIPHome contract does not exist") + } + if state.Chains[p.HomeChainSelector].CapabilityRegistry == nil { + return nil, fmt.Errorf("CapabilityRegistry contract does not exist") + } nodes, err := deployment.NodeInfo(p.NodeIDs, e.Offchain) if err != nil { @@ -47,21 +58,38 @@ func (p PromoteAllCandidatesChangesetConfig) Validate(e deployment.Environment, donID, err := internal.DonIDForChain( state.Chains[p.HomeChainSelector].CapabilityRegistry, state.Chains[p.HomeChainSelector].CCIPHome, - p.NewChainSelector, + p.DONChainSelector, ) if err != nil { return nil, fmt.Errorf("fetch don id for chain: %w", err) } + if donID == 0 { + return nil, fmt.Errorf("don doesn't exist in CR for chain %d", p.DONChainSelector) + } - // check if the DON ID has a candidate digest set that we can promote - for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} { - candidateDigest, err := state.Chains[p.HomeChainSelector].CCIPHome.GetCandidateDigest(nil, donID, uint8(pluginType)) - if err != nil { - return nil, fmt.Errorf("error fetching candidate digest for pluginType(%s): %w", pluginType.String(), err) - } - if candidateDigest == [32]byte{} { - return nil, fmt.Errorf("candidate digest is zero, must be non-zero to promote") - } + // Check that candidate digest and active digest are not both zero - this is enforced onchain. + commitConfigs, err := state.Chains[p.HomeChainSelector].CCIPHome.GetAllConfigs(&bind.CallOpts{ + Context: context.Background(), + }, donID, uint8(cctypes.PluginTypeCCIPCommit)) + if err != nil { + return nil, fmt.Errorf("fetching commit configs from cciphome: %w", err) + } + + execConfigs, err := state.Chains[p.HomeChainSelector].CCIPHome.GetAllConfigs(&bind.CallOpts{ + Context: context.Background(), + }, donID, uint8(cctypes.PluginTypeCCIPExec)) + if err != nil { + return nil, fmt.Errorf("fetching exec configs from cciphome: %w", err) + } + + if commitConfigs.ActiveConfig.ConfigDigest == [32]byte{} && + commitConfigs.CandidateConfig.ConfigDigest == [32]byte{} { + return nil, fmt.Errorf("commit active and candidate config digests are both zero") + } + + if execConfigs.ActiveConfig.ConfigDigest == [32]byte{} && + execConfigs.CandidateConfig.ConfigDigest == [32]byte{} { + return nil, fmt.Errorf("exec active and candidate config digests are both zero") } return nodes, nil @@ -83,33 +111,44 @@ func PromoteAllCandidatesChangeset( return deployment.ChangesetOutput{}, fmt.Errorf("%w: %w", deployment.ErrInvalidConfig, err) } + txOpts := e.Chains[cfg.HomeChainSelector].DeployerKey + if cfg.MCMS != nil { + txOpts = deployment.SimTransactOpts() + } + + homeChain := e.Chains[cfg.HomeChainSelector] + promoteCandidateOps, err := promoteAllCandidatesForChainOps( + homeChain, + txOpts, state.Chains[cfg.HomeChainSelector].CapabilityRegistry, state.Chains[cfg.HomeChainSelector].CCIPHome, - cfg.NewChainSelector, + cfg.DONChainSelector, nodes.NonBootstraps(), + cfg.MCMS != nil, ) if err != nil { - return deployment.ChangesetOutput{}, err + return deployment.ChangesetOutput{}, fmt.Errorf("generating promote candidate ops: %w", err) } - var ( - timelocksPerChain = map[uint64]common.Address{ + // Disabled MCMS means that we already executed the txes, so just return early w/out the proposals. + if cfg.MCMS == nil { + return deployment.ChangesetOutput{}, nil + } + + prop, err := proposalutils.BuildProposalFromBatches( + map[uint64]common.Address{ cfg.HomeChainSelector: state.Chains[cfg.HomeChainSelector].Timelock.Address(), - } - proposerMCMSes = map[uint64]*gethwrappers.ManyChainMultiSig{ + }, + map[uint64]*gethwrappers.ManyChainMultiSig{ cfg.HomeChainSelector: state.Chains[cfg.HomeChainSelector].ProposerMcm, - } - ) - prop, err := proposalutils.BuildProposalFromBatches( - timelocksPerChain, - proposerMCMSes, + }, []timelock.BatchChainOperation{{ ChainIdentifier: mcms.ChainIdentifier(cfg.HomeChainSelector), Batch: promoteCandidateOps, }}, "promoteCandidate for commit and execution", - 0, // minDelay + cfg.MCMS.MinDelay, ) if err != nil { return deployment.ChangesetOutput{}, err @@ -208,6 +247,10 @@ func setCandidateOnExistingDon( if err != nil { return nil, fmt.Errorf("fetch don id for chain: %w", err) } + if donID == 0 { + return nil, fmt.Errorf("don doesn't exist in CR for chain %d", chainSelector) + } + fmt.Printf("donID: %d", donID) encodedSetCandidateCall, err := internal.CCIPHomeABI.Pack( "setCandidate", @@ -246,19 +289,21 @@ func setCandidateOnExistingDon( } // promoteCandidateOp will create the MCMS Operation for `promoteCandidateAndRevokeActive` directed towards the capabilityRegistry -func promoteCandidateOp(donID uint32, pluginType uint8, capReg *capabilities_registry.CapabilitiesRegistry, - ccipHome *ccip_home.CCIPHome, nodes deployment.Nodes) (mcms.Operation, error) { - +func promoteCandidateOp( + homeChain deployment.Chain, + txOpts *bind.TransactOpts, + donID uint32, + pluginType uint8, + capReg *capabilities_registry.CapabilitiesRegistry, + ccipHome *ccip_home.CCIPHome, + nodes deployment.Nodes, + mcmsEnabled bool, +) (mcms.Operation, error) { allConfigs, err := ccipHome.GetAllConfigs(nil, donID, pluginType) if err != nil { return mcms.Operation{}, err } - if allConfigs.CandidateConfig.ConfigDigest == [32]byte{} { - return mcms.Operation{}, fmt.Errorf("candidate digest is empty, expected nonempty") - } - fmt.Printf("commit candidate digest after setCandidate: %x\n", allConfigs.CandidateConfig.ConfigDigest) - encodedPromotionCall, err := internal.CCIPHomeABI.Pack( "promoteCandidateAndRevokeActive", donID, @@ -271,7 +316,7 @@ func promoteCandidateOp(donID uint32, pluginType uint8, capReg *capabilities_reg } updateDonTx, err := capReg.UpdateDON( - deployment.SimTransactOpts(), + txOpts, donID, nodes.PeerIDs(), []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ @@ -286,6 +331,13 @@ func promoteCandidateOp(donID uint32, pluginType uint8, capReg *capabilities_reg if err != nil { return mcms.Operation{}, fmt.Errorf("error creating updateDon op for donID(%d) and plugin type (%d): %w", donID, pluginType, err) } + if !mcmsEnabled { + _, err = deployment.ConfirmIfNoError(homeChain, updateDonTx, err) + if err != nil { + return mcms.Operation{}, fmt.Errorf("error confirming updateDon call for donID(%d) and plugin type (%d): %w", donID, pluginType, err) + } + } + return mcms.Operation{ To: capReg.Address(), Data: updateDonTx.Data(), @@ -295,25 +347,31 @@ func promoteCandidateOp(donID uint32, pluginType uint8, capReg *capabilities_reg // promoteAllCandidatesForChainOps promotes the candidate commit and exec configs to active by calling promoteCandidateAndRevokeActive on CCIPHome through the UpdateDON call on CapReg contract func promoteAllCandidatesForChainOps( + homeChain deployment.Chain, + txOpts *bind.TransactOpts, capReg *capabilities_registry.CapabilitiesRegistry, ccipHome *ccip_home.CCIPHome, chainSelector uint64, nodes deployment.Nodes, + mcmsEnabled bool, ) ([]mcms.Operation, error) { // fetch DON ID for the chain donID, err := internal.DonIDForChain(capReg, ccipHome, chainSelector) if err != nil { return nil, fmt.Errorf("fetch don id for chain: %w", err) } + if donID == 0 { + return nil, fmt.Errorf("don doesn't exist in CR for chain %d", chainSelector) + } var mcmsOps []mcms.Operation - updateCommitOp, err := promoteCandidateOp(donID, uint8(cctypes.PluginTypeCCIPCommit), capReg, ccipHome, nodes) + updateCommitOp, err := promoteCandidateOp(homeChain, txOpts, donID, uint8(cctypes.PluginTypeCCIPCommit), capReg, ccipHome, nodes, mcmsEnabled) if err != nil { return nil, fmt.Errorf("promote candidate op: %w", err) } mcmsOps = append(mcmsOps, updateCommitOp) - updateExecOp, err := promoteCandidateOp(donID, uint8(cctypes.PluginTypeCCIPExec), capReg, ccipHome, nodes) + updateExecOp, err := promoteCandidateOp(homeChain, txOpts, donID, uint8(cctypes.PluginTypeCCIPExec), capReg, ccipHome, nodes, mcmsEnabled) if err != nil { return nil, fmt.Errorf("promote candidate op: %w", err) } diff --git a/deployment/ccip/changeset/cs_active_candidate_test.go b/deployment/ccip/changeset/cs_ccip_home_test.go similarity index 61% rename from deployment/ccip/changeset/cs_active_candidate_test.go rename to deployment/ccip/changeset/cs_ccip_home_test.go index 0fb29242794..47f262d3f83 100644 --- a/deployment/ccip/changeset/cs_active_candidate_test.go +++ b/deployment/ccip/changeset/cs_ccip_home_test.go @@ -3,6 +3,7 @@ package changeset import ( "testing" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" @@ -12,7 +13,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" - "github.com/smartcontractkit/chainlink/deployment/environment/memory" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" @@ -22,20 +23,14 @@ import ( commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" - - "github.com/smartcontractkit/chainlink/v2/core/logger" ) func TestActiveCandidate(t *testing.T) { t.Skipf("to be enabled after latest cl-ccip is compatible") - - lggr := logger.TestLogger(t) - tenv := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, memory.MemoryEnvironmentConfig{ - Chains: 3, - NumOfUsersPerChain: 1, - Nodes: 5, - Bootstraps: 1, - }, nil) + t.Parallel() + tenv := NewMemoryEnvironment(t, + WithChains(3), + WithNodes(5)) e := tenv.Env state, err := LoadOnchainState(tenv.Env) require.NoError(t, err) @@ -91,11 +86,15 @@ func TestActiveCandidate(t *testing.T) { ConfirmExecWithSeqNrsForAll(t, e, state, expectedSeqNumExec, startBlocks) // compose the transfer ownership and accept ownership changesets - timelocks := make(map[uint64]*gethwrappers.RBACTimelock) + timelockContracts := make(map[uint64]*proposalutils.TimelockExecutionContracts) for _, chain := range allChains { - timelocks[chain] = state.Chains[chain].Timelock + timelockContracts[chain] = &proposalutils.TimelockExecutionContracts{ + Timelock: state.Chains[chain].Timelock, + CallProxy: state.Chains[chain].CallProxy, + } } - _, err = commonchangeset.ApplyChangesets(t, e, timelocks, []commonchangeset.ChangesetApplication{ + + _, err = commonchangeset.ApplyChangesets(t, e, timelockContracts, []commonchangeset.ChangesetApplication{ // note this doesn't have proposals. { Changeset: commonchangeset.WrapChangeSet(commonchangeset.TransferToMCMSWithTimelock), @@ -112,6 +111,7 @@ func TestActiveCandidate(t *testing.T) { capReg, ccipHome := state.Chains[tenv.HomeChainSel].CapabilityRegistry, state.Chains[tenv.HomeChainSel].CCIPHome donID, err := internal.DonIDForChain(capReg, ccipHome, tenv.FeedChainSel) require.NoError(t, err) + require.NotEqual(t, uint32(0), donID) donInfo, err := state.Chains[tenv.HomeChainSel].CapabilityRegistry.GetDON(nil, donID) require.NoError(t, err) require.Equal(t, 5, len(donInfo.NodeP2PIds)) @@ -176,8 +176,11 @@ func TestActiveCandidate(t *testing.T) { Batch: setCommitCandidateOp, }}, "set new candidates on commit plugin", 0) require.NoError(t, err) - setCommitCandidateSigned := commonchangeset.SignProposal(t, e, setCommitCandidateProposal) - commonchangeset.ExecuteProposal(t, e, setCommitCandidateSigned, state.Chains[tenv.HomeChainSel].Timelock, tenv.HomeChainSel) + setCommitCandidateSigned := proposalutils.SignProposal(t, e, setCommitCandidateProposal) + proposalutils.ExecuteProposal(t, e, setCommitCandidateSigned, &proposalutils.TimelockExecutionContracts{ + Timelock: state.Chains[tenv.HomeChainSel].Timelock, + CallProxy: state.Chains[tenv.HomeChainSel].CallProxy, + }, tenv.HomeChainSel) // create the op for the commit plugin as well setExecCandidateOp, err := setCandidateOnExistingDon( @@ -194,8 +197,11 @@ func TestActiveCandidate(t *testing.T) { Batch: setExecCandidateOp, }}, "set new candidates on commit and exec plugins", 0) require.NoError(t, err) - setExecCandidateSigned := commonchangeset.SignProposal(t, e, setExecCandidateProposal) - commonchangeset.ExecuteProposal(t, e, setExecCandidateSigned, state.Chains[tenv.HomeChainSel].Timelock, tenv.HomeChainSel) + setExecCandidateSigned := proposalutils.SignProposal(t, e, setExecCandidateProposal) + proposalutils.ExecuteProposal(t, e, setExecCandidateSigned, &proposalutils.TimelockExecutionContracts{ + Timelock: state.Chains[tenv.HomeChainSel].Timelock, + CallProxy: state.Chains[tenv.HomeChainSel].CallProxy, + }, tenv.HomeChainSel) // check setup was successful by confirming number of nodes from cap reg donInfo, err = state.Chains[tenv.HomeChainSel].CapabilityRegistry.GetDON(nil, donID) @@ -214,15 +220,25 @@ func TestActiveCandidate(t *testing.T) { oldCandidateDigest, err := state.Chains[tenv.HomeChainSel].CCIPHome.GetCandidateDigest(nil, donID, uint8(cctypes.PluginTypeCCIPExec)) require.NoError(t, err) - promoteOps, err := promoteAllCandidatesForChainOps(state.Chains[tenv.HomeChainSel].CapabilityRegistry, state.Chains[tenv.HomeChainSel].CCIPHome, tenv.FeedChainSel, nodes.NonBootstraps()) + promoteOps, err := promoteAllCandidatesForChainOps( + tenv.Env.Chains[tenv.HomeChainSel], + deployment.SimTransactOpts(), + state.Chains[tenv.HomeChainSel].CapabilityRegistry, + state.Chains[tenv.HomeChainSel].CCIPHome, + tenv.FeedChainSel, + nodes.NonBootstraps(), + true) require.NoError(t, err) promoteProposal, err := proposalutils.BuildProposalFromBatches(timelocksPerChain, proposerMCMSes, []timelock.BatchChainOperation{{ ChainIdentifier: mcms.ChainIdentifier(tenv.HomeChainSel), Batch: promoteOps, }}, "promote candidates and revoke actives", 0) require.NoError(t, err) - promoteSigned := commonchangeset.SignProposal(t, e, promoteProposal) - commonchangeset.ExecuteProposal(t, e, promoteSigned, state.Chains[tenv.HomeChainSel].Timelock, tenv.HomeChainSel) + promoteSigned := proposalutils.SignProposal(t, e, promoteProposal) + proposalutils.ExecuteProposal(t, e, promoteSigned, &proposalutils.TimelockExecutionContracts{ + Timelock: state.Chains[tenv.HomeChainSel].Timelock, + CallProxy: state.Chains[tenv.HomeChainSel].CallProxy, + }, tenv.HomeChainSel) // [NEW ACTIVE, NO CANDIDATE] done promoting // [NEW ACTIVE, NO CANDIDATE] check onchain state @@ -244,3 +260,121 @@ func TestActiveCandidate(t *testing.T) { require.NoError(t, err) // [NEW ACTIVE, NO CANDIDATE] done sending successful request } + +func Test_PromoteCandidate(t *testing.T) { + for _, tc := range []struct { + name string + mcmsEnabled bool + }{ + { + name: "MCMS enabled", + mcmsEnabled: true, + }, + { + name: "MCMS disabled", + mcmsEnabled: false, + }, + } { + t.Run(tc.name, func(t *testing.T) { + ctx := testcontext.Get(t) + tenv := NewMemoryEnvironment(t, + WithChains(2), + WithNodes(4)) + state, err := LoadOnchainState(tenv.Env) + require.NoError(t, err) + + // Deploy to all chains. + allChains := maps.Keys(tenv.Env.Chains) + source := allChains[0] + dest := allChains[1] + + nodes, err := deployment.NodeInfo(tenv.Env.NodeIDs, tenv.Env.Offchain) + require.NoError(t, err) + + var nodeIDs []string + for _, node := range nodes { + nodeIDs = append(nodeIDs, node.NodeID) + } + + if tc.mcmsEnabled { + // Transfer ownership to timelock so that we can promote the zero digest later down the line. + _, err = commonchangeset.ApplyChangesets(t, tenv.Env, map[uint64]*proposalutils.TimelockExecutionContracts{ + source: { + Timelock: state.Chains[source].Timelock, + CallProxy: state.Chains[source].CallProxy, + }, + dest: { + Timelock: state.Chains[dest].Timelock, + CallProxy: state.Chains[dest].CallProxy, + }, + tenv.HomeChainSel: { + Timelock: state.Chains[tenv.HomeChainSel].Timelock, + CallProxy: state.Chains[tenv.HomeChainSel].CallProxy, + }, + }, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(commonchangeset.TransferToMCMSWithTimelock), + Config: genTestTransferOwnershipConfig(tenv, allChains, state), + }, + }) + require.NoError(t, err) + assertTimelockOwnership(t, tenv, allChains, state) + } + + var ( + capReg = state.Chains[tenv.HomeChainSel].CapabilityRegistry + ccipHome = state.Chains[tenv.HomeChainSel].CCIPHome + ) + donID, err := internal.DonIDForChain(capReg, ccipHome, dest) + require.NoError(t, err) + require.NotEqual(t, uint32(0), donID) + candidateDigestCommitBefore, err := ccipHome.GetCandidateDigest(&bind.CallOpts{ + Context: ctx, + }, donID, uint8(types.PluginTypeCCIPCommit)) + require.NoError(t, err) + require.Equal(t, [32]byte{}, candidateDigestCommitBefore) + candidateDigestExecBefore, err := ccipHome.GetCandidateDigest(&bind.CallOpts{ + Context: ctx, + }, donID, uint8(types.PluginTypeCCIPExec)) + require.NoError(t, err) + require.Equal(t, [32]byte{}, candidateDigestExecBefore) + + var mcmsConfig *MCMSConfig + if tc.mcmsEnabled { + mcmsConfig = &MCMSConfig{ + MinDelay: 0, + } + } + _, err = commonchangeset.ApplyChangesets(t, tenv.Env, map[uint64]*proposalutils.TimelockExecutionContracts{ + tenv.HomeChainSel: { + Timelock: state.Chains[tenv.HomeChainSel].Timelock, + CallProxy: state.Chains[tenv.HomeChainSel].CallProxy, + }, + }, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(PromoteAllCandidatesChangeset), + Config: PromoteAllCandidatesChangesetConfig{ + HomeChainSelector: tenv.HomeChainSel, + DONChainSelector: dest, + NodeIDs: nodeIDs, + MCMS: mcmsConfig, + }, + }, + }) + require.NoError(t, err) + + // after promoting the zero digest, active digest should also be zero + activeDigestCommit, err := ccipHome.GetActiveDigest(&bind.CallOpts{ + Context: ctx, + }, donID, uint8(types.PluginTypeCCIPCommit)) + require.NoError(t, err) + require.Equal(t, [32]byte{}, activeDigestCommit) + + activeDigestExec, err := ccipHome.GetActiveDigest(&bind.CallOpts{ + Context: ctx, + }, donID, uint8(types.PluginTypeCCIPExec)) + require.NoError(t, err) + require.Equal(t, [32]byte{}, activeDigestExec) + }) + } +} diff --git a/deployment/ccip/changeset/cs_deploy_chain.go b/deployment/ccip/changeset/cs_deploy_chain.go index e2762b27578..5acb8e15307 100644 --- a/deployment/ccip/changeset/cs_deploy_chain.go +++ b/deployment/ccip/changeset/cs_deploy_chain.go @@ -65,38 +65,6 @@ func (c DeployChainContractsConfig) Validate() error { return nil } -// deployCCIPContracts assumes the following contracts are deployed: -// - Capability registry -// - CCIP home -// - RMN home -// - Fee tokens on all chains. -// and present in ExistingAddressBook. -// It then deploys the rest of the CCIP chain contracts to the selected chains -// registers the nodes with the capability registry and creates a DON for -// each new chain. -func deployCCIPContracts( - e deployment.Environment, - ab deployment.AddressBook, - c NewChainsConfig) error { - err := deployChainContractsForChains(e, ab, c.HomeChainSel, c.Chains()) - if err != nil { - e.Logger.Errorw("Failed to deploy chain contracts", "err", err) - return err - } - err = e.ExistingAddresses.Merge(ab) - if err != nil { - e.Logger.Errorw("Failed to merge address book", "err", err) - return err - } - err = configureChain(e, c) - if err != nil { - e.Logger.Errorw("Failed to add chain", "err", err) - return err - } - - return nil -} - func deployChainContractsForChains( e deployment.Environment, ab deployment.AddressBook, @@ -412,10 +380,11 @@ func deployChainContracts( chain.DeployerKey, chain.Client, offramp.OffRampStaticConfig{ - ChainSelector: chain.Selector, - RmnRemote: rmnProxyContract.Address(), - NonceManager: nmContract.Address(), - TokenAdminRegistry: tokenAdminReg.Address(), + ChainSelector: chain.Selector, + GasForCallExactCheck: 5_000, + RmnRemote: rmnProxyContract.Address(), + NonceManager: nmContract.Address(), + TokenAdminRegistry: tokenAdminReg.Address(), }, offramp.OffRampDynamicConfig{ FeeQuoter: feeQuoterContract.Address(), diff --git a/deployment/ccip/changeset/cs_deploy_chain_test.go b/deployment/ccip/changeset/cs_deploy_chain_test.go index 234d73cc4b5..9e1a581112d 100644 --- a/deployment/ccip/changeset/cs_deploy_chain_test.go +++ b/deployment/ccip/changeset/cs_deploy_chain_test.go @@ -3,7 +3,6 @@ package changeset import ( "encoding/json" "fmt" - "math/big" "testing" "github.com/stretchr/testify/require" @@ -11,12 +10,14 @@ import ( "github.com/smartcontractkit/chainlink/deployment" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/v2/core/logger" ) func TestDeployChainContractsChangeset(t *testing.T) { + t.Parallel() lggr := logger.TestLogger(t) e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ Bootstraps: 1, @@ -30,13 +31,7 @@ func TestDeployChainContractsChangeset(t *testing.T) { p2pIds := nodes.NonBootstraps().PeerIDs() cfg := make(map[uint64]commontypes.MCMSWithTimelockConfig) for _, chain := range e.AllChainSelectors() { - cfg[chain] = commontypes.MCMSWithTimelockConfig{ - Canceller: commonchangeset.SingleGroupMCMS(t), - Bypasser: commonchangeset.SingleGroupMCMS(t), - Proposer: commonchangeset.SingleGroupMCMS(t), - TimelockExecutors: e.AllDeployerKeys(), - TimelockMinDelay: big.NewInt(0), - } + cfg[chain] = proposalutils.SingleGroupTimelockConfig(t) } e, err = commonchangeset.ApplyChangesets(t, e, nil, []commonchangeset.ChangesetApplication{ { @@ -99,12 +94,8 @@ func TestDeployChainContractsChangeset(t *testing.T) { } func TestDeployCCIPContracts(t *testing.T) { - lggr := logger.TestLogger(t) - e := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, memory.MemoryEnvironmentConfig{ - Chains: 2, - Nodes: 4, - Bootstraps: 1, - }, nil) + t.Parallel() + e := NewMemoryEnvironment(t) // Deploy all the CCIP contracts. state, err := LoadOnchainState(e.Env) require.NoError(t, err) diff --git a/deployment/ccip/changeset/cs_home_chain_test.go b/deployment/ccip/changeset/cs_home_chain_test.go index a06161f7086..eb620691db0 100644 --- a/deployment/ccip/changeset/cs_home_chain_test.go +++ b/deployment/ccip/changeset/cs_home_chain_test.go @@ -13,6 +13,7 @@ import ( ) func TestDeployHomeChain(t *testing.T) { + t.Parallel() lggr := logger.TestLogger(t) e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ Bootstraps: 1, diff --git a/deployment/ccip/changeset/cs_initial_add_chain.go b/deployment/ccip/changeset/cs_initial_add_chain.go index 13aee106e5a..5ba648d74b5 100644 --- a/deployment/ccip/changeset/cs_initial_add_chain.go +++ b/deployment/ccip/changeset/cs_initial_add_chain.go @@ -242,6 +242,20 @@ func setupConfigInfo(chainSelector uint64, readers [][32]byte, fChain uint8, cfg } } +func isChainConfigEqual(a, b ccip_home.CCIPHomeChainConfig) bool { + mapReader := make(map[[32]byte]struct{}) + for i := range a.Readers { + mapReader[a.Readers[i]] = struct{}{} + } + for i := range b.Readers { + if _, ok := mapReader[b.Readers[i]]; !ok { + return false + } + } + return bytes.Equal(a.Config, b.Config) && + a.FChain == b.FChain +} + func addChainConfig( lggr logger.Logger, h deployment.Chain, @@ -259,6 +273,18 @@ func addChainConfig( return ccip_home.CCIPHomeChainConfigArgs{}, err } chainConfig := setupConfigInfo(chainSelector, p2pIDs, uint8(len(p2pIDs)/3), encodedExtraChainConfig) + existingCfg, err := ccipConfig.GetChainConfig(nil, chainSelector) + if err != nil { + return ccip_home.CCIPHomeChainConfigArgs{}, fmt.Errorf("get chain config for selector %d: %w", chainSelector, err) + } + if isChainConfigEqual(existingCfg, chainConfig.ChainConfig) { + lggr.Infow("Chain config already exists, not applying again", + "homeChain", h.String(), + "addedChain", chainSelector, + "chainConfig", chainConfig, + ) + return chainConfig, nil + } tx, err := ccipConfig.ApplyChainConfigUpdates(h.DeployerKey, nil, []ccip_home.CCIPHomeChainConfigArgs{ chainConfig, }) @@ -282,6 +308,15 @@ func createDON( newChainSel uint64, nodes deployment.Nodes, ) error { + donID, err := internal.DonIDForChain(capReg, ccipHome, newChainSel) + if err != nil { + return fmt.Errorf("fetch don id for chain: %w", err) + } + if donID != 0 { + lggr.Infow("DON already exists not adding it again", "donID", donID, "chain", newChainSel) + return ValidateCCIPHomeConfigSetUp(lggr, capReg, ccipHome, newChainSel) + } + commitConfig, ok := ocr3Configs[cctypes.PluginTypeCCIPCommit] if !ok { return fmt.Errorf("missing commit plugin in ocr3Configs") @@ -297,7 +332,7 @@ func createDON( return err } - donID := latestDon.Id + 1 + donID = latestDon.Id + 1 err = internal.SetupCommitDON(lggr, donID, commitConfig, capReg, home, nodes, ccipHome) if err != nil { @@ -350,11 +385,37 @@ func addDON( "chainSelector", dest.Selector, ) + // check if OCR3 config is already set on offramp + ocr3ConfigSet, err := isOCR3ConfigSetOnOffRamp(lggr, dest, offRamp, offrampOCR3Configs) + if err != nil { + return fmt.Errorf("error checking if OCR3 config is set on offramp: %w", err) + } + if ocr3ConfigSet { + lggr.Infow("OCR3 config already set on offramp, not applying again", "chain", dest.String()) + return nil + } tx, err := offRamp.SetOCR3Configs(dest.DeployerKey, offrampOCR3Configs) if _, err := deployment.ConfirmIfNoError(dest, tx, err); err != nil { return err } + lggr.Infow("Set OCR3 Configs", "chain", dest.String()) + // now check if OCR3 config is set on offramp + ocr3ConfigSet, err = isOCR3ConfigSetOnOffRamp(lggr, dest, offRamp, offrampOCR3Configs) + if err != nil { + return fmt.Errorf("error checking if OCR3 config is set on offramp: %w", err) + } + if !ocr3ConfigSet { + return fmt.Errorf("OCR3 config not set on offramp properly, check logs, chain %s", dest.String()) + } + return nil +} +func isOCR3ConfigSetOnOffRamp( + lggr logger.Logger, + chain deployment.Chain, + offRamp *offramp.OffRamp, + offrampOCR3Configs []offramp.MultiOCR3BaseOCRConfigArgs, +) (bool, error) { mapOfframpOCR3Configs := make(map[cctypes.PluginType]offramp.MultiOCR3BaseOCRConfigArgs) for _, config := range offrampOCR3Configs { mapOfframpOCR3Configs[cctypes.PluginType(config.OcrPluginType)] = config @@ -365,7 +426,7 @@ func addDON( Context: context.Background(), }, uint8(pluginType)) if err != nil { - return err + return false, fmt.Errorf("error fetching OCR3 config for plugin %s chain %s: %w", pluginType.String(), chain.String(), err) } lggr.Debugw("Fetched OCR3 Configs", "MultiOCR3BaseOCRConfig.F", ocrConfig.ConfigInfo.F, @@ -374,35 +435,39 @@ func addDON( "Signers", ocrConfig.Signers, "Transmitters", ocrConfig.Transmitters, "configDigest", hex.EncodeToString(ocrConfig.ConfigInfo.ConfigDigest[:]), - "chain", dest.String(), + "chain", chain.String(), ) // TODO: assertions to be done as part of full state // resprentation validation CCIP-3047 if mapOfframpOCR3Configs[pluginType].ConfigDigest != ocrConfig.ConfigInfo.ConfigDigest { - return fmt.Errorf("%s OCR3 config digest mismatch", pluginType.String()) + lggr.Infow("OCR3 config digest mismatch", "pluginType", pluginType.String()) + return false, nil } if mapOfframpOCR3Configs[pluginType].F != ocrConfig.ConfigInfo.F { - return fmt.Errorf("%s OCR3 config F mismatch", pluginType.String()) + lggr.Infow("OCR3 config F mismatch", "pluginType", pluginType.String()) + return false, nil } if mapOfframpOCR3Configs[pluginType].IsSignatureVerificationEnabled != ocrConfig.ConfigInfo.IsSignatureVerificationEnabled { - return fmt.Errorf("%s OCR3 config signature verification mismatch", pluginType.String()) + lggr.Infow("OCR3 config signature verification mismatch", "pluginType", pluginType.String()) + return false, nil } if pluginType == cctypes.PluginTypeCCIPCommit { // only commit will set signers, exec doesn't need them. for i, signer := range mapOfframpOCR3Configs[pluginType].Signers { if !bytes.Equal(signer.Bytes(), ocrConfig.Signers[i].Bytes()) { - return fmt.Errorf("%s OCR3 config signer mismatch", pluginType.String()) + lggr.Infow("OCR3 config signer mismatch", "pluginType", pluginType.String()) + return false, nil } } } for i, transmitter := range mapOfframpOCR3Configs[pluginType].Transmitters { if !bytes.Equal(transmitter.Bytes(), ocrConfig.Transmitters[i].Bytes()) { - return fmt.Errorf("%s OCR3 config transmitter mismatch", pluginType.String()) + lggr.Infow("OCR3 config transmitter mismatch", "pluginType", pluginType.String()) + return false, nil } } } - - return nil + return true, nil } // ValidateCCIPHomeConfigSetUp checks that the commit and exec active and candidate configs are set up correctly @@ -417,6 +482,10 @@ func ValidateCCIPHomeConfigSetUp( if err != nil { return fmt.Errorf("fetch don id for chain: %w", err) } + if donID == 0 { + return fmt.Errorf("don id for chain(%d) does not exist", chainSel) + } + // final sanity checks on configs. commitConfigs, err := ccipHome.GetAllConfigs(&bind.CallOpts{ //Pending: true, diff --git a/deployment/ccip/changeset/cs_initial_add_chain_test.go b/deployment/ccip/changeset/cs_initial_add_chain_test.go new file mode 100644 index 00000000000..f344068f11b --- /dev/null +++ b/deployment/ccip/changeset/cs_initial_add_chain_test.go @@ -0,0 +1,94 @@ +package changeset + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/chainlink-ccip/pluginconfig" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" + "github.com/stretchr/testify/require" + + commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" +) + +func TestInitialAddChainAppliedTwice(t *testing.T) { + t.Parallel() + // This already applies the initial add chain changeset. + e := NewMemoryEnvironment(t) + + state, err := LoadOnchainState(e.Env) + require.NoError(t, err) + + // now try to apply it again for the second time + // Build the per chain config. + allChains := e.Env.AllChainSelectors() + tokenConfig := NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) + chainConfigs := make(map[uint64]CCIPOCRParams) + timelockContractsPerChain := make(map[uint64]*proposalutils.TimelockExecutionContracts) + + for _, chain := range allChains { + timelockContractsPerChain[chain] = &proposalutils.TimelockExecutionContracts{ + Timelock: state.Chains[chain].Timelock, + CallProxy: state.Chains[chain].CallProxy, + } + tokenInfo := tokenConfig.GetTokenInfo(e.Env.Logger, state.Chains[chain].LinkToken, state.Chains[chain].Weth9) + ocrParams := DefaultOCRParams(e.FeedChainSel, tokenInfo, []pluginconfig.TokenDataObserverConfig{}) + chainConfigs[chain] = ocrParams + } + e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, timelockContractsPerChain, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(ConfigureNewChains), + Config: NewChainsConfig{ + HomeChainSel: e.HomeChainSel, + FeedChainSel: e.FeedChainSel, + ChainConfigByChain: chainConfigs, + }, + }, + }) + require.NoError(t, err) + // send requests + chain1, chain2 := allChains[0], allChains[1] + + _, err = AddLanes(e.Env, AddLanesConfig{ + LaneConfigs: []LaneConfig{ + { + SourceSelector: chain1, + DestSelector: chain2, + InitialPricesBySource: DefaultInitialPrices, + FeeQuoterDestChain: DefaultFeeQuoterDestChainConfig(), + TestRouter: true, + }, + }, + }) + require.NoError(t, err) + ReplayLogs(t, e.Env.Offchain, e.ReplayBlocks) + // Need to keep track of the block number for each chain so that event subscription can be done from that block. + startBlocks := make(map[uint64]*uint64) + // Send a message from each chain to every other chain. + expectedSeqNumExec := make(map[SourceDestPair][]uint64) + expectedSeqNum := make(map[SourceDestPair]uint64) + latesthdr, err := e.Env.Chains[chain2].Client.HeaderByNumber(testcontext.Get(t), nil) + require.NoError(t, err) + block := latesthdr.Number.Uint64() + startBlocks[chain2] = &block + msgSentEvent := TestSendRequest(t, e.Env, state, chain1, chain2, true, router.ClientEVM2AnyMessage{ + Receiver: common.LeftPadBytes(state.Chains[chain2].Receiver.Address().Bytes(), 32), + Data: []byte("hello"), + TokenAmounts: nil, + FeeToken: common.HexToAddress("0x0"), + ExtraArgs: nil, + }) + + expectedSeqNum[SourceDestPair{ + SourceChainSelector: chain1, + DestChainSelector: chain2, + }] = msgSentEvent.SequenceNumber + expectedSeqNumExec[SourceDestPair{ + SourceChainSelector: chain1, + DestChainSelector: chain2, + }] = []uint64{msgSentEvent.SequenceNumber} + ConfirmCommitForAllWithExpectedSeqNums(t, e.Env, state, expectedSeqNum, startBlocks) + ConfirmExecWithSeqNrsForAll(t, e.Env, state, expectedSeqNumExec, startBlocks) +} diff --git a/deployment/ccip/changeset/cs_jobspec_test.go b/deployment/ccip/changeset/cs_jobspec_test.go index 21e80e85aa2..a0445b0d5ee 100644 --- a/deployment/ccip/changeset/cs_jobspec_test.go +++ b/deployment/ccip/changeset/cs_jobspec_test.go @@ -13,6 +13,7 @@ import ( ) func TestJobSpecChangeset(t *testing.T) { + t.Parallel() lggr := logger.TestLogger(t) e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ Chains: 1, diff --git a/deployment/ccip/changeset/cs_update_rmn_config.go b/deployment/ccip/changeset/cs_update_rmn_config.go new file mode 100644 index 00000000000..42eace928c3 --- /dev/null +++ b/deployment/ccip/changeset/cs_update_rmn_config.go @@ -0,0 +1,472 @@ +package changeset + +import ( + "fmt" + "math/big" + "reflect" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_home" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_remote" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" +) + +type RMNNopConfig struct { + NodeIndex uint64 + OffchainPublicKey [32]byte + EVMOnChainPublicKey common.Address + PeerId p2pkey.PeerID +} + +func (c RMNNopConfig) ToRMNHomeNode() rmn_home.RMNHomeNode { + return rmn_home.RMNHomeNode{ + PeerId: c.PeerId, + OffchainPublicKey: c.OffchainPublicKey, + } +} + +func (c RMNNopConfig) ToRMNRemoteSigner() rmn_remote.RMNRemoteSigner { + return rmn_remote.RMNRemoteSigner{ + OnchainPublicKey: c.EVMOnChainPublicKey, + NodeIndex: c.NodeIndex, + } +} + +func (c RMNNopConfig) SetBit(bitmap *big.Int, value bool) { + if value { + bitmap.SetBit(bitmap, int(c.NodeIndex), 1) + } else { + bitmap.SetBit(bitmap, int(c.NodeIndex), 0) + } +} + +func getDeployer(e deployment.Environment, chain uint64, mcmConfig *MCMSConfig) *bind.TransactOpts { + if mcmConfig == nil { + return e.Chains[chain].DeployerKey + } + + return deployment.SimTransactOpts() +} + +type MCMSConfig struct { + MinDelay time.Duration +} + +type SetRMNHomeCandidateConfig struct { + HomeChainSelector uint64 + RMNStaticConfig rmn_home.RMNHomeStaticConfig + RMNDynamicConfig rmn_home.RMNHomeDynamicConfig + DigestToOverride [32]byte + MCMSConfig *MCMSConfig +} + +func (c SetRMNHomeCandidateConfig) Validate(state CCIPOnChainState) error { + err := deployment.IsValidChainSelector(c.HomeChainSelector) + if err != nil { + return err + } + + if len(c.RMNDynamicConfig.OffchainConfig) != 0 { + return fmt.Errorf("RMNDynamicConfig.OffchainConfig must be empty") + } + if len(c.RMNStaticConfig.OffchainConfig) != 0 { + return fmt.Errorf("RMNStaticConfig.OffchainConfig must be empty") + } + + if len(c.RMNStaticConfig.Nodes) > 256 { + return fmt.Errorf("RMNStaticConfig.Nodes must be less than 256") + } + + var ( + peerIds = make(map[[32]byte]struct{}) + offchainPublicKeys = make(map[[32]byte]struct{}) + ) + + for _, node := range c.RMNStaticConfig.Nodes { + if _, exists := peerIds[node.PeerId]; exists { + return fmt.Errorf("peerId %x is duplicated", node.PeerId) + } + peerIds[node.PeerId] = struct{}{} + + if _, exists := offchainPublicKeys[node.OffchainPublicKey]; exists { + return fmt.Errorf("offchainPublicKey %x is duplicated", node.OffchainPublicKey) + } + offchainPublicKeys[node.OffchainPublicKey] = struct{}{} + } + rmnHome := state.Chains[c.HomeChainSelector].RMNHome + + if rmnHome == nil { + return fmt.Errorf("RMNHome not found for chain %d", c.HomeChainSelector) + } + + currentDigest, err := rmnHome.GetCandidateDigest(nil) + if err != nil { + return fmt.Errorf("failed to get RMNHome candidate digest: %w", err) + } + + if currentDigest != c.DigestToOverride { + return fmt.Errorf("current digest (%x) does not match digest to override (%x)", currentDigest[:], c.DigestToOverride[:]) + } + + return nil +} + +type PromoteRMNHomeCandidateConfig struct { + HomeChainSelector uint64 + DigestToPromote [32]byte + MCMSConfig *MCMSConfig +} + +func (c PromoteRMNHomeCandidateConfig) Validate(state CCIPOnChainState) error { + err := deployment.IsValidChainSelector(c.HomeChainSelector) + if err != nil { + return err + } + + rmnHome := state.Chains[c.HomeChainSelector].RMNHome + if rmnHome == nil { + return fmt.Errorf("RMNHome not found for chain %d", c.HomeChainSelector) + } + + currentCandidateDigest, err := rmnHome.GetCandidateDigest(nil) + if err != nil { + return fmt.Errorf("failed to get RMNHome candidate digest: %w", err) + } + + if currentCandidateDigest != c.DigestToPromote { + return fmt.Errorf("current digest (%x) does not match digest to promote (%x)", currentCandidateDigest[:], c.DigestToPromote[:]) + } + + return nil +} + +// NewSetRMNHomeCandidateConfigChangeset creates a changeset to set the RMNHome candidate config +// DigestToOverride is the digest of the current candidate config that the new config will override +// StaticConfig contains the list of nodes with their peerIDs (found in their rageproxy keystore) and offchain public keys (found in the RMN keystore) +// DynamicConfig contains the list of source chains with their chain selectors, f value and the bitmap of the nodes that are oberver for each source chain +// The bitmap is a 256 bit array where each bit represents a node. If the bit matching the index of the node in the static config is set it means that the node is an observer +func NewSetRMNHomeCandidateConfigChangeset(e deployment.Environment, config SetRMNHomeCandidateConfig) (deployment.ChangesetOutput, error) { + state, err := LoadOnchainState(e) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to load onchain state: %w", err) + } + + err = config.Validate(state) + if err != nil { + return deployment.ChangesetOutput{}, err + } + + homeChain, ok := e.Chains[config.HomeChainSelector] + if !ok { + return deployment.ChangesetOutput{}, fmt.Errorf("chain %d not found", config.HomeChainSelector) + } + + rmnHome := state.Chains[config.HomeChainSelector].RMNHome + if rmnHome == nil { + return deployment.ChangesetOutput{}, fmt.Errorf("RMNHome not found for chain %s", homeChain.String()) + } + + deployer := getDeployer(e, config.HomeChainSelector, config.MCMSConfig) + setCandidateTx, err := rmnHome.SetCandidate(deployer, config.RMNStaticConfig, config.RMNDynamicConfig, config.DigestToOverride) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("build RMNHome set candidate calldata for chain %s: %w", homeChain.String(), err) + } + + if config.MCMSConfig == nil { + chain := e.Chains[config.HomeChainSelector] + _, err := chain.Confirm(setCandidateTx) + + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to confirm tx for chain %s: %w", homeChain.String(), deployment.MaybeDataErr(err)) + } + + return deployment.ChangesetOutput{}, nil + } + + op := mcms.Operation{ + To: rmnHome.Address(), + Data: setCandidateTx.Data(), + Value: big.NewInt(0), + } + + batches := []timelock.BatchChainOperation{ + { + ChainIdentifier: mcms.ChainIdentifier(config.HomeChainSelector), + Batch: []mcms.Operation{op}, + }, + } + + timelocksPerChain := buildTimelockAddressPerChain(e, state) + + proposerMCMSes := buildProposerPerChain(e, state) + + prop, err := proposalutils.BuildProposalFromBatches( + timelocksPerChain, + proposerMCMSes, + batches, + "proposal to set candidate config", + config.MCMSConfig.MinDelay, + ) + + return deployment.ChangesetOutput{ + Proposals: []timelock.MCMSWithTimelockProposal{*prop}, + }, nil +} + +func NewPromoteCandidateConfigChangeset(e deployment.Environment, config PromoteRMNHomeCandidateConfig) (deployment.ChangesetOutput, error) { + state, err := LoadOnchainState(e) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to load onchain state: %w", err) + } + + err = config.Validate(state) + if err != nil { + return deployment.ChangesetOutput{}, err + } + + homeChain, ok := e.Chains[config.HomeChainSelector] + + if !ok { + return deployment.ChangesetOutput{}, fmt.Errorf("chain %d not found", config.HomeChainSelector) + } + + rmnHome := state.Chains[config.HomeChainSelector].RMNHome + if rmnHome == nil { + return deployment.ChangesetOutput{}, fmt.Errorf("RMNHome not found for chain %s", homeChain.String()) + } + + currentCandidateDigest, err := rmnHome.GetCandidateDigest(nil) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to get RMNHome candidate digest for chain %s: %w", homeChain.String(), err) + } + + currentActiveDigest, err := rmnHome.GetActiveDigest(nil) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to get RMNHome active digest for chain %s: %w", homeChain.String(), err) + } + + deployer := getDeployer(e, config.HomeChainSelector, config.MCMSConfig) + promoteCandidateTx, err := rmnHome.PromoteCandidateAndRevokeActive(deployer, currentCandidateDigest, currentActiveDigest) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("get call data to promote RMNHome candidate digest for chain %s: %w", homeChain.String(), err) + } + + if config.MCMSConfig == nil { + chain := e.Chains[config.HomeChainSelector] + _, err := chain.Confirm(promoteCandidateTx) + + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to confirm tx for chain %s: %w", homeChain.String(), deployment.MaybeDataErr(err)) + } + + return deployment.ChangesetOutput{}, nil + } + + op := mcms.Operation{ + To: rmnHome.Address(), + Data: promoteCandidateTx.Data(), + Value: big.NewInt(0), + } + + batches := []timelock.BatchChainOperation{ + { + ChainIdentifier: mcms.ChainIdentifier(config.HomeChainSelector), + Batch: []mcms.Operation{op}, + }, + } + + timelocksPerChain := buildTimelockAddressPerChain(e, state) + + proposerMCMSes := buildProposerPerChain(e, state) + + prop, err := proposalutils.BuildProposalFromBatches( + timelocksPerChain, + proposerMCMSes, + batches, + "proposal to promote candidate config", + config.MCMSConfig.MinDelay, + ) + + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to build proposal for chain %s: %w", homeChain.String(), err) + } + + return deployment.ChangesetOutput{ + Proposals: []timelock.MCMSWithTimelockProposal{*prop}, + }, nil +} + +func buildTimelockPerChain(e deployment.Environment, state CCIPOnChainState) map[uint64]*proposalutils.TimelockExecutionContracts { + timelocksPerChain := make(map[uint64]*proposalutils.TimelockExecutionContracts) + for _, chain := range e.Chains { + timelocksPerChain[chain.Selector] = &proposalutils.TimelockExecutionContracts{ + Timelock: state.Chains[chain.Selector].Timelock, + CallProxy: state.Chains[chain.Selector].CallProxy, + } + } + return timelocksPerChain +} + +func buildTimelockAddressPerChain(e deployment.Environment, state CCIPOnChainState) map[uint64]common.Address { + timelocksPerChain := buildTimelockPerChain(e, state) + timelockAddressPerChain := make(map[uint64]common.Address) + for chain, timelock := range timelocksPerChain { + timelockAddressPerChain[chain] = timelock.Timelock.Address() + } + return timelockAddressPerChain +} + +func buildProposerPerChain(e deployment.Environment, state CCIPOnChainState) map[uint64]*gethwrappers.ManyChainMultiSig { + proposerPerChain := make(map[uint64]*gethwrappers.ManyChainMultiSig) + for _, chain := range e.Chains { + proposerPerChain[chain.Selector] = state.Chains[chain.Selector].ProposerMcm + } + return proposerPerChain +} + +func buildRMNRemotePerChain(e deployment.Environment, state CCIPOnChainState) map[uint64]*rmn_remote.RMNRemote { + timelocksPerChain := make(map[uint64]*rmn_remote.RMNRemote) + for _, chain := range e.Chains { + timelocksPerChain[chain.Selector] = state.Chains[chain.Selector].RMNRemote + } + return timelocksPerChain +} + +type SetRMNRemoteConfig struct { + HomeChainSelector uint64 + Signers []rmn_remote.RMNRemoteSigner + F uint64 + MCMSConfig *MCMSConfig +} + +func (c SetRMNRemoteConfig) Validate() error { + err := deployment.IsValidChainSelector(c.HomeChainSelector) + if err != nil { + return err + } + + for i := 0; i < len(c.Signers)-1; i++ { + if c.Signers[i].NodeIndex >= c.Signers[i+1].NodeIndex { + return fmt.Errorf("signers must be in ascending order of nodeIndex") + } + } + + if len(c.Signers) < 2*int(c.F)+1 { + return fmt.Errorf("signers count must greater than or equal to %d", 2*c.F+1) + } + + return nil +} + +func NewSetRMNRemoteConfigChangeset(e deployment.Environment, config SetRMNRemoteConfig) (deployment.ChangesetOutput, error) { + state, err := LoadOnchainState(e) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to load onchain state: %w", err) + } + + lggr := e.Logger + + err = config.Validate() + if err != nil { + return deployment.ChangesetOutput{}, err + } + + homeChain, ok := e.Chains[config.HomeChainSelector] + + if !ok { + return deployment.ChangesetOutput{}, fmt.Errorf("chain %d not found", config.HomeChainSelector) + } + + rmnHome := state.Chains[config.HomeChainSelector].RMNHome + if rmnHome == nil { + return deployment.ChangesetOutput{}, fmt.Errorf("RMNHome not found for chain %s", homeChain.String()) + } + + activeConfig, err := rmnHome.GetActiveDigest(nil) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to get RMNHome active digest for chain %s: %w", homeChain.String(), err) + } + + rmnRemotePerChain := buildRMNRemotePerChain(e, state) + batches := make([]timelock.BatchChainOperation, 0) + for chain, remote := range rmnRemotePerChain { + if remote == nil { + continue + } + + currentVersionConfig, err := remote.GetVersionedConfig(nil) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to get RMNRemote config for chain %s: %w", e.Chains[chain].String(), err) + } + + newConfig := rmn_remote.RMNRemoteConfig{ + RmnHomeContractConfigDigest: activeConfig, + Signers: config.Signers, + F: config.F, + } + + if reflect.DeepEqual(currentVersionConfig.Config, newConfig) { + lggr.Infow("RMNRemote config already up to date", "chain", e.Chains[chain].String()) + continue + } + + deployer := getDeployer(e, chain, config.MCMSConfig) + tx, err := remote.SetConfig(deployer, newConfig) + + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("build call data to set RMNRemote config for chain %s: %w", e.Chains[chain].String(), err) + } + + if config.MCMSConfig == nil { + _, err := e.Chains[chain].Confirm(tx) + + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to confirm tx for chain %s: %w", e.Chains[chain].String(), deployment.MaybeDataErr(err)) + } + } + + op := mcms.Operation{ + To: remote.Address(), + Data: tx.Data(), + Value: big.NewInt(0), + } + + batch := timelock.BatchChainOperation{ + ChainIdentifier: mcms.ChainIdentifier(chain), + Batch: []mcms.Operation{op}, + } + + batches = append(batches, batch) + } + + if config.MCMSConfig == nil { + return deployment.ChangesetOutput{}, nil + } + + timelocksPerChain := buildTimelockAddressPerChain(e, state) + + proposerMCMSes := buildProposerPerChain(e, state) + + prop, err := proposalutils.BuildProposalFromBatches( + timelocksPerChain, + proposerMCMSes, + batches, + "proposal to promote candidate config", + config.MCMSConfig.MinDelay, + ) + + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to build proposal for chain %s: %w", homeChain.String(), err) + } + + return deployment.ChangesetOutput{ + Proposals: []timelock.MCMSWithTimelockProposal{*prop}, + }, nil +} diff --git a/deployment/ccip/changeset/cs_update_rmn_config_test.go b/deployment/ccip/changeset/cs_update_rmn_config_test.go new file mode 100644 index 00000000000..bab70f68fb5 --- /dev/null +++ b/deployment/ccip/changeset/cs_update_rmn_config_test.go @@ -0,0 +1,208 @@ +package changeset + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/deployment" + commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_home" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_remote" +) + +var ( + rmn_staging_1 = RMNNopConfig{ + NodeIndex: 0, + PeerId: deployment.MustPeerIDFromString("p2p_12D3KooWRXxZq3pd4a3ZGkKj7Nt1SQQrnB8CuvbPnnV9KVeMeWqg"), + OffchainPublicKey: [32]byte(common.FromHex("0xb34944857a42444d1b285d7940d6e06682309e0781e43a69676ee9f85c73c2d1")), + EVMOnChainPublicKey: common.HexToAddress("0x5af8ee32316a6427f169a45fdc1b3a91a85ac459e3c1cb91c69e1c51f0c1fc21"), + } + rmn_staging_2 = RMNNopConfig{ + NodeIndex: 1, + PeerId: deployment.MustPeerIDFromString("p2p_12D3KooWEmdxYQFsRbD9aFczF32zA3CcUwuSiWCk2CrmACo4v9RL"), + OffchainPublicKey: [32]byte(common.FromHex("0x68d9f3f274e3985528a923a9bace3d39c55dd778b187b4120b384cc48c892859")), + EVMOnChainPublicKey: common.HexToAddress("0x858589216956f482a0f68b282a7050af4cd48ed2"), + } + rmn_staging_3 = RMNNopConfig{ + NodeIndex: 2, + PeerId: deployment.MustPeerIDFromString("p2p_12D3KooWJS42cNXKJvj6DeZnxEX7aGxhEuap6uNFrz554AbUDw6Q"), + OffchainPublicKey: [32]byte(common.FromHex("0x5af8ee32316a6427f169a45fdc1b3a91a85ac459e3c1cb91c69e1c51f0c1fc21")), + EVMOnChainPublicKey: common.HexToAddress("0x7c5e94162c6fabbdeb3bfe83ae532846e337bfae"), + } +) + +type updateRMNConfigTestCase struct { + useMCMS bool + name string + nops []RMNNopConfig +} + +func TestUpdateRMNConfig(t *testing.T) { + t.Parallel() + testCases := []updateRMNConfigTestCase{ + { + useMCMS: true, + name: "with MCMS", + nops: []RMNNopConfig{rmn_staging_1, rmn_staging_2, rmn_staging_3}, + }, + { + useMCMS: false, + name: "without MCMS", + nops: []RMNNopConfig{rmn_staging_1, rmn_staging_2, rmn_staging_3}, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + updateRMNConfig(t, tc) + }) + } +} + +func updateRMNConfig(t *testing.T, tc updateRMNConfigTestCase) { + e := NewMemoryEnvironment(t) + + state, err := LoadOnchainState(e.Env) + require.NoError(t, err) + + contractsByChain := make(map[uint64][]common.Address) + rmnRemoteAddressesByChain := buildRMNRemoteAddressPerChain(e.Env, state) + for chainSelector, rmnRemoteAddress := range rmnRemoteAddressesByChain { + contractsByChain[chainSelector] = []common.Address{rmnRemoteAddress} + } + + contractsByChain[e.HomeChainSel] = append(contractsByChain[e.HomeChainSel], state.Chains[e.HomeChainSel].RMNHome.Address()) + + timelocksPerChain := buildTimelockPerChain(e.Env, state) + if tc.useMCMS { + // This is required because RMNHome is initially owned by the deployer + _, err = commonchangeset.ApplyChangesets(t, e.Env, timelocksPerChain, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(commonchangeset.TransferToMCMSWithTimelock), + Config: commonchangeset.TransferToMCMSWithTimelockConfig{ + ContractsByChain: contractsByChain, + MinDelay: 0, + }, + }, + }) + } + + rmnHome := state.Chains[e.HomeChainSel].RMNHome + + previousCandidateDigest, err := rmnHome.GetCandidateDigest(nil) + require.NoError(t, err) + previousActiveDigest, err := rmnHome.GetActiveDigest(nil) + require.NoError(t, err) + + var mcmsConfig *MCMSConfig = nil + + if tc.useMCMS { + mcmsConfig = &MCMSConfig{ + MinDelay: 0, + } + } + + nodes := make([]rmn_home.RMNHomeNode, 0, len(tc.nops)) + for _, nop := range tc.nops { + nodes = append(nodes, nop.ToRMNHomeNode()) + } + + setRMNHomeCandidateConfig := SetRMNHomeCandidateConfig{ + HomeChainSelector: e.HomeChainSel, + RMNStaticConfig: rmn_home.RMNHomeStaticConfig{ + Nodes: nodes, + OffchainConfig: []byte(""), + }, + RMNDynamicConfig: rmn_home.RMNHomeDynamicConfig{ + SourceChains: []rmn_home.RMNHomeSourceChain{}, + OffchainConfig: []byte(""), + }, + MCMSConfig: mcmsConfig, + } + + _, err = commonchangeset.ApplyChangesets(t, e.Env, timelocksPerChain, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(NewSetRMNHomeCandidateConfigChangeset), + Config: setRMNHomeCandidateConfig, + }, + }) + + require.NoError(t, err) + + state, err = LoadOnchainState(e.Env) + require.NoError(t, err) + + currentCandidateDigest, err := rmnHome.GetCandidateDigest(nil) + require.NoError(t, err) + currentActiveDigest, err := rmnHome.GetActiveDigest(nil) + require.NoError(t, err) + + require.NotEqual(t, previousCandidateDigest, currentCandidateDigest) + require.Equal(t, previousActiveDigest, currentActiveDigest) + + promoteConfig := PromoteRMNHomeCandidateConfig{ + HomeChainSelector: e.HomeChainSel, + DigestToPromote: currentCandidateDigest, + MCMSConfig: mcmsConfig, + } + + _, err = commonchangeset.ApplyChangesets(t, e.Env, timelocksPerChain, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(NewPromoteCandidateConfigChangeset), + Config: promoteConfig, + }, + }) + + require.NoError(t, err) + currentActiveDigest, err = rmnHome.GetActiveDigest(nil) + + require.NoError(t, err) + require.NotEqual(t, previousActiveDigest, currentActiveDigest) + + signers := make([]rmn_remote.RMNRemoteSigner, 0, len(tc.nops)) + for _, nop := range tc.nops { + signers = append(signers, nop.ToRMNRemoteSigner()) + } + + setRemoteConfig := SetRMNRemoteConfig{ + HomeChainSelector: e.HomeChainSel, + Signers: signers, + F: 0, + MCMSConfig: mcmsConfig, + } + + _, err = commonchangeset.ApplyChangesets(t, e.Env, timelocksPerChain, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(NewSetRMNRemoteConfigChangeset), + Config: setRemoteConfig, + }, + }) + + require.NoError(t, err) + rmnRemotePerChain := buildRMNRemotePerChain(e.Env, state) + for _, rmnRemote := range rmnRemotePerChain { + remoteConfigSetEvents, err := rmnRemote.FilterConfigSet(nil, nil) + require.NoError(t, err) + var lastEvent *rmn_remote.RMNRemoteConfigSet + for remoteConfigSetEvents.Next() { + lastEvent = remoteConfigSetEvents.Event + } + require.NotNil(t, lastEvent) + require.Equal(t, lastEvent.Config.RmnHomeContractConfigDigest, currentActiveDigest) + } +} + +func buildRMNRemoteAddressPerChain(e deployment.Environment, state CCIPOnChainState) map[uint64]common.Address { + rmnRemotePerChain := buildRMNRemotePerChain(e, state) + rmnRemoteAddressPerChain := make(map[uint64]common.Address) + for chain, remote := range rmnRemotePerChain { + if remote == nil { + continue + } + rmnRemoteAddressPerChain[chain] = remote.Address() + } + return rmnRemoteAddressPerChain +} diff --git a/deployment/ccip/changeset/initial_deploy_test.go b/deployment/ccip/changeset/initial_deploy_test.go deleted file mode 100644 index 97e516c8f94..00000000000 --- a/deployment/ccip/changeset/initial_deploy_test.go +++ /dev/null @@ -1,82 +0,0 @@ -package changeset - -import ( - "testing" - - "github.com/ethereum/go-ethereum/common" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" - - "github.com/smartcontractkit/chainlink/deployment/environment/memory" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/logger" - - "github.com/stretchr/testify/require" -) - -func TestInitialDeploy(t *testing.T) { - lggr := logger.TestLogger(t) - tenv := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, memory.MemoryEnvironmentConfig{ - Chains: 3, - Nodes: 4, - Bootstraps: 1, - NumOfUsersPerChain: 1, - }, nil) - e := tenv.Env - state, err := LoadOnchainState(e) - require.NoError(t, err) - // Add all lanes - require.NoError(t, AddLanesForAll(e, state)) - // Need to keep track of the block number for each chain so that event subscription can be done from that block. - startBlocks := make(map[uint64]*uint64) - // Send a message from each chain to every other chain. - expectedSeqNum := make(map[SourceDestPair]uint64) - expectedSeqNumExec := make(map[SourceDestPair][]uint64) - - for src := range e.Chains { - for dest, destChain := range e.Chains { - if src == dest { - continue - } - latesthdr, err := destChain.Client.HeaderByNumber(testcontext.Get(t), nil) - require.NoError(t, err) - block := latesthdr.Number.Uint64() - startBlocks[dest] = &block - require.GreaterOrEqual(t, len(tenv.Users[src]), 1) - msgSentEvent, err := DoSendRequest(t, e, state, - WithTestRouter(false), - WithSourceChain(src), - WithDestChain(dest), - WithEvm2AnyMessage(router.ClientEVM2AnyMessage{ - Receiver: common.LeftPadBytes(state.Chains[dest].Receiver.Address().Bytes(), 32), - Data: []byte("hello"), - TokenAmounts: nil, - FeeToken: common.HexToAddress("0x0"), - ExtraArgs: nil, - }), - WithSender(tenv.Users[src][0]), - ) - require.NoError(t, err) - expectedSeqNum[SourceDestPair{ - SourceChainSelector: src, - DestChainSelector: dest, - }] = msgSentEvent.SequenceNumber - expectedSeqNumExec[SourceDestPair{ - SourceChainSelector: src, - DestChainSelector: dest, - }] = []uint64{msgSentEvent.SequenceNumber} - } - } - - // Wait for all commit reports to land. - ConfirmCommitForAllWithExpectedSeqNums(t, e, state, expectedSeqNum, startBlocks) - - // Confirm token and gas prices are updated - ConfirmTokenPriceUpdatedForAll(t, e, state, startBlocks, - DefaultInitialPrices.LinkPrice, DefaultInitialPrices.WethPrice) - // TODO: Fix gas prices? - //ConfirmGasPriceUpdatedForAll(t, e, state, startBlocks) - // - //// Wait for all exec reports to land - ConfirmExecWithSeqNrsForAll(t, e, state, expectedSeqNumExec, startBlocks) -} diff --git a/deployment/ccip/changeset/internal/deploy_home_chain.go b/deployment/ccip/changeset/internal/deploy_home_chain.go index 6328c329b9a..aa029fd4bec 100644 --- a/deployment/ccip/changeset/internal/deploy_home_chain.go +++ b/deployment/ccip/changeset/internal/deploy_home_chain.go @@ -113,22 +113,34 @@ func LatestCCIPDON(registry *capabilities_registry.CapabilitiesRegistry) (*capab func DonIDForChain(registry *capabilities_registry.CapabilitiesRegistry, ccipHome *ccip_home.CCIPHome, chainSelector uint64) (uint32, error) { dons, err := registry.GetDONs(nil) if err != nil { - return 0, err + return 0, fmt.Errorf("get Dons from capability registry: %w", err) } - // TODO: what happens if there are multiple dons for one chain (accidentally?) + var donIDs []uint32 for _, don := range dons { if len(don.CapabilityConfigurations) == 1 && don.CapabilityConfigurations[0].CapabilityId == CCIPCapabilityID { configs, err := ccipHome.GetAllConfigs(nil, don.Id, uint8(types.PluginTypeCCIPCommit)) if err != nil { - return 0, err + return 0, fmt.Errorf("get all commit configs from cciphome: %w", err) } if configs.ActiveConfig.Config.ChainSelector == chainSelector || configs.CandidateConfig.Config.ChainSelector == chainSelector { - return don.Id, nil + donIDs = append(donIDs, don.Id) } } } - return 0, fmt.Errorf("no DON found for chain %d", chainSelector) + + // more than one DON is an error + if len(donIDs) > 1 { + return 0, fmt.Errorf("more than one DON found for (chain selector %d, ccip capability id %x) pair", chainSelector, CCIPCapabilityID[:]) + } + + // no DON found - don ID of 0 indicates that (this is the case in the CR as well). + if len(donIDs) == 0 { + return 0, nil + } + + // DON found - return it. + return donIDs[0], nil } func BuildSetOCR3ConfigArgs( diff --git a/deployment/ccip/changeset/solana_state.go b/deployment/ccip/changeset/solana_state.go new file mode 100644 index 00000000000..4e5507cfcd3 --- /dev/null +++ b/deployment/ccip/changeset/solana_state.go @@ -0,0 +1,6 @@ +package changeset + +// SolChainState holds a Go binding for all the currently deployed CCIP programs +// on a chain. If a binding is nil, it means here is no such contract on the chain. +type SolCCIPChainState struct { +} diff --git a/deployment/ccip/changeset/state.go b/deployment/ccip/changeset/state.go index 22ae59fc360..af982f35e0a 100644 --- a/deployment/ccip/changeset/state.go +++ b/deployment/ccip/changeset/state.go @@ -23,7 +23,6 @@ import ( commoncs "github.com/smartcontractkit/chainlink/deployment/common/changeset" commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" common_v1_0 "github.com/smartcontractkit/chainlink/deployment/common/view/v1_0" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_rmn_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/registry_module_owner_custom" @@ -48,33 +47,38 @@ import ( ) var ( + // Legacy + CommitStore deployment.ContractType = "CommitStore" + + // Not legacy MockRMN deployment.ContractType = "MockRMN" RMNRemote deployment.ContractType = "RMNRemote" ARMProxy deployment.ContractType = "ARMProxy" WETH9 deployment.ContractType = "WETH9" Router deployment.ContractType = "Router" - CommitStore deployment.ContractType = "CommitStore" TokenAdminRegistry deployment.ContractType = "TokenAdminRegistry" RegistryModule deployment.ContractType = "RegistryModuleOwnerCustom" NonceManager deployment.ContractType = "NonceManager" FeeQuoter deployment.ContractType = "FeeQuoter" CCIPHome deployment.ContractType = "CCIPHome" - CCIPConfig deployment.ContractType = "CCIPConfig" RMNHome deployment.ContractType = "RMNHome" OnRamp deployment.ContractType = "OnRamp" OffRamp deployment.ContractType = "OffRamp" CapabilitiesRegistry deployment.ContractType = "CapabilitiesRegistry" PriceFeed deployment.ContractType = "PriceFeed" - // Note test router maps to a regular router contract. + + // Test contracts. Note test router maps to a regular router contract. TestRouter deployment.ContractType = "TestRouter" Multicall3 deployment.ContractType = "Multicall3" CCIPReceiver deployment.ContractType = "CCIPReceiver" - BurnMintToken deployment.ContractType = "BurnMintToken" - BurnMintTokenPool deployment.ContractType = "BurnMintTokenPool" - USDCToken deployment.ContractType = "USDCToken" USDCMockTransmitter deployment.ContractType = "USDCMockTransmitter" - USDCTokenMessenger deployment.ContractType = "USDCTokenMessenger" - USDCTokenPool deployment.ContractType = "USDCTokenPool" + + // Pools + BurnMintToken deployment.ContractType = "BurnMintToken" + BurnMintTokenPool deployment.ContractType = "BurnMintTokenPool" + USDCToken deployment.ContractType = "USDCToken" + USDCTokenMessenger deployment.ContractType = "USDCTokenMessenger" + USDCTokenPool deployment.ContractType = "USDCTokenPool" ) // CCIPChainState holds a Go binding for all the currently deployed CCIP contracts @@ -117,8 +121,6 @@ type CCIPChainState struct { CapabilityRegistry *capabilities_registry.CapabilitiesRegistry CCIPHome *ccip_home.CCIPHome RMNHome *rmn_home.RMNHome - // TODO remove once staging upgraded. - CCIPConfig *ccip_config.CCIPConfig // Test contracts Receiver *maybe_revert_message_receiver.MaybeRevertMessageReceiver @@ -205,6 +207,13 @@ func (c CCIPChainState) GenerateView() (view.ChainView, error) { } chainView.RMNProxy[c.RMNProxyNew.Address().Hex()] = rmnProxyView } + if c.CCIPHome != nil && c.CapabilityRegistry != nil { + chView, err := v1_6.GenerateCCIPHomeView(c.CapabilityRegistry, c.CCIPHome) + if err != nil { + return chainView, errors.Wrapf(err, "failed to generate CCIP home view for CCIP home %s", c.CCIPHome.Address()) + } + chainView.CCIPHome[c.CCIPHome.Address().Hex()] = chView + } if c.CapabilityRegistry != nil { capRegView, err := common_v1_0.GenerateCapabilityRegistryView(c.CapabilityRegistry) if err != nil { @@ -243,7 +252,8 @@ type CCIPOnChainState struct { // Populated go bindings for the appropriate version for all contracts. // We would hold 2 versions of each contract here. Once we upgrade we can phase out the old one. // When generating bindings, make sure the package name corresponds to the version. - Chains map[uint64]CCIPChainState + Chains map[uint64]CCIPChainState + SolChains map[uint64]SolCCIPChainState } func (s CCIPOnChainState) View(chains []uint64) (map[string]view.ChainView, error) { @@ -311,6 +321,7 @@ func LoadChainState(chain deployment.Chain, addresses map[string]deployment.Type for address, tvStr := range addresses { switch tvStr.String() { case deployment.NewTypeAndVersion(commontypes.RBACTimelock, deployment.Version1_0_0).String(), + deployment.NewTypeAndVersion(commontypes.CallProxy, deployment.Version1_0_0).String(), deployment.NewTypeAndVersion(commontypes.ProposerManyChainMultisig, deployment.Version1_0_0).String(), deployment.NewTypeAndVersion(commontypes.CancellerManyChainMultisig, deployment.Version1_0_0).String(), deployment.NewTypeAndVersion(commontypes.BypasserManyChainMultisig, deployment.Version1_0_0).String(), @@ -452,13 +463,6 @@ func LoadChainState(chain deployment.Chain, addresses map[string]deployment.Type return state, err } state.CCIPHome = ccipHome - case deployment.NewTypeAndVersion(CCIPConfig, deployment.Version1_0_0).String(): - // TODO: Remove once staging upgraded. - ccipConfig, err := ccip_config.NewCCIPConfig(common.HexToAddress(address), chain.Client) - if err != nil { - return state, err - } - state.CCIPConfig = ccipConfig case deployment.NewTypeAndVersion(CCIPReceiver, deployment.Version1_0_0).String(): mr, err := maybe_revert_message_receiver.NewMaybeRevertMessageReceiver(common.HexToAddress(address), chain.Client) if err != nil { diff --git a/deployment/ccip/changeset/state_test.go b/deployment/ccip/changeset/state_test.go index 6e679c265dc..3587332fff2 100644 --- a/deployment/ccip/changeset/state_test.go +++ b/deployment/ccip/changeset/state_test.go @@ -4,19 +4,10 @@ import ( "testing" "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink/deployment/environment/memory" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) func TestSmokeState(t *testing.T) { - lggr := logger.TestLogger(t) - tenv := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, memory.MemoryEnvironmentConfig{ - Chains: 3, - Nodes: 4, - Bootstraps: 1, - NumOfUsersPerChain: 1, - }, nil) + tenv := NewMemoryEnvironment(t, WithChains(3)) state, err := LoadOnchainState(tenv.Env) require.NoError(t, err) _, err = state.View(tenv.Env.AllChainSelectors()) diff --git a/deployment/ccip/changeset/test_assertions.go b/deployment/ccip/changeset/test_assertions.go index a7d3ecf61f8..a114e52b361 100644 --- a/deployment/ccip/changeset/test_assertions.go +++ b/deployment/ccip/changeset/test_assertions.go @@ -16,6 +16,7 @@ import ( "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" commonutils "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/deployment" @@ -220,8 +221,8 @@ func ConfirmCommitForAllWithExpectedSeqNums( return false } }, - 3*time.Minute, - 1*time.Second, + tests.WaitTimeout(t), + 2*time.Second, "all commitments did not confirm", ) } @@ -598,7 +599,7 @@ func RequireConsistently(t *testing.T, condition func() bool, duration time.Dura } } -func SeqNumberRageToSlice(seqRanges map[SourceDestPair]ccipocr3.SeqNumRange) map[SourceDestPair][]uint64 { +func SeqNumberRangeToSlice(seqRanges map[SourceDestPair]ccipocr3.SeqNumRange) map[SourceDestPair][]uint64 { flatten := make(map[SourceDestPair][]uint64) for srcDst, seqRange := range seqRanges { diff --git a/deployment/ccip/changeset/test_environment.go b/deployment/ccip/changeset/test_environment.go new file mode 100644 index 00000000000..0efa44d108c --- /dev/null +++ b/deployment/ccip/changeset/test_environment.go @@ -0,0 +1,439 @@ +package changeset + +import ( + "context" + "fmt" + "math/big" + "os" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink-ccip/pluginconfig" + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job" + "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink/deployment" + commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" + commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" + "github.com/smartcontractkit/chainlink/deployment/environment/memory" +) + +type EnvType string + +const ( + Memory EnvType = "in-memory" + Docker EnvType = "docker" + ENVTESTTYPE = "CCIP_V16_TEST_ENV" +) + +type TestConfigs struct { + Type EnvType // set by env var CCIP_V16_TEST_ENV, defaults to Memory + CreateJob bool + CreateJobAndContracts bool + Chains int // only used in memory mode, for docker mode, this is determined by the integration-test config toml input + NumOfUsersPerChain int // only used in memory mode, for docker mode, this is determined by the integration-test config toml input + Nodes int // only used in memory mode, for docker mode, this is determined by the integration-test config toml input + Bootstraps int // only used in memory mode, for docker mode, this is determined by the integration-test config toml input + IsUSDC bool + IsUSDCAttestationMissing bool + IsMultiCall3 bool + OCRConfigOverride func(CCIPOCRParams) CCIPOCRParams + RMNEnabled bool + NumOfRMNNodes int + LinkPrice *big.Int + WethPrice *big.Int +} + +func (tc *TestConfigs) Validate() error { + if tc.Chains < 2 { + return fmt.Errorf("chains must be at least 2") + } + if tc.Nodes < 4 { + return fmt.Errorf("nodes must be at least 4") + } + if tc.Bootstraps < 1 { + return fmt.Errorf("bootstraps must be at least 1") + } + if tc.Type == Memory && tc.RMNEnabled { + return fmt.Errorf("cannot run RMN tests in memory mode") + } + return nil +} + +func (tc *TestConfigs) MustSetEnvTypeOrDefault(t *testing.T) { + envType := os.Getenv(ENVTESTTYPE) + if envType == "" || envType == string(Memory) { + tc.Type = Memory + } else if envType == string(Docker) { + tc.Type = Docker + } else { + t.Fatalf("env var CCIP_V16_TEST_ENV must be either %s or %s, defaults to %s if unset, got: %s", Memory, Docker, Memory, envType) + } +} + +func DefaultTestConfigs() *TestConfigs { + return &TestConfigs{ + Chains: 2, + NumOfUsersPerChain: 1, + Nodes: 4, + Bootstraps: 1, + LinkPrice: MockLinkPrice, + WethPrice: MockWethPrice, + CreateJobAndContracts: true, + } +} + +type TestOps func(testCfg *TestConfigs) + +func WithMultiCall3() TestOps { + return func(testCfg *TestConfigs) { + testCfg.IsMultiCall3 = true + } +} + +func WithJobsOnly() TestOps { + return func(testCfg *TestConfigs) { + testCfg.CreateJobAndContracts = false + testCfg.CreateJob = true + } +} + +func WithNoJobsAndContracts() TestOps { + return func(testCfg *TestConfigs) { + testCfg.CreateJobAndContracts = false + testCfg.CreateJob = false + } +} + +func WithRMNEnabled(numOfNode int) TestOps { + return func(testCfg *TestConfigs) { + testCfg.RMNEnabled = true + testCfg.NumOfRMNNodes = numOfNode + } +} + +func WithOCRConfigOverride(override func(CCIPOCRParams) CCIPOCRParams) TestOps { + return func(testCfg *TestConfigs) { + testCfg.OCRConfigOverride = override + } +} + +func WithUSDCAttestationMissing() TestOps { + return func(testCfg *TestConfigs) { + testCfg.IsUSDCAttestationMissing = true + } +} + +func WithUSDC() TestOps { + return func(testCfg *TestConfigs) { + testCfg.IsUSDC = true + } +} + +func WithChains(numChains int) TestOps { + return func(testCfg *TestConfigs) { + testCfg.Chains = numChains + } +} + +func WithUsersPerChain(numUsers int) TestOps { + return func(testCfg *TestConfigs) { + testCfg.NumOfUsersPerChain = numUsers + } +} + +func WithNodes(numNodes int) TestOps { + return func(testCfg *TestConfigs) { + testCfg.Nodes = numNodes + } +} + +func WithBootstraps(numBootstraps int) TestOps { + return func(testCfg *TestConfigs) { + testCfg.Bootstraps = numBootstraps + } +} + +type TestEnvironment interface { + SetupJobs(t *testing.T) + StartNodes(t *testing.T, tc *TestConfigs, crConfig deployment.CapabilityRegistryConfig) + StartChains(t *testing.T, tc *TestConfigs) + DeployedEnvironment() DeployedEnv + MockUSDCAttestationServer(t *testing.T, isUSDCAttestationMissing bool) string +} + +type DeployedEnv struct { + Env deployment.Environment + HomeChainSel uint64 + FeedChainSel uint64 + ReplayBlocks map[uint64]uint64 + Users map[uint64][]*bind.TransactOpts +} + +func (d *DeployedEnv) SetupJobs(t *testing.T) { + ctx := testcontext.Get(t) + out, err := CCIPCapabilityJobspec(d.Env, struct{}{}) + require.NoError(t, err) + for nodeID, jobs := range out.JobSpecs { + for _, job := range jobs { + // Note these auto-accept + _, err := d.Env.Offchain.ProposeJob(ctx, + &jobv1.ProposeJobRequest{ + NodeId: nodeID, + Spec: job, + }) + require.NoError(t, err) + } + } + // Wait for plugins to register filters? + // TODO: Investigate how to avoid. + time.Sleep(30 * time.Second) + ReplayLogs(t, d.Env.Offchain, d.ReplayBlocks) +} + +type MemoryEnvironment struct { + DeployedEnv + chains map[uint64]deployment.Chain +} + +func (m *MemoryEnvironment) DeployedEnvironment() DeployedEnv { + return m.DeployedEnv +} + +func (m *MemoryEnvironment) StartChains(t *testing.T, tc *TestConfigs) { + ctx := testcontext.Get(t) + chains, users := memory.NewMemoryChains(t, tc.Chains, tc.NumOfUsersPerChain) + m.chains = chains + homeChainSel, feedSel := allocateCCIPChainSelectors(chains) + replayBlocks, err := LatestBlocksByChain(ctx, chains) + require.NoError(t, err) + m.DeployedEnv = DeployedEnv{ + Env: deployment.Environment{ + Chains: m.chains, + }, + HomeChainSel: homeChainSel, + FeedChainSel: feedSel, + ReplayBlocks: replayBlocks, + Users: users, + } +} + +func (m *MemoryEnvironment) StartNodes(t *testing.T, tc *TestConfigs, crConfig deployment.CapabilityRegistryConfig) { + require.NotNil(t, m.chains, "start chains first, chains are empty") + require.NotNil(t, m.DeployedEnv, "start chains and initiate deployed env first before starting nodes") + nodes := memory.NewNodes(t, zapcore.InfoLevel, m.chains, tc.Nodes, tc.Bootstraps, crConfig) + ctx := testcontext.Get(t) + lggr := logger.Test(t) + for _, node := range nodes { + require.NoError(t, node.App.Start(ctx)) + t.Cleanup(func() { + require.NoError(t, node.App.Stop()) + }) + } + m.DeployedEnv.Env = memory.NewMemoryEnvironmentFromChainsNodes(func() context.Context { return ctx }, lggr, m.chains, nodes) +} + +func (m *MemoryEnvironment) MockUSDCAttestationServer(t *testing.T, isUSDCAttestationMissing bool) string { + server := mockAttestationResponse(isUSDCAttestationMissing) + endpoint := server.URL + t.Cleanup(func() { + server.Close() + }) + return endpoint +} + +// NewMemoryEnvironment creates an in-memory environment based on the testconfig requested +func NewMemoryEnvironment(t *testing.T, opts ...TestOps) DeployedEnv { + testCfg := DefaultTestConfigs() + for _, opt := range opts { + opt(testCfg) + } + require.NoError(t, testCfg.Validate(), "invalid test config") + env := &MemoryEnvironment{} + if testCfg.CreateJobAndContracts { + return NewEnvironmentWithJobsAndContracts(t, testCfg, env) + } + if testCfg.CreateJob { + return NewEnvironmentWithJobs(t, testCfg, env) + } + return NewEnvironment(t, testCfg, env) +} + +func NewEnvironment(t *testing.T, tc *TestConfigs, tEnv TestEnvironment) DeployedEnv { + lggr := logger.Test(t) + tEnv.StartChains(t, tc) + dEnv := tEnv.DeployedEnvironment() + require.NotEmpty(t, dEnv.FeedChainSel) + require.NotEmpty(t, dEnv.HomeChainSel) + require.NotEmpty(t, dEnv.Env.Chains) + ab := deployment.NewMemoryAddressBook() + crConfig := DeployTestContracts(t, lggr, ab, dEnv.HomeChainSel, dEnv.FeedChainSel, dEnv.Env.Chains, tc.LinkPrice, tc.WethPrice) + tEnv.StartNodes(t, tc, crConfig) + dEnv = tEnv.DeployedEnvironment() + envNodes, err := deployment.NodeInfo(dEnv.Env.NodeIDs, dEnv.Env.Offchain) + require.NoError(t, err) + dEnv.Env.ExistingAddresses = ab + _, err = deployHomeChain(lggr, dEnv.Env, dEnv.Env.ExistingAddresses, dEnv.Env.Chains[dEnv.HomeChainSel], + NewTestRMNStaticConfig(), + NewTestRMNDynamicConfig(), + NewTestNodeOperator(dEnv.Env.Chains[dEnv.HomeChainSel].DeployerKey.From), + map[string][][32]byte{ + "NodeOperator": envNodes.NonBootstraps().PeerIDs(), + }, + ) + require.NoError(t, err) + + return dEnv +} + +func NewEnvironmentWithJobsAndContracts(t *testing.T, tc *TestConfigs, tEnv TestEnvironment) DeployedEnv { + var err error + e := NewEnvironment(t, tc, tEnv) + allChains := e.Env.AllChainSelectors() + mcmsCfg := make(map[uint64]commontypes.MCMSWithTimelockConfig) + + for _, c := range e.Env.AllChainSelectors() { + mcmsCfg[c] = proposalutils.SingleGroupTimelockConfig(t) + } + var ( + usdcChains []uint64 + isMulticall3 bool + ) + if tc != nil { + if tc.IsUSDC { + usdcChains = allChains + } + isMulticall3 = tc.IsMultiCall3 + } + // Need to deploy prerequisites first so that we can form the USDC config + // no proposals to be made, timelock can be passed as nil here + e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, nil, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(commonchangeset.DeployLinkToken), + Config: allChains, + }, + { + Changeset: commonchangeset.WrapChangeSet(DeployPrerequisites), + Config: DeployPrerequisiteConfig{ + ChainSelectors: allChains, + Opts: []PrerequisiteOpt{ + WithUSDCChains(usdcChains), + WithMulticall3(isMulticall3), + }, + }, + }, + { + Changeset: commonchangeset.WrapChangeSet(commonchangeset.DeployMCMSWithTimelock), + Config: mcmsCfg, + }, + { + Changeset: commonchangeset.WrapChangeSet(DeployChainContracts), + Config: DeployChainContractsConfig{ + ChainSelectors: allChains, + HomeChainSelector: e.HomeChainSel, + }, + }, + }) + require.NoError(t, err) + + state, err := LoadOnchainState(e.Env) + require.NoError(t, err) + // Assert USDC set up as expected. + for _, chain := range usdcChains { + require.NotNil(t, state.Chains[chain].MockUSDCTokenMessenger) + require.NotNil(t, state.Chains[chain].MockUSDCTransmitter) + require.NotNil(t, state.Chains[chain].USDCTokenPool) + } + // Assert link present + require.NotNil(t, state.Chains[e.FeedChainSel].LinkToken) + require.NotNil(t, state.Chains[e.FeedChainSel].Weth9) + + tokenConfig := NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) + var tokenDataProviders []pluginconfig.TokenDataObserverConfig + if len(usdcChains) > 0 { + endpoint := tEnv.MockUSDCAttestationServer(t, tc.IsUSDCAttestationMissing) + cctpContracts := make(map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig) + for _, usdcChain := range usdcChains { + cctpContracts[cciptypes.ChainSelector(usdcChain)] = pluginconfig.USDCCCTPTokenConfig{ + SourcePoolAddress: state.Chains[usdcChain].USDCTokenPool.Address().String(), + SourceMessageTransmitterAddr: state.Chains[usdcChain].MockUSDCTransmitter.Address().String(), + } + } + tokenDataProviders = append(tokenDataProviders, pluginconfig.TokenDataObserverConfig{ + Type: pluginconfig.USDCCCTPHandlerType, + Version: "1.0", + USDCCCTPObserverConfig: &pluginconfig.USDCCCTPObserverConfig{ + Tokens: cctpContracts, + AttestationAPI: endpoint, + AttestationAPITimeout: commonconfig.MustNewDuration(time.Second), + AttestationAPIInterval: commonconfig.MustNewDuration(500 * time.Millisecond), + }}) + } + // Build the per chain config. + chainConfigs := make(map[uint64]CCIPOCRParams) + timelockContractsPerChain := make(map[uint64]*proposalutils.TimelockExecutionContracts) + for _, chain := range allChains { + timelockContractsPerChain[chain] = &proposalutils.TimelockExecutionContracts{ + Timelock: state.Chains[chain].Timelock, + CallProxy: state.Chains[chain].CallProxy, + } + tokenInfo := tokenConfig.GetTokenInfo(e.Env.Logger, state.Chains[chain].LinkToken, state.Chains[chain].Weth9) + ocrParams := DefaultOCRParams(e.FeedChainSel, tokenInfo, tokenDataProviders) + if tc.OCRConfigOverride != nil { + ocrParams = tc.OCRConfigOverride(ocrParams) + } + chainConfigs[chain] = ocrParams + } + // Deploy second set of changesets to deploy and configure the CCIP contracts. + e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, timelockContractsPerChain, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(ConfigureNewChains), + Config: NewChainsConfig{ + HomeChainSel: e.HomeChainSel, + FeedChainSel: e.FeedChainSel, + ChainConfigByChain: chainConfigs, + }, + }, + { + Changeset: commonchangeset.WrapChangeSet(CCIPCapabilityJobspec), + }, + }) + require.NoError(t, err) + + ReplayLogs(t, e.Env.Offchain, e.ReplayBlocks) + + state, err = LoadOnchainState(e.Env) + require.NoError(t, err) + require.NotNil(t, state.Chains[e.HomeChainSel].CapabilityRegistry) + require.NotNil(t, state.Chains[e.HomeChainSel].CCIPHome) + require.NotNil(t, state.Chains[e.HomeChainSel].RMNHome) + for _, chain := range allChains { + require.NotNil(t, state.Chains[chain].LinkToken) + require.NotNil(t, state.Chains[chain].Weth9) + require.NotNil(t, state.Chains[chain].TokenAdminRegistry) + require.NotNil(t, state.Chains[chain].RegistryModule) + require.NotNil(t, state.Chains[chain].Router) + require.NotNil(t, state.Chains[chain].RMNRemote) + require.NotNil(t, state.Chains[chain].TestRouter) + require.NotNil(t, state.Chains[chain].NonceManager) + require.NotNil(t, state.Chains[chain].FeeQuoter) + require.NotNil(t, state.Chains[chain].OffRamp) + require.NotNil(t, state.Chains[chain].OnRamp) + } + return e +} + +// NewEnvironmentWithJobs creates a new CCIP environment +// with capreg, fee tokens, feeds, nodes and jobs set up. +func NewEnvironmentWithJobs(t *testing.T, tc *TestConfigs, tEnv TestEnvironment) DeployedEnv { + e := NewEnvironment(t, tc, tEnv) + e.SetupJobs(t) + return e +} diff --git a/deployment/ccip/changeset/test_helpers.go b/deployment/ccip/changeset/test_helpers.go index 49edb275526..75801d99cff 100644 --- a/deployment/ccip/changeset/test_helpers.go +++ b/deployment/ccip/changeset/test_helpers.go @@ -13,29 +13,19 @@ import ( "golang.org/x/sync/errgroup" - mapset "github.com/deckarep/golang-set/v2" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/pkg/errors" - "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" - "github.com/smartcontractkit/chainlink-ccip/pluginconfig" - commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" - - commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" - commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" - "go.uber.org/multierr" - "go.uber.org/zap/zapcore" - chainsel "github.com/smartcontractkit/chain-selectors" + "go.uber.org/multierr" - jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink-ccip/pkg/reader" @@ -89,35 +79,6 @@ func Context(tb testing.TB) context.Context { return ctx } -type DeployedEnv struct { - Env deployment.Environment - HomeChainSel uint64 - FeedChainSel uint64 - ReplayBlocks map[uint64]uint64 - Users map[uint64][]*bind.TransactOpts -} - -func (e *DeployedEnv) SetupJobs(t *testing.T) { - ctx := testcontext.Get(t) - out, err := CCIPCapabilityJobspec(e.Env, struct{}{}) - require.NoError(t, err) - for nodeID, jobs := range out.JobSpecs { - for _, job := range jobs { - // Note these auto-accept - _, err := e.Env.Offchain.ProposeJob(ctx, - &jobv1.ProposeJobRequest{ - NodeId: nodeID, - Spec: job, - }) - require.NoError(t, err) - } - } - // Wait for plugins to register filters? - // TODO: Investigate how to avoid. - time.Sleep(30 * time.Second) - ReplayLogs(t, e.Env.Offchain, e.ReplayBlocks) -} - func ReplayLogs(t *testing.T, oc deployment.OffchainClient, replayBlocks map[uint64]uint64) { switch oc := oc.(type) { case *memory.JobClient: @@ -185,62 +146,6 @@ func allocateCCIPChainSelectors(chains map[uint64]deployment.Chain) (homeChainSe return chainSels[HomeChainIndex], chainSels[FeedChainIndex] } -// NewMemoryEnvironment creates a new CCIP environment -// with capreg, fee tokens, feeds and nodes set up. -func NewMemoryEnvironment( - t *testing.T, - lggr logger.Logger, - config memory.MemoryEnvironmentConfig, - linkPrice *big.Int, - wethPrice *big.Int) DeployedEnv { - require.GreaterOrEqual(t, config.Chains, 2, "numChains must be at least 2 for home and feed chains") - require.GreaterOrEqual(t, config.Nodes, 4, "numNodes must be at least 4") - ctx := testcontext.Get(t) - chains, users := memory.NewMemoryChains(t, config.Chains, config.NumOfUsersPerChain) - homeChainSel, feedSel := allocateCCIPChainSelectors(chains) - replayBlocks, err := LatestBlocksByChain(ctx, chains) - require.NoError(t, err) - - ab := deployment.NewMemoryAddressBook() - crConfig := DeployTestContracts(t, lggr, ab, homeChainSel, feedSel, chains, linkPrice, wethPrice) - nodes := memory.NewNodes(t, zapcore.InfoLevel, chains, config.Nodes, config.Bootstraps, crConfig) - for _, node := range nodes { - require.NoError(t, node.App.Start(ctx)) - t.Cleanup(func() { - require.NoError(t, node.App.Stop()) - }) - } - e := memory.NewMemoryEnvironmentFromChainsNodes(func() context.Context { return ctx }, lggr, chains, nodes) - envNodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) - require.NoError(t, err) - e.ExistingAddresses = ab - _, err = deployHomeChain(lggr, e, e.ExistingAddresses, chains[homeChainSel], - NewTestRMNStaticConfig(), - NewTestRMNDynamicConfig(), - NewTestNodeOperator(chains[homeChainSel].DeployerKey.From), - map[string][][32]byte{ - "NodeOperator": envNodes.NonBootstraps().PeerIDs(), - }, - ) - require.NoError(t, err) - - return DeployedEnv{ - Env: e, - HomeChainSel: homeChainSel, - FeedChainSel: feedSel, - ReplayBlocks: replayBlocks, - Users: users, - } -} - -// NewMemoryEnvironmentWithJobs creates a new CCIP environment -// with capreg, fee tokens, feeds, nodes and jobs set up. -func NewMemoryEnvironmentWithJobs(t *testing.T, lggr logger.Logger, config memory.MemoryEnvironmentConfig) DeployedEnv { - e := NewMemoryEnvironment(t, lggr, config, MockLinkPrice, MockWethPrice) - e.SetupJobs(t) - return e -} - // mockAttestationResponse mocks the USDC attestation server, it returns random Attestation. // We don't need to return exactly the same attestation, because our Mocked USDC contract doesn't rely on any specific // value, but instead of that it just checks if the attestation is present. Therefore, it makes the test a bit simpler @@ -265,150 +170,6 @@ func mockAttestationResponse(isFaulty bool) *httptest.Server { return server } -type TestConfigs struct { - IsUSDC bool - IsUSDCAttestationMissing bool - IsMultiCall3 bool - OCRConfigOverride func(CCIPOCRParams) CCIPOCRParams -} - -func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, config memory.MemoryEnvironmentConfig, tCfg *TestConfigs) DeployedEnv { - var err error - e := NewMemoryEnvironment(t, lggr, config, MockLinkPrice, MockWethPrice) - allChains := e.Env.AllChainSelectors() - mcmsCfg := make(map[uint64]commontypes.MCMSWithTimelockConfig) - for _, c := range e.Env.AllChainSelectors() { - mcmsCfg[c] = commontypes.MCMSWithTimelockConfig{ - Canceller: commonchangeset.SingleGroupMCMS(t), - Bypasser: commonchangeset.SingleGroupMCMS(t), - Proposer: commonchangeset.SingleGroupMCMS(t), - TimelockExecutors: e.Env.AllDeployerKeys(), - TimelockMinDelay: big.NewInt(0), - } - } - var ( - usdcChains []uint64 - isMulticall3 bool - ) - if tCfg != nil { - if tCfg.IsUSDC { - usdcChains = allChains - } - isMulticall3 = tCfg.IsMultiCall3 - } - // Need to deploy prerequisites first so that we can form the USDC config - // no proposals to be made, timelock can be passed as nil here - e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, nil, []commonchangeset.ChangesetApplication{ - { - Changeset: commonchangeset.WrapChangeSet(commonchangeset.DeployLinkToken), - Config: allChains, - }, - { - Changeset: commonchangeset.WrapChangeSet(DeployPrerequisites), - Config: DeployPrerequisiteConfig{ - ChainSelectors: allChains, - Opts: []PrerequisiteOpt{ - WithUSDCChains(usdcChains), - WithMulticall3(isMulticall3), - }, - }, - }, - { - Changeset: commonchangeset.WrapChangeSet(commonchangeset.DeployMCMSWithTimelock), - Config: mcmsCfg, - }, - { - Changeset: commonchangeset.WrapChangeSet(DeployChainContracts), - Config: DeployChainContractsConfig{ - ChainSelectors: allChains, - HomeChainSelector: e.HomeChainSel, - }, - }, - }) - require.NoError(t, err) - - state, err := LoadOnchainState(e.Env) - require.NoError(t, err) - // Assert USDC set up as expected. - for _, chain := range usdcChains { - require.NotNil(t, state.Chains[chain].MockUSDCTokenMessenger) - require.NotNil(t, state.Chains[chain].MockUSDCTransmitter) - require.NotNil(t, state.Chains[chain].USDCTokenPool) - } - // Assert link present - require.NotNil(t, state.Chains[e.FeedChainSel].LinkToken) - require.NotNil(t, state.Chains[e.FeedChainSel].Weth9) - - tokenConfig := NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) - var tokenDataProviders []pluginconfig.TokenDataObserverConfig - if len(usdcChains) > 0 { - server := mockAttestationResponse(tCfg.IsUSDCAttestationMissing) - endpoint := server.URL - t.Cleanup(func() { - server.Close() - }) - cctpContracts := make(map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig) - for _, usdcChain := range usdcChains { - cctpContracts[cciptypes.ChainSelector(usdcChain)] = pluginconfig.USDCCCTPTokenConfig{ - SourcePoolAddress: state.Chains[usdcChain].USDCTokenPool.Address().String(), - SourceMessageTransmitterAddr: state.Chains[usdcChain].MockUSDCTransmitter.Address().String(), - } - } - tokenDataProviders = append(tokenDataProviders, pluginconfig.TokenDataObserverConfig{ - Type: pluginconfig.USDCCCTPHandlerType, - Version: "1.0", - USDCCCTPObserverConfig: &pluginconfig.USDCCCTPObserverConfig{ - Tokens: cctpContracts, - AttestationAPI: endpoint, - AttestationAPITimeout: commonconfig.MustNewDuration(time.Second), - AttestationAPIInterval: commonconfig.MustNewDuration(500 * time.Millisecond), - }}) - } - // Build the per chain config. - chainConfigs := make(map[uint64]CCIPOCRParams) - timelocksPerChain := make(map[uint64]*gethwrappers.RBACTimelock) - for _, chain := range allChains { - timelocksPerChain[chain] = state.Chains[chain].Timelock - tokenInfo := tokenConfig.GetTokenInfo(e.Env.Logger, state.Chains[chain].LinkToken, state.Chains[chain].Weth9) - chainConfigs[chain] = DefaultOCRParams(e.FeedChainSel, tokenInfo, tokenDataProviders) - } - // Deploy second set of changesets to deploy and configure the CCIP contracts. - e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, timelocksPerChain, []commonchangeset.ChangesetApplication{ - { - Changeset: commonchangeset.WrapChangeSet(ConfigureNewChains), - Config: NewChainsConfig{ - HomeChainSel: e.HomeChainSel, - FeedChainSel: e.FeedChainSel, - ChainConfigByChain: chainConfigs, - }, - }, - { - Changeset: commonchangeset.WrapChangeSet(CCIPCapabilityJobspec), - }, - }) - require.NoError(t, err) - - state, err = LoadOnchainState(e.Env) - require.NoError(t, err) - require.NotNil(t, state.Chains[e.HomeChainSel].CapabilityRegistry) - require.NotNil(t, state.Chains[e.HomeChainSel].CCIPHome) - require.NotNil(t, state.Chains[e.HomeChainSel].RMNHome) - for _, chain := range allChains { - require.NotNil(t, state.Chains[chain].LinkToken) - require.NotNil(t, state.Chains[chain].Weth9) - require.NotNil(t, state.Chains[chain].TokenAdminRegistry) - require.NotNil(t, state.Chains[chain].RegistryModule) - require.NotNil(t, state.Chains[chain].Router) - require.NotNil(t, state.Chains[chain].RMNRemote) - require.NotNil(t, state.Chains[chain].TestRouter) - require.NotNil(t, state.Chains[chain].NonceManager) - require.NotNil(t, state.Chains[chain].FeeQuoter) - require.NotNil(t, state.Chains[chain].OffRamp) - require.NotNil(t, state.Chains[chain].OnRamp) - } - return e -} - func CCIPSendRequest( e deployment.Environment, state CCIPOnChainState, @@ -805,35 +566,6 @@ func ConfirmRequestOnSourceAndDest(t *testing.T, env deployment.Environment, sta return nil } -// TODO: Remove this to replace with ApplyChangeset -func ProcessChangeset(t *testing.T, e deployment.Environment, c deployment.ChangesetOutput) { - - // TODO: Add support for jobspecs as well - - // sign and execute all proposals provided - if len(c.Proposals) != 0 { - state, err := LoadOnchainState(e) - require.NoError(t, err) - for _, prop := range c.Proposals { - chains := mapset.NewSet[uint64]() - for _, op := range prop.Transactions { - chains.Add(uint64(op.ChainIdentifier)) - } - - signed := commonchangeset.SignProposal(t, e, &prop) - for _, sel := range chains.ToSlice() { - commonchangeset.ExecuteProposal(t, e, signed, state.Chains[sel].Timelock, sel) - } - } - } - - // merge address books - if c.AddressBook != nil { - err := e.ExistingAddresses.Merge(c.AddressBook) - require.NoError(t, err) - } -} - func DeployTransferableToken( lggr logger.Logger, chains map[uint64]deployment.Chain, diff --git a/deployment/ccip/changeset/view_test.go b/deployment/ccip/changeset/view_test.go index 934b937f7b5..35193979849 100644 --- a/deployment/ccip/changeset/view_test.go +++ b/deployment/ccip/changeset/view_test.go @@ -4,19 +4,11 @@ import ( "testing" "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink/deployment/environment/memory" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) func TestSmokeView(t *testing.T) { - lggr := logger.TestLogger(t) - tenv := NewMemoryEnvironmentWithJobsAndContracts(t, lggr, memory.MemoryEnvironmentConfig{ - Chains: 3, - Nodes: 4, - Bootstraps: 1, - NumOfUsersPerChain: 1, - }, nil) + t.Parallel() + tenv := NewMemoryEnvironment(t, WithChains(3)) _, err := ViewCCIP(tenv.Env) require.NoError(t, err) } diff --git a/deployment/ccip/view/v1_2/price_registry.go b/deployment/ccip/view/v1_2/price_registry.go new file mode 100644 index 00000000000..ee0f1067b6c --- /dev/null +++ b/deployment/ccip/view/v1_2/price_registry.go @@ -0,0 +1,45 @@ +package v1_2 + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink/deployment/common/view/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" +) + +type PriceRegistryView struct { + types.ContractMetaData + FeeTokens []common.Address `json:"feeTokens"` + StalenessThreshold string `json:"stalenessThreshold"` + Updaters []common.Address `json:"updaters"` +} + +func GeneratePriceRegistryView(pr *price_registry_1_2_0.PriceRegistry) (PriceRegistryView, error) { + if pr == nil { + return PriceRegistryView{}, fmt.Errorf("cannot generate view for nil PriceRegistry") + } + meta, err := types.NewContractMetaData(pr, pr.Address()) + if err != nil { + return PriceRegistryView{}, fmt.Errorf("failed to generate contract metadata for PriceRegistry %s: %w", pr.Address(), err) + } + ft, err := pr.GetFeeTokens(nil) + if err != nil { + return PriceRegistryView{}, fmt.Errorf("failed to get fee tokens %s: %w", pr.Address(), err) + } + st, err := pr.GetStalenessThreshold(nil) + if err != nil { + return PriceRegistryView{}, fmt.Errorf("failed to get staleness threshold %s: %w", pr.Address(), err) + } + updaters, err := pr.GetPriceUpdaters(nil) + if err != nil { + return PriceRegistryView{}, fmt.Errorf("failed to get price updaters %s: %w", pr.Address(), err) + } + return PriceRegistryView{ + ContractMetaData: meta, + FeeTokens: ft, + StalenessThreshold: st.String(), + Updaters: updaters, + }, nil +} diff --git a/deployment/ccip/view/v1_2/price_registry_test.go b/deployment/ccip/view/v1_2/price_registry_test.go new file mode 100644 index 00000000000..cbcdbe253ce --- /dev/null +++ b/deployment/ccip/view/v1_2/price_registry_test.go @@ -0,0 +1,38 @@ +package v1_2 + +import ( + "encoding/json" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/environment/memory" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry_1_2_0" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestGeneratePriceRegistryView(t *testing.T) { + e := memory.NewMemoryEnvironment(t, logger.TestLogger(t), zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ + Chains: 1, + }) + chain := e.Chains[e.AllChainSelectors()[0]] + f1, f2 := common.HexToAddress("0x1"), common.HexToAddress("0x2") + _, tx, c, err := price_registry_1_2_0.DeployPriceRegistry( + chain.DeployerKey, chain.Client, []common.Address{chain.DeployerKey.From}, []common.Address{f1, f2}, uint32(10)) + _, err = deployment.ConfirmIfNoError(chain, tx, err) + require.NoError(t, err) + + v, err := GeneratePriceRegistryView(c) + require.NoError(t, err) + assert.Equal(t, v.Owner, chain.DeployerKey.From) + assert.Equal(t, v.TypeAndVersion, "PriceRegistry 1.2.0") + assert.Equal(t, v.FeeTokens, []common.Address{f1, f2}) + assert.Equal(t, v.StalenessThreshold, "10") + assert.Equal(t, v.Updaters, []common.Address{chain.DeployerKey.From}) + _, err = json.MarshalIndent(v, "", " ") + require.NoError(t, err) +} diff --git a/deployment/ccip/view/v1_5/offramp.go b/deployment/ccip/view/v1_5/offramp.go new file mode 100644 index 00000000000..95e40d9da27 --- /dev/null +++ b/deployment/ccip/view/v1_5/offramp.go @@ -0,0 +1,40 @@ +package v1_5 + +import ( + "fmt" + + "github.com/smartcontractkit/chainlink/deployment/common/view/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" +) + +type OffRampView struct { + types.ContractMetaData + StaticConfig evm_2_evm_offramp.EVM2EVMOffRampStaticConfig `json:"staticConfig"` + DynamicConfig evm_2_evm_offramp.EVM2EVMOffRampDynamicConfig `json:"dynamicConfig"` +} + +func GenerateOffRampView(r *evm_2_evm_offramp.EVM2EVMOffRamp) (OffRampView, error) { + if r == nil { + return OffRampView{}, fmt.Errorf("cannot generate view for nil OffRamp") + } + meta, err := types.NewContractMetaData(r, r.Address()) + if err != nil { + return OffRampView{}, fmt.Errorf("failed to generate contract metadata for OffRamp %s: %w", r.Address(), err) + } + staticConfig, err := r.GetStaticConfig(nil) + if err != nil { + return OffRampView{}, fmt.Errorf("failed to get static config for OffRamp %s: %w", r.Address(), err) + } + dynamicConfig, err := r.GetDynamicConfig(nil) + if err != nil { + return OffRampView{}, fmt.Errorf("failed to get dynamic config for OffRamp %s: %w", r.Address(), err) + } + + // TODO: If needed, we can filter logs to get the OCR config. + // May not be required for the legacy contracts. + return OffRampView{ + ContractMetaData: meta, + StaticConfig: staticConfig, + DynamicConfig: dynamicConfig, + }, nil +} diff --git a/deployment/ccip/view/v1_5/offramp_test.go b/deployment/ccip/view/v1_5/offramp_test.go new file mode 100644 index 00000000000..d6539fe2ba5 --- /dev/null +++ b/deployment/ccip/view/v1_5/offramp_test.go @@ -0,0 +1,60 @@ +package v1_5 + +import ( + "encoding/json" + "testing" + + "github.com/ethereum/go-ethereum/common" + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "math/big" + + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/environment/memory" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestOffRampView(t *testing.T) { + e := memory.NewMemoryEnvironment(t, logger.TestLogger(t), zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ + Chains: 1, + }) + chain := e.Chains[e.AllChainSelectors()[0]] + _, tx, c, err := commit_store.DeployCommitStore( + chain.DeployerKey, chain.Client, commit_store.CommitStoreStaticConfig{ + ChainSelector: chainsel.TEST_90000002.Selector, + SourceChainSelector: chainsel.TEST_90000001.Selector, + OnRamp: common.HexToAddress("0x4"), + RmnProxy: common.HexToAddress("0x1"), + }) + _, err = deployment.ConfirmIfNoError(chain, tx, err) + require.NoError(t, err) + sc := evm_2_evm_offramp.EVM2EVMOffRampStaticConfig{ + ChainSelector: chainsel.TEST_90000002.Selector, + SourceChainSelector: chainsel.TEST_90000001.Selector, + RmnProxy: common.HexToAddress("0x1"), + CommitStore: c.Address(), + TokenAdminRegistry: common.HexToAddress("0x3"), + OnRamp: common.HexToAddress("0x4"), + } + rl := evm_2_evm_offramp.RateLimiterConfig{ + IsEnabled: true, + Capacity: big.NewInt(100), + Rate: big.NewInt(10), + } + _, tx, c2, err := evm_2_evm_offramp.DeployEVM2EVMOffRamp( + chain.DeployerKey, chain.Client, sc, rl) + _, err = deployment.ConfirmIfNoError(chain, tx, err) + require.NoError(t, err) + + v, err := GenerateOffRampView(c2) + require.NoError(t, err) + assert.Equal(t, v.StaticConfig, sc) + assert.Equal(t, v.TypeAndVersion, "EVM2EVMOffRamp 1.5.0") + _, err = json.MarshalIndent(v, "", " ") + require.NoError(t, err) +} diff --git a/deployment/ccip/view/v1_5/onramp.go b/deployment/ccip/view/v1_5/onramp.go new file mode 100644 index 00000000000..d679f6c14c0 --- /dev/null +++ b/deployment/ccip/view/v1_5/onramp.go @@ -0,0 +1,39 @@ +package v1_5 + +import ( + "fmt" + + "github.com/smartcontractkit/chainlink/deployment/common/view/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" +) + +type OnRampView struct { + types.ContractMetaData + StaticConfig evm_2_evm_onramp.EVM2EVMOnRampStaticConfig `json:"staticConfig"` + DynamicConfig evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig `json:"dynamicConfig"` +} + +func GenerateOnRampView(r *evm_2_evm_onramp.EVM2EVMOnRamp) (OnRampView, error) { + if r == nil { + return OnRampView{}, fmt.Errorf("cannot generate view for nil OnRamp") + } + meta, err := types.NewContractMetaData(r, r.Address()) + if err != nil { + return OnRampView{}, fmt.Errorf("failed to generate contract metadata for OnRamp %s: %w", r.Address(), err) + } + staticConfig, err := r.GetStaticConfig(nil) + if err != nil { + return OnRampView{}, fmt.Errorf("failed to get static config for OnRamp %s: %w", r.Address(), err) + } + dynamicConfig, err := r.GetDynamicConfig(nil) + if err != nil { + return OnRampView{}, fmt.Errorf("failed to get dynamic config for OnRamp %s: %w", r.Address(), err) + } + + // Add billing if needed, maybe not required for legacy contract? + return OnRampView{ + ContractMetaData: meta, + StaticConfig: staticConfig, + DynamicConfig: dynamicConfig, + }, nil +} diff --git a/deployment/ccip/view/v1_5/onramp_test.go b/deployment/ccip/view/v1_5/onramp_test.go new file mode 100644 index 00000000000..4d7ef0225a6 --- /dev/null +++ b/deployment/ccip/view/v1_5/onramp_test.go @@ -0,0 +1,71 @@ +package v1_5 + +import ( + "encoding/json" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/environment/memory" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestOnRampView(t *testing.T) { + e := memory.NewMemoryEnvironment(t, logger.TestLogger(t), zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ + Chains: 1, + }) + chain := e.Chains[e.AllChainSelectors()[0]] + _, tx, c, err := evm_2_evm_onramp.DeployEVM2EVMOnRamp( + chain.DeployerKey, chain.Client, + evm_2_evm_onramp.EVM2EVMOnRampStaticConfig{ + LinkToken: common.HexToAddress("0x1"), + ChainSelector: chain.Selector, + DestChainSelector: 100, + DefaultTxGasLimit: 10, + MaxNopFeesJuels: big.NewInt(10), + PrevOnRamp: common.Address{}, + RmnProxy: common.HexToAddress("0x2"), + TokenAdminRegistry: common.HexToAddress("0x3"), + }, + evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{ + Router: common.HexToAddress("0x4"), + MaxNumberOfTokensPerMsg: 0, + DestGasOverhead: 0, + DestGasPerPayloadByte: 0, + DestDataAvailabilityOverheadGas: 0, + DestGasPerDataAvailabilityByte: 0, + DestDataAvailabilityMultiplierBps: 0, + PriceRegistry: common.HexToAddress("0x5"), + MaxDataBytes: 0, + MaxPerMsgGasLimit: 0, + DefaultTokenFeeUSDCents: 0, + DefaultTokenDestGasOverhead: 0, + EnforceOutOfOrder: false, + }, + evm_2_evm_onramp.RateLimiterConfig{ + IsEnabled: true, + Capacity: big.NewInt(100), + Rate: big.NewInt(10), + }, + []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs{}, + []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs{}, + []evm_2_evm_onramp.EVM2EVMOnRampNopAndWeight{}, + ) + _, err = deployment.ConfirmIfNoError(chain, tx, err) + require.NoError(t, err) + v, err := GenerateOnRampView(c) + require.NoError(t, err) + // Check a few fields. + assert.Equal(t, v.StaticConfig.ChainSelector, chain.Selector) + assert.Equal(t, v.DynamicConfig.Router, common.HexToAddress("0x4")) + assert.Equal(t, v.TypeAndVersion, "EVM2EVMOnRamp 1.5.0") + _, err = json.MarshalIndent(v, "", " ") + require.NoError(t, err) + +} diff --git a/deployment/ccip/view/v1_5/rmn.go b/deployment/ccip/view/v1_5/rmn.go new file mode 100644 index 00000000000..cef55460446 --- /dev/null +++ b/deployment/ccip/view/v1_5/rmn.go @@ -0,0 +1,31 @@ +package v1_5 + +import ( + "fmt" + + "github.com/smartcontractkit/chainlink/deployment/common/view/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_contract" +) + +type RMNView struct { + types.ContractMetaData + ConfigDetails rmn_contract.GetConfigDetails `json:"configDetails"` +} + +func GenerateRMNView(r *rmn_contract.RMNContract) (RMNView, error) { + if r == nil { + return RMNView{}, fmt.Errorf("cannot generate view for nil RMN") + } + meta, err := types.NewContractMetaData(r, r.Address()) + if err != nil { + return RMNView{}, fmt.Errorf("failed to generate contract metadata for RMN: %w", err) + } + config, err := r.GetConfigDetails(nil) + if err != nil { + return RMNView{}, fmt.Errorf("failed to get config details for RMN: %w", err) + } + return RMNView{ + ContractMetaData: meta, + ConfigDetails: config, + }, nil +} diff --git a/deployment/ccip/view/v1_5/rmn_test.go b/deployment/ccip/view/v1_5/rmn_test.go new file mode 100644 index 00000000000..3ec7d7a9cc9 --- /dev/null +++ b/deployment/ccip/view/v1_5/rmn_test.go @@ -0,0 +1,53 @@ +package v1_5 + +import ( + "encoding/json" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink/deployment/environment/memory" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_contract" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestGenerateRMNView(t *testing.T) { + e := memory.NewMemoryEnvironment(t, logger.TestLogger(t), zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ + Chains: 1, + }) + chain := e.Chains[e.AllChainSelectors()[0]] + cfg := rmn_contract.RMNConfig{ + Voters: []rmn_contract.RMNVoter{ + { + BlessVoteAddr: chain.DeployerKey.From, + CurseVoteAddr: common.HexToAddress("0x3"), + BlessWeight: 1, + CurseWeight: 1, + }, + { + BlessVoteAddr: common.HexToAddress("0x1"), + CurseVoteAddr: common.HexToAddress("0x2"), + BlessWeight: 1, + CurseWeight: 1, + }, + }, + BlessWeightThreshold: uint16(2), + CurseWeightThreshold: uint16(1), + } + _, tx, c, err := rmn_contract.DeployRMNContract( + chain.DeployerKey, chain.Client, cfg) + require.NoError(t, err) + _, err = chain.Confirm(tx) + require.NoError(t, err) + v, err := GenerateRMNView(c) + require.NoError(t, err) + assert.Equal(t, v.Owner, chain.DeployerKey.From) + assert.Equal(t, v.TypeAndVersion, "RMN 1.5.0") + assert.Equal(t, v.ConfigDetails.Version, uint32(1)) + assert.Equal(t, v.ConfigDetails.Config, cfg) + _, err = json.MarshalIndent(v, "", " ") + require.NoError(t, err) +} diff --git a/deployment/ccip/view/v1_6/capreg.go b/deployment/ccip/view/v1_6/capreg.go deleted file mode 100644 index 26ec545d98e..00000000000 --- a/deployment/ccip/view/v1_6/capreg.go +++ /dev/null @@ -1,45 +0,0 @@ -package v1_6 - -import ( - "github.com/ethereum/go-ethereum/common" - - "github.com/smartcontractkit/chainlink/deployment/common/view/types" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" -) - -// CapRegView denotes a view of the capabilities registry contract. -// Note that the contract itself is 1.0.0 versioned, but we're releasing it first -// as part of 1.6 for CCIP. -type CapRegView struct { - types.ContractMetaData - Capabilities []CapabilityView `json:"capabilities,omitempty"` -} - -type CapabilityView struct { - LabelledName string `json:"labelledName"` - Version string `json:"version"` - ConfigContract common.Address `json:"configContract"` -} - -func GenerateCapRegView(capReg *capabilities_registry.CapabilitiesRegistry) (CapRegView, error) { - tv, err := types.NewContractMetaData(capReg, capReg.Address()) - if err != nil { - return CapRegView{}, err - } - caps, err := capReg.GetCapabilities(nil) - if err != nil { - return CapRegView{}, err - } - var capViews []CapabilityView - for _, capability := range caps { - capViews = append(capViews, CapabilityView{ - LabelledName: capability.LabelledName, - Version: capability.Version, - ConfigContract: capability.ConfigurationContract, - }) - } - return CapRegView{ - ContractMetaData: tv, - Capabilities: capViews, - }, nil -} diff --git a/deployment/ccip/view/v1_6/ccip_home.go b/deployment/ccip/view/v1_6/ccip_home.go new file mode 100644 index 00000000000..ac1e23179c4 --- /dev/null +++ b/deployment/ccip/view/v1_6/ccip_home.go @@ -0,0 +1,85 @@ +package v1_6 + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink/deployment/common/view/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_home" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" +) + +// https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/ccip/libraries/Internal.sol#L190 +const ( + CommitPluginType = 0 + ExecPluginType = 1 +) + +type DonView struct { + DonID uint32 `json:"donID"` + // TODO: find a way to hexify the bytes here + CommitConfigs ccip_home.GetAllConfigs `json:"commitConfigs"` + ExecConfigs ccip_home.GetAllConfigs `json:"execConfigs"` +} + +type CCIPHomeView struct { + types.ContractMetaData + ChainConfigs []ccip_home.CCIPHomeChainConfigArgs `json:"chainConfigs"` + CapabilityRegistry common.Address `json:"capabilityRegistry"` + Dons []DonView `json:"dons"` +} + +func GenerateCCIPHomeView(cr *capabilities_registry.CapabilitiesRegistry, ch *ccip_home.CCIPHome) (CCIPHomeView, error) { + if ch == nil { + return CCIPHomeView{}, fmt.Errorf("cannot generate view for nil CCIPHome") + } + meta, err := types.NewContractMetaData(ch, ch.Address()) + if err != nil { + return CCIPHomeView{}, fmt.Errorf("failed to generate contract metadata for CCIPHome %s: %w", ch.Address(), err) + } + numChains, err := ch.GetNumChainConfigurations(nil) + if err != nil { + return CCIPHomeView{}, fmt.Errorf("failed to get number of chain configurations for CCIPHome %s: %w", ch.Address(), err) + } + // Pagination shouldn't be required here, but we can add it if needed. + chains, err := ch.GetAllChainConfigs(nil, big.NewInt(0), numChains) + if err != nil { + return CCIPHomeView{}, fmt.Errorf("failed to get all chain configs for CCIPHome %s: %w", ch.Address(), err) + } + crAddr, err := ch.GetCapabilityRegistry(nil) + if err != nil { + return CCIPHomeView{}, fmt.Errorf("failed to get capability registry for CCIPHome %s: %w", ch.Address(), err) + } + if crAddr != cr.Address() { + return CCIPHomeView{}, fmt.Errorf("capability registry address mismatch for CCIPHome %s: %w", ch.Address(), err) + } + dons, err := cr.GetDONs(nil) + if err != nil { + return CCIPHomeView{}, fmt.Errorf("failed to get DONs for CCIPHome %s: %w", ch.Address(), err) + } + // Get every don's configuration. + var dvs []DonView + for _, d := range dons { + commitConfigs, err := ch.GetAllConfigs(nil, d.Id, CommitPluginType) + if err != nil { + return CCIPHomeView{}, fmt.Errorf("failed to get active commit config for CCIPHome %s: %w", ch.Address(), err) + } + execConfigs, err := ch.GetAllConfigs(nil, d.Id, ExecPluginType) + if err != nil { + return CCIPHomeView{}, fmt.Errorf("failed to get active commit config for CCIPHome %s: %w", ch.Address(), err) + } + dvs = append(dvs, DonView{ + DonID: d.Id, + CommitConfigs: commitConfigs, + ExecConfigs: execConfigs, + }) + } + return CCIPHomeView{ + ContractMetaData: meta, + ChainConfigs: chains, + CapabilityRegistry: crAddr, + Dons: dvs, + }, nil +} diff --git a/deployment/ccip/view/v1_6/ccip_home_test.go b/deployment/ccip/view/v1_6/ccip_home_test.go new file mode 100644 index 00000000000..26f6f50aed5 --- /dev/null +++ b/deployment/ccip/view/v1_6/ccip_home_test.go @@ -0,0 +1,40 @@ +package v1_6 + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/environment/memory" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_home" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestCCIPHomeView(t *testing.T) { + e := memory.NewMemoryEnvironment(t, logger.TestLogger(t), zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ + Chains: 1, + }) + chain := e.Chains[e.AllChainSelectors()[0]] + _, tx, cr, err := capabilities_registry.DeployCapabilitiesRegistry( + chain.DeployerKey, chain.Client) + require.NoError(t, err) + _, err = deployment.ConfirmIfNoError(chain, tx, err) + require.NoError(t, err) + + _, tx, ch, err := ccip_home.DeployCCIPHome( + chain.DeployerKey, chain.Client, cr.Address()) + _, err = deployment.ConfirmIfNoError(chain, tx, err) + require.NoError(t, err) + + v, err := GenerateCCIPHomeView(cr, ch) + require.NoError(t, err) + assert.Equal(t, v.TypeAndVersion, "CCIPHome 1.6.0-dev") + + _, err = json.MarshalIndent(v, "", " ") + require.NoError(t, err) +} diff --git a/deployment/ccip/view/view.go b/deployment/ccip/view/view.go index 1cacd58cc2b..77781a8a31a 100644 --- a/deployment/ccip/view/view.go +++ b/deployment/ccip/view/view.go @@ -20,11 +20,14 @@ type ChainView struct { TokenAdminRegistry map[string]v1_5.TokenAdminRegistryView `json:"tokenAdminRegistry,omitempty"` CommitStore map[string]v1_5.CommitStoreView `json:"commitStore,omitempty"` // v1.6 - FeeQuoter map[string]v1_6.FeeQuoterView `json:"feeQuoter,omitempty"` - NonceManager map[string]v1_6.NonceManagerView `json:"nonceManager,omitempty"` - RMN map[string]v1_6.RMNRemoteView `json:"rmn,omitempty"` - OnRamp map[string]v1_6.OnRampView `json:"onRamp,omitempty"` - OffRamp map[string]v1_6.OffRampView `json:"offRamp,omitempty"` + FeeQuoter map[string]v1_6.FeeQuoterView `json:"feeQuoter,omitempty"` + NonceManager map[string]v1_6.NonceManagerView `json:"nonceManager,omitempty"` + RMN map[string]v1_6.RMNRemoteView `json:"rmn,omitempty"` + OnRamp map[string]v1_6.OnRampView `json:"onRamp,omitempty"` + OffRamp map[string]v1_6.OffRampView `json:"offRamp,omitempty"` + // TODO: Perhaps restrict to one CCIPHome/CR? Shouldn't + // be more than one per env. + CCIPHome map[string]v1_6.CCIPHomeView `json:"ccipHome,omitempty"` CapabilityRegistry map[string]common_v1_0.CapabilityRegistryView `json:"capabilityRegistry,omitempty"` MCMSWithTimelock common_v1_0.MCMSWithTimelockView `json:"mcmsWithTimelock,omitempty"` LinkToken common_v1_0.LinkTokenView `json:"linkToken,omitempty"` @@ -47,7 +50,10 @@ func NewChain() ChainView { OnRamp: make(map[string]v1_6.OnRampView), OffRamp: make(map[string]v1_6.OffRampView), CapabilityRegistry: make(map[string]common_v1_0.CapabilityRegistryView), + CCIPHome: make(map[string]v1_6.CCIPHomeView), MCMSWithTimelock: common_v1_0.MCMSWithTimelockView{}, + LinkToken: common_v1_0.LinkTokenView{}, + StaticLinkToken: common_v1_0.StaticLinkTokenView{}, } } diff --git a/deployment/common/changeset/internal/mcms.go b/deployment/common/changeset/internal/mcms.go index 281f43924f4..baa82d77c8f 100644 --- a/deployment/common/changeset/internal/mcms.go +++ b/deployment/common/changeset/internal/mcms.go @@ -55,6 +55,7 @@ type MCMSWithTimelockDeploy struct { Bypasser *deployment.ContractDeploy[*owner_helpers.ManyChainMultiSig] Proposer *deployment.ContractDeploy[*owner_helpers.ManyChainMultiSig] Timelock *deployment.ContractDeploy[*owner_helpers.RBACTimelock] + CallProxy *deployment.ContractDeploy[*owner_helpers.CallProxy] } func DeployMCMSWithTimelockContractsBatch( @@ -106,10 +107,12 @@ func DeployMCMSWithTimelockContracts( // TODO: Could expose this as config? // Or keep this enforced to follow the same pattern? chain.DeployerKey.From, - []common.Address{proposer.Address}, // proposers - config.TimelockExecutors, //executors - []common.Address{canceller.Address}, // cancellers - []common.Address{bypasser.Address}, // bypassers + []common.Address{proposer.Address}, // proposers + // Executors field is empty here because we grant the executor role to the call proxy later + // and the call proxy cannot be deployed before the timelock. + []common.Address{}, + []common.Address{canceller.Address, proposer.Address, bypasser.Address}, // cancellers + []common.Address{bypasser.Address}, // bypassers ) return deployment.ContractDeploy[*owner_helpers.RBACTimelock]{ timelock, cc, tx2, deployment.NewTypeAndVersion(types.RBACTimelock, deployment.Version1_0_0), err2, @@ -119,6 +122,37 @@ func DeployMCMSWithTimelockContracts( lggr.Errorw("Failed to deploy timelock", "chain", chain.String(), "err", err) return nil, err } + + callProxy, err := deployment.DeployContract(lggr, chain, ab, + func(chain deployment.Chain) deployment.ContractDeploy[*owner_helpers.CallProxy] { + callProxy, tx2, cc, err2 := owner_helpers.DeployCallProxy( + chain.DeployerKey, + chain.Client, + timelock.Address, + ) + return deployment.ContractDeploy[*owner_helpers.CallProxy]{ + callProxy, cc, tx2, deployment.NewTypeAndVersion(types.CallProxy, deployment.Version1_0_0), err2, + } + }) + if err != nil { + lggr.Errorw("Failed to deploy call proxy", "chain", chain.String(), "err", err) + return nil, err + } + + grantRoleTx, err := timelock.Contract.GrantRole( + chain.DeployerKey, + v1_0.EXECUTOR_ROLE.ID, + callProxy.Address, + ) + if err != nil { + lggr.Errorw("Failed to grant timelock executor role", "chain", chain.String(), "err", err) + return nil, err + } + + if _, err := deployment.ConfirmIfNoError(chain, grantRoleTx, err); err != nil { + lggr.Errorw("Failed to grant timelock executor role", "chain", chain.String(), "err", err) + return nil, err + } // We grant the timelock the admin role on the MCMS contracts. tx, err := timelock.Contract.GrantRole(chain.DeployerKey, v1_0.ADMIN_ROLE.ID, timelock.Address) @@ -133,5 +167,6 @@ func DeployMCMSWithTimelockContracts( Bypasser: bypasser, Proposer: proposer, Timelock: timelock, + CallProxy: callProxy, }, nil } diff --git a/deployment/common/changeset/internal/mcms_test.go b/deployment/common/changeset/internal/mcms_test.go index 2269911f4cd..8446aab4bfe 100644 --- a/deployment/common/changeset/internal/mcms_test.go +++ b/deployment/common/changeset/internal/mcms_test.go @@ -2,16 +2,15 @@ package internal_test import ( "encoding/json" - "math/big" "testing" - "github.com/ethereum/go-ethereum/common" chainsel "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/common/changeset" "github.com/smartcontractkit/chainlink/deployment/common/changeset/internal" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" "github.com/smartcontractkit/chainlink/deployment/common/types" "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -24,7 +23,7 @@ func TestDeployMCMSWithConfig(t *testing.T) { }) ab := deployment.NewMemoryAddressBook() _, err := internal.DeployMCMSWithConfig(types.ProposerManyChainMultisig, - lggr, chains[chainsel.TEST_90000001.Selector], ab, changeset.SingleGroupMCMS(t)) + lggr, chains[chainsel.TEST_90000001.Selector], ab, proposalutils.SingleGroupMCMS(t)) require.NoError(t, err) } @@ -36,19 +35,11 @@ func TestDeployMCMSWithTimelockContracts(t *testing.T) { ab := deployment.NewMemoryAddressBook() _, err := internal.DeployMCMSWithTimelockContracts(lggr, chains[chainsel.TEST_90000001.Selector], - ab, types.MCMSWithTimelockConfig{ - Canceller: changeset.SingleGroupMCMS(t), - Bypasser: changeset.SingleGroupMCMS(t), - Proposer: changeset.SingleGroupMCMS(t), - TimelockExecutors: []common.Address{ - chains[chainsel.TEST_90000001.Selector].DeployerKey.From, - }, - TimelockMinDelay: big.NewInt(0), - }) + ab, proposalutils.SingleGroupTimelockConfig(t)) require.NoError(t, err) addresses, err := ab.AddressesForChain(chainsel.TEST_90000001.Selector) require.NoError(t, err) - require.Len(t, addresses, 4) + require.Len(t, addresses, 5) mcmsState, err := changeset.MaybeLoadMCMSWithTimelockState(chains[chainsel.TEST_90000001.Selector], addresses) require.NoError(t, err) v, err := mcmsState.GenerateMCMSWithTimelockView() diff --git a/deployment/common/changeset/state.go b/deployment/common/changeset/state.go index 0055c908f8d..c45fe6ba9b5 100644 --- a/deployment/common/changeset/state.go +++ b/deployment/common/changeset/state.go @@ -5,9 +5,9 @@ import ( "fmt" "github.com/ethereum/go-ethereum/common" - owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" "github.com/smartcontractkit/chainlink/deployment/common/types" "github.com/smartcontractkit/chainlink/deployment/common/view/v1_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" @@ -19,28 +19,18 @@ import ( // It is public for use in product specific packages. // Either all fields are nil or all fields are non-nil. type MCMSWithTimelockState struct { - CancellerMcm *owner_helpers.ManyChainMultiSig - BypasserMcm *owner_helpers.ManyChainMultiSig - ProposerMcm *owner_helpers.ManyChainMultiSig - Timelock *owner_helpers.RBACTimelock + *proposalutils.MCMSWithTimelockContracts } -// Validate checks that all fields are non-nil, ensuring it's ready -// for use generating views or interactions. -func (state MCMSWithTimelockState) Validate() error { - if state.Timelock == nil { - return errors.New("timelock not found") - } - if state.CancellerMcm == nil { - return errors.New("canceller not found") - } - if state.ProposerMcm == nil { - return errors.New("proposer not found") - } - if state.BypasserMcm == nil { - return errors.New("bypasser not found") +func MaybeLoadMCMSWithTimelockState(chain deployment.Chain, addresses map[string]deployment.TypeAndVersion) (*MCMSWithTimelockState, error) { + contracts, err := proposalutils.MaybeLoadMCMSWithTimelockContracts(chain, addresses) + if err != nil { + return nil, err } - return nil + + return &MCMSWithTimelockState{ + MCMSWithTimelockContracts: contracts, + }, nil } func (state MCMSWithTimelockState) GenerateMCMSWithTimelockView() (v1_0.MCMSWithTimelockView, error) { @@ -51,6 +41,10 @@ func (state MCMSWithTimelockState) GenerateMCMSWithTimelockView() (v1_0.MCMSWith if err != nil { return v1_0.MCMSWithTimelockView{}, nil } + callProxyView, err := v1_0.GenerateCallProxyView(*state.CallProxy) + if err != nil { + return v1_0.MCMSWithTimelockView{}, nil + } bypasserView, err := v1_0.GenerateMCMSView(*state.BypasserMcm) if err != nil { return v1_0.MCMSWithTimelockView{}, nil @@ -68,64 +62,10 @@ func (state MCMSWithTimelockState) GenerateMCMSWithTimelockView() (v1_0.MCMSWith Bypasser: bypasserView, Proposer: proposerView, Canceller: cancellerView, + CallProxy: callProxyView, }, nil } -// MaybeLoadMCMSWithTimelockState looks for the addresses corresponding to -// contracts deployed with DeployMCMSWithTimelock and loads them into a -// MCMSWithTimelockState struct. If none of the contracts are found, the state struct will be nil. -// An error indicates: -// - Found but was unable to load a contract -// - It only found part of the bundle of contracts -// - If found more than one instance of a contract (we expect one bundle in the given addresses) -func MaybeLoadMCMSWithTimelockState(chain deployment.Chain, addresses map[string]deployment.TypeAndVersion) (*MCMSWithTimelockState, error) { - state := MCMSWithTimelockState{} - // We expect one of each contract on the chain. - timelock := deployment.NewTypeAndVersion(types.RBACTimelock, deployment.Version1_0_0) - proposer := deployment.NewTypeAndVersion(types.ProposerManyChainMultisig, deployment.Version1_0_0) - canceller := deployment.NewTypeAndVersion(types.CancellerManyChainMultisig, deployment.Version1_0_0) - bypasser := deployment.NewTypeAndVersion(types.BypasserManyChainMultisig, deployment.Version1_0_0) - - // Ensure we either have the bundle or not. - _, err := deployment.AddressesContainBundle(addresses, - map[deployment.TypeAndVersion]struct{}{ - timelock: {}, proposer: {}, canceller: {}, bypasser: {}, - }) - if err != nil { - return nil, fmt.Errorf("unable to check MCMS contracts on chain %s error: %w", chain.Name(), err) - } - - for address, tvStr := range addresses { - switch tvStr { - case timelock: - tl, err := owner_helpers.NewRBACTimelock(common.HexToAddress(address), chain.Client) - if err != nil { - return nil, err - } - state.Timelock = tl - case proposer: - mcms, err := owner_helpers.NewManyChainMultiSig(common.HexToAddress(address), chain.Client) - if err != nil { - return nil, err - } - state.ProposerMcm = mcms - case bypasser: - mcms, err := owner_helpers.NewManyChainMultiSig(common.HexToAddress(address), chain.Client) - if err != nil { - return nil, err - } - state.BypasserMcm = mcms - case canceller: - mcms, err := owner_helpers.NewManyChainMultiSig(common.HexToAddress(address), chain.Client) - if err != nil { - return nil, err - } - state.CancellerMcm = mcms - } - } - return &state, nil -} - type LinkTokenState struct { LinkToken *link_token.LinkToken } diff --git a/deployment/common/changeset/test_helpers.go b/deployment/common/changeset/test_helpers.go index 2d5295282f5..e92b36e5b55 100644 --- a/deployment/common/changeset/test_helpers.go +++ b/deployment/common/changeset/test_helpers.go @@ -5,11 +5,11 @@ import ( "testing" mapset "github.com/deckarep/golang-set/v2" - "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" ) type ChangesetApplication struct { @@ -33,7 +33,7 @@ func WrapChangeSet[C any](fn deployment.ChangeSet[C]) func(e deployment.Environm } // ApplyChangesets applies the changeset applications to the environment and returns the updated environment. -func ApplyChangesets(t *testing.T, e deployment.Environment, timelocksPerChain map[uint64]*gethwrappers.RBACTimelock, changesetApplications []ChangesetApplication) (deployment.Environment, error) { +func ApplyChangesets(t *testing.T, e deployment.Environment, timelockContractsPerChain map[uint64]*proposalutils.TimelockExecutionContracts, changesetApplications []ChangesetApplication) (deployment.Environment, error) { currentEnv := e for i, csa := range changesetApplications { out, err := csa.Changeset(currentEnv, csa.Config) @@ -73,13 +73,14 @@ func ApplyChangesets(t *testing.T, e deployment.Environment, timelocksPerChain m chains.Add(uint64(op.ChainIdentifier)) } - signed := SignProposal(t, e, &prop) + signed := proposalutils.SignProposal(t, e, &prop) for _, sel := range chains.ToSlice() { - timelock, ok := timelocksPerChain[sel] - if !ok || timelock == nil { - return deployment.Environment{}, fmt.Errorf("timelock not found for chain %d", sel) + timelockContracts, ok := timelockContractsPerChain[sel] + if !ok || timelockContracts == nil { + return deployment.Environment{}, fmt.Errorf("timelock contracts not found for chain %d", sel) } - ExecuteProposal(t, e, signed, timelock, sel) + + proposalutils.ExecuteProposal(t, e, signed, timelockContracts, sel) } } } @@ -91,6 +92,7 @@ func ApplyChangesets(t *testing.T, e deployment.Environment, timelocksPerChain m NodeIDs: e.NodeIDs, Offchain: e.Offchain, OCRSecrets: e.OCRSecrets, + GetContext: e.GetContext, } } return currentEnv, nil diff --git a/deployment/common/changeset/transfer_to_mcms_with_timelock_test.go b/deployment/common/changeset/transfer_to_mcms_with_timelock_test.go index 6cdff286707..40cef99a54f 100644 --- a/deployment/common/changeset/transfer_to_mcms_with_timelock_test.go +++ b/deployment/common/changeset/transfer_to_mcms_with_timelock_test.go @@ -4,11 +4,9 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" - owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/stretchr/testify/require" - "math/big" - + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" "github.com/smartcontractkit/chainlink/deployment/common/types" "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -29,13 +27,7 @@ func TestTransferToMCMSWithTimelock(t *testing.T) { { Changeset: WrapChangeSet(DeployMCMSWithTimelock), Config: map[uint64]types.MCMSWithTimelockConfig{ - chain1: { - Canceller: SingleGroupMCMS(t), - Bypasser: SingleGroupMCMS(t), - Proposer: SingleGroupMCMS(t), - TimelockExecutors: e.AllDeployerKeys(), - TimelockMinDelay: big.NewInt(0), - }, + chain1: proposalutils.SingleGroupTimelockConfig(t), }, }, }) @@ -46,8 +38,11 @@ func TestTransferToMCMSWithTimelock(t *testing.T) { require.NoError(t, err) link, err := MaybeLoadLinkTokenState(e.Chains[chain1], addrs) require.NoError(t, err) - e, err = ApplyChangesets(t, e, map[uint64]*owner_helpers.RBACTimelock{ - chain1: state.Timelock, + e, err = ApplyChangesets(t, e, map[uint64]*proposalutils.TimelockExecutionContracts{ + chain1: { + Timelock: state.Timelock, + CallProxy: state.CallProxy, + }, }, []ChangesetApplication{ { Changeset: WrapChangeSet(TransferToMCMSWithTimelock), diff --git a/deployment/common/proposalutils/mcms_helpers.go b/deployment/common/proposalutils/mcms_helpers.go new file mode 100644 index 00000000000..4a7540761ee --- /dev/null +++ b/deployment/common/proposalutils/mcms_helpers.go @@ -0,0 +1,273 @@ +package proposalutils + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/common/types" +) + +// TimelockExecutionContracts is a helper struct for executing timelock proposals. it contains +// the timelock and call proxy contracts. +type TimelockExecutionContracts struct { + Timelock *owner_helpers.RBACTimelock + CallProxy *owner_helpers.CallProxy +} + +// NewTimelockExecutionContracts creates a new TimelockExecutionContracts struct. +// If there are multiple timelocks or call proxy on the chain, an error is returned. +// If there is a missing timelocks or call proxy on the chain, an error is returned. +func NewTimelockExecutionContracts(env deployment.Environment, chainSelector uint64) (*TimelockExecutionContracts, error) { + addrTypeVer, err := env.ExistingAddresses.AddressesForChain(chainSelector) + if err != nil { + return nil, fmt.Errorf("error getting addresses for chain: %w", err) + } + var timelock *owner_helpers.RBACTimelock + var callProxy *owner_helpers.CallProxy + for addr, tv := range addrTypeVer { + if tv.Type == types.RBACTimelock { + if timelock != nil { + return nil, fmt.Errorf("multiple timelocks found on chain %d", chainSelector) + } + var err error + timelock, err = owner_helpers.NewRBACTimelock(common.HexToAddress(addr), env.Chains[chainSelector].Client) + if err != nil { + return nil, fmt.Errorf("error creating timelock: %w", err) + } + } + if tv.Type == types.CallProxy { + if callProxy != nil { + return nil, fmt.Errorf("multiple call proxies found on chain %d", chainSelector) + } + var err error + callProxy, err = owner_helpers.NewCallProxy(common.HexToAddress(addr), env.Chains[chainSelector].Client) + if err != nil { + return nil, fmt.Errorf("error creating call proxy: %w", err) + } + } + } + if timelock == nil || callProxy == nil { + return nil, fmt.Errorf("missing timelock (%T) or call proxy(%T) on chain %d", timelock == nil, callProxy == nil, chainSelector) + } + return &TimelockExecutionContracts{ + Timelock: timelock, + CallProxy: callProxy, + }, nil +} + +type RunTimelockExecutorConfig struct { + Executor *mcms.Executor + TimelockContracts *TimelockExecutionContracts + ChainSelector uint64 + // BlockStart is optional. It filter the timelock scheduled events. + // If not provided, the executor assumes that the operations have not been executed yet + // executes all the operations for the given chain. + BlockStart *uint64 + BlockEnd *uint64 +} + +func (cfg RunTimelockExecutorConfig) Validate() error { + if cfg.Executor == nil { + return fmt.Errorf("executor is nil") + } + if cfg.TimelockContracts == nil { + return fmt.Errorf("timelock contracts is nil") + } + if cfg.ChainSelector == 0 { + return fmt.Errorf("chain selector is 0") + } + if cfg.BlockStart != nil && cfg.BlockEnd == nil { + if *cfg.BlockStart > *cfg.BlockEnd { + return fmt.Errorf("block start is greater than block end") + } + } + if cfg.BlockStart == nil && cfg.BlockEnd != nil { + return fmt.Errorf("block start must not be nil when block end is not nil") + } + + if len(cfg.Executor.Operations[mcms.ChainIdentifier(cfg.ChainSelector)]) == 0 { + return fmt.Errorf("no operations for chain %d", cfg.ChainSelector) + } + return nil +} + +// RunTimelockExecutor runs the scheduled operations for the given chain. +// If the block start is not provided, it assumes that the operations have not been scheduled yet +// and executes all the operations for the given chain. +// It is an error if there are no operations for the given chain. +func RunTimelockExecutor(env deployment.Environment, cfg RunTimelockExecutorConfig) error { + // TODO: This sort of helper probably should move to the MCMS lib. + // Execute all the transactions in the proposal which are for this chain. + if err := cfg.Validate(); err != nil { + return fmt.Errorf("error validating config: %w", err) + } + for _, chainOp := range cfg.Executor.Operations[mcms.ChainIdentifier(cfg.ChainSelector)] { + for idx, op := range cfg.Executor.ChainAgnosticOps { + start := cfg.BlockStart + end := cfg.BlockEnd + if bytes.Equal(op.Data, chainOp.Data) && op.To == chainOp.To { + if start == nil { + opTx, err2 := cfg.Executor.ExecuteOnChain(env.Chains[cfg.ChainSelector].Client, env.Chains[cfg.ChainSelector].DeployerKey, idx) + if err2 != nil { + return fmt.Errorf("error executing on chain: %w", err2) + } + block, err2 := env.Chains[cfg.ChainSelector].Confirm(opTx) + if err2 != nil { + return fmt.Errorf("error confirming on chain: %w", err2) + } + start = &block + end = &block + } + + it, err2 := cfg.TimelockContracts.Timelock.FilterCallScheduled(&bind.FilterOpts{ + Start: *start, + End: end, + Context: env.GetContext(), + }, nil, nil) + if err2 != nil { + return fmt.Errorf("error filtering call scheduled: %w", err2) + } + var calls []owner_helpers.RBACTimelockCall + var pred, salt [32]byte + for it.Next() { + // Note these are the same for the whole batch, can overwrite + pred = it.Event.Predecessor + salt = it.Event.Salt + verboseDebug(env.Logger, it.Event) + env.Logger.Info("scheduled", "event", it.Event) + calls = append(calls, owner_helpers.RBACTimelockCall{ + Target: it.Event.Target, + Data: it.Event.Data, + Value: it.Event.Value, + }) + } + + timelockExecutorProxy, err := owner_helpers.NewRBACTimelock(cfg.TimelockContracts.CallProxy.Address(), env.Chains[cfg.ChainSelector].Client) + if err != nil { + return fmt.Errorf("error creating timelock executor proxy: %w", err) + } + tx, err := timelockExecutorProxy.ExecuteBatch( + env.Chains[cfg.ChainSelector].DeployerKey, calls, pred, salt) + if err != nil { + return fmt.Errorf("error executing batch: %w", err) + } + _, err = env.Chains[cfg.ChainSelector].Confirm(tx) + if err != nil { + return fmt.Errorf("error confirming batch: %w", err) + } + } + } + } + return nil +} + +func verboseDebug(lggr logger.Logger, event *owner_helpers.RBACTimelockCallScheduled) { + b, err := json.Marshal(event) + if err != nil { + panic(err) + } + lggr.Debug("scheduled", "event", string(b)) +} + +// MCMSWithTimelockContracts holds the Go bindings +// for a MCMSWithTimelock contract deployment. +// It is public for use in product specific packages. +// Either all fields are nil or all fields are non-nil. +type MCMSWithTimelockContracts struct { + CancellerMcm *owner_helpers.ManyChainMultiSig + BypasserMcm *owner_helpers.ManyChainMultiSig + ProposerMcm *owner_helpers.ManyChainMultiSig + Timelock *owner_helpers.RBACTimelock + CallProxy *owner_helpers.CallProxy +} + +// Validate checks that all fields are non-nil, ensuring it's ready +// for use generating views or interactions. +func (state MCMSWithTimelockContracts) Validate() error { + if state.Timelock == nil { + return errors.New("timelock not found") + } + if state.CancellerMcm == nil { + return errors.New("canceller not found") + } + if state.ProposerMcm == nil { + return errors.New("proposer not found") + } + if state.BypasserMcm == nil { + return errors.New("bypasser not found") + } + if state.CallProxy == nil { + return errors.New("call proxy not found") + } + return nil +} + +// MaybeLoadMCMSWithTimelockContracts looks for the addresses corresponding to +// contracts deployed with DeployMCMSWithTimelock and loads them into a +// MCMSWithTimelockState struct. If none of the contracts are found, the state struct will be nil. +// An error indicates: +// - Found but was unable to load a contract +// - It only found part of the bundle of contracts +// - If found more than one instance of a contract (we expect one bundle in the given addresses) +func MaybeLoadMCMSWithTimelockContracts(chain deployment.Chain, addresses map[string]deployment.TypeAndVersion) (*MCMSWithTimelockContracts, error) { + state := MCMSWithTimelockContracts{} + // We expect one of each contract on the chain. + timelock := deployment.NewTypeAndVersion(types.RBACTimelock, deployment.Version1_0_0) + callProxy := deployment.NewTypeAndVersion(types.CallProxy, deployment.Version1_0_0) + proposer := deployment.NewTypeAndVersion(types.ProposerManyChainMultisig, deployment.Version1_0_0) + canceller := deployment.NewTypeAndVersion(types.CancellerManyChainMultisig, deployment.Version1_0_0) + bypasser := deployment.NewTypeAndVersion(types.BypasserManyChainMultisig, deployment.Version1_0_0) + + // Ensure we either have the bundle or not. + _, err := deployment.AddressesContainBundle(addresses, + map[deployment.TypeAndVersion]struct{}{ + timelock: {}, proposer: {}, canceller: {}, bypasser: {}, callProxy: {}, + }) + if err != nil { + return nil, fmt.Errorf("unable to check MCMS contracts on chain %s error: %w", chain.Name(), err) + } + + for address, tvStr := range addresses { + switch tvStr { + case timelock: + tl, err := owner_helpers.NewRBACTimelock(common.HexToAddress(address), chain.Client) + if err != nil { + return nil, err + } + state.Timelock = tl + case callProxy: + cp, err := owner_helpers.NewCallProxy(common.HexToAddress(address), chain.Client) + if err != nil { + return nil, err + } + state.CallProxy = cp + case proposer: + mcms, err := owner_helpers.NewManyChainMultiSig(common.HexToAddress(address), chain.Client) + if err != nil { + return nil, err + } + state.ProposerMcm = mcms + case bypasser: + mcms, err := owner_helpers.NewManyChainMultiSig(common.HexToAddress(address), chain.Client) + if err != nil { + return nil, err + } + state.BypasserMcm = mcms + case canceller: + mcms, err := owner_helpers.NewManyChainMultiSig(common.HexToAddress(address), chain.Client) + if err != nil { + return nil, err + } + state.CancellerMcm = mcms + } + } + return &state, nil +} diff --git a/deployment/common/changeset/mcms_test_helpers.go b/deployment/common/proposalutils/mcms_test_helpers.go similarity index 59% rename from deployment/common/changeset/mcms_test_helpers.go rename to deployment/common/proposalutils/mcms_test_helpers.go index 3951149815c..610fe84f34c 100644 --- a/deployment/common/changeset/mcms_test_helpers.go +++ b/deployment/common/proposalutils/mcms_test_helpers.go @@ -1,22 +1,21 @@ -package changeset +package proposalutils import ( - "bytes" - "context" "crypto/ecdsa" + "math/big" "testing" - "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/smartcontractkit/ccip-owner-contracts/pkg/config" - owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" chainsel "github.com/smartcontractkit/chain-selectors" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/deployment" + commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" + // "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" ) var ( @@ -65,51 +64,29 @@ func SignProposal(t *testing.T, env deployment.Environment, proposal *timelock.M } func ExecuteProposal(t *testing.T, env deployment.Environment, executor *mcms.Executor, - timelock *owner_helpers.RBACTimelock, sel uint64) { + timelockContracts *TimelockExecutionContracts, sel uint64) { t.Log("Executing proposal on chain", sel) // Set the root. tx, err2 := executor.SetRootOnChain(env.Chains[sel].Client, env.Chains[sel].DeployerKey, mcms.ChainIdentifier(sel)) if err2 != nil { require.NoError(t, deployment.MaybeDataErr(err2)) } + _, err2 = env.Chains[sel].Confirm(tx) require.NoError(t, err2) + cfg := RunTimelockExecutorConfig{ + Executor: executor, + TimelockContracts: timelockContracts, + ChainSelector: sel, + } + require.NoError(t, RunTimelockExecutor(env, cfg)) +} - // TODO: This sort of helper probably should move to the MCMS lib. - // Execute all the transactions in the proposal which are for this chain. - for _, chainOp := range executor.Operations[mcms.ChainIdentifier(sel)] { - for idx, op := range executor.ChainAgnosticOps { - if bytes.Equal(op.Data, chainOp.Data) && op.To == chainOp.To { - opTx, err3 := executor.ExecuteOnChain(env.Chains[sel].Client, env.Chains[sel].DeployerKey, idx) - require.NoError(t, err3) - block, err3 := env.Chains[sel].Confirm(opTx) - require.NoError(t, err3) - t.Log("executed", chainOp) - it, err3 := timelock.FilterCallScheduled(&bind.FilterOpts{ - Start: block, - End: &block, - Context: context.Background(), - }, nil, nil) - require.NoError(t, err3) - var calls []owner_helpers.RBACTimelockCall - var pred, salt [32]byte - for it.Next() { - // Note these are the same for the whole batch, can overwrite - pred = it.Event.Predecessor - salt = it.Event.Salt - t.Log("scheduled", it.Event) - calls = append(calls, owner_helpers.RBACTimelockCall{ - Target: it.Event.Target, - Data: it.Event.Data, - Value: it.Event.Value, - }) - } - tx, err := timelock.ExecuteBatch( - env.Chains[sel].DeployerKey, calls, pred, salt) - require.NoError(t, err) - _, err = env.Chains[sel].Confirm(tx) - require.NoError(t, err) - } - } +func SingleGroupTimelockConfig(t *testing.T) commontypes.MCMSWithTimelockConfig { + return commontypes.MCMSWithTimelockConfig{ + Canceller: SingleGroupMCMS(t), + Bypasser: SingleGroupMCMS(t), + Proposer: SingleGroupMCMS(t), + TimelockMinDelay: big.NewInt(0), } } diff --git a/deployment/common/proposalutils/propose.go b/deployment/common/proposalutils/propose.go index f525c0b6643..feaee69940e 100644 --- a/deployment/common/proposalutils/propose.go +++ b/deployment/common/proposalutils/propose.go @@ -11,6 +11,10 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" ) +const ( + DefaultValidUntil = 72 * time.Hour +) + func buildProposalMetadata( chainSelectors []uint64, proposerMcmsesPerChain map[uint64]*gethwrappers.ManyChainMultiSig, @@ -61,10 +65,10 @@ func BuildProposalFromBatches( for chainId, tl := range timelocksPerChain { tlsPerChainId[mcms.ChainIdentifier(chainId)] = tl } - + validUntil := time.Now().Unix() + int64(DefaultValidUntil.Seconds()) return timelock.NewMCMSWithTimelockProposal( "1", - 2004259681, // TODO: should be parameterized and based on current block timestamp. + uint32(validUntil), []mcms.Signature{}, false, mcmsMd, diff --git a/deployment/common/types/types.go b/deployment/common/types/types.go index 386ef8fbb36..0f04421af43 100644 --- a/deployment/common/types/types.go +++ b/deployment/common/types/types.go @@ -5,7 +5,6 @@ import ( "math/big" "time" - "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/ccip-owner-contracts/pkg/config" "github.com/smartcontractkit/chainlink/deployment" @@ -16,6 +15,7 @@ const ( CancellerManyChainMultisig deployment.ContractType = "CancellerManyChainMultiSig" ProposerManyChainMultisig deployment.ContractType = "ProposerManyChainMultiSig" RBACTimelock deployment.ContractType = "RBACTimelock" + CallProxy deployment.ContractType = "CallProxy" // LinkToken is the burn/mint link token. It should be used everywhere for // new deployments. Corresponds to // https://github.com/smartcontractkit/chainlink/blob/develop/core/gethwrappers/shared/generated/link_token/link_token.go#L34 @@ -29,11 +29,10 @@ const ( ) type MCMSWithTimelockConfig struct { - Canceller config.Config - Bypasser config.Config - Proposer config.Config - TimelockExecutors []common.Address - TimelockMinDelay *big.Int + Canceller config.Config + Bypasser config.Config + Proposer config.Config + TimelockMinDelay *big.Int } type OCRParameters struct { diff --git a/deployment/common/view/v1_0/mcms.go b/deployment/common/view/v1_0/mcms.go index 25ca614a553..bc971623545 100644 --- a/deployment/common/view/v1_0/mcms.go +++ b/deployment/common/view/v1_0/mcms.go @@ -107,11 +107,24 @@ func GenerateTimelockView(tl owner_helpers.RBACTimelock) (TimelockView, error) { }, nil } +type CallProxyView struct { + types.ContractMetaData +} + +func GenerateCallProxyView(cp owner_helpers.CallProxy) (CallProxyView, error) { + return CallProxyView{ + ContractMetaData: types.ContractMetaData{ + Address: cp.Address(), + }, + }, nil +} + type MCMSWithTimelockView struct { - Bypasser MCMSView `json:"bypasser"` - Canceller MCMSView `json:"canceller"` - Proposer MCMSView `json:"proposer"` - Timelock TimelockView `json:"timelock"` + Bypasser MCMSView `json:"bypasser"` + Canceller MCMSView `json:"canceller"` + Proposer MCMSView `json:"proposer"` + Timelock TimelockView `json:"timelock"` + CallProxy CallProxyView `json:"callProxy"` } func GenerateMCMSWithTimelockView( @@ -124,6 +137,10 @@ func GenerateMCMSWithTimelockView( if err != nil { return MCMSWithTimelockView{}, nil } + callProxyView, err := GenerateCallProxyView(owner_helpers.CallProxy{}) + if err != nil { + return MCMSWithTimelockView{}, nil + } bypasserView, err := GenerateMCMSView(bypasser) if err != nil { return MCMSWithTimelockView{}, nil @@ -142,5 +159,6 @@ func GenerateMCMSWithTimelockView( Bypasser: bypasserView, Proposer: proposerView, Canceller: cancellerView, + CallProxy: callProxyView, }, nil } diff --git a/deployment/environment.go b/deployment/environment.go index 3d120adbbf1..c9de89b8c0c 100644 --- a/deployment/environment.go +++ b/deployment/environment.go @@ -95,6 +95,7 @@ type Environment struct { Logger logger.Logger ExistingAddresses AddressBook Chains map[uint64]Chain + SolChains map[uint64]SolChain NodeIDs []string Offchain OffchainClient GetContext func() context.Context @@ -331,7 +332,6 @@ func NodeInfo(nodeIDs []string, oc NodeChainConfigsLister) (Nodes, error) { Enabled: 1, Ids: nodeIDs, } - } nodesFromJD, err := oc.ListNodes(context.Background(), &nodev1.ListNodesRequest{ Filter: filter, diff --git a/deployment/environment/devenv/README.md b/deployment/environment/devenv/README.md index f5e11f0475e..e6f5bc1b5ac 100644 --- a/deployment/environment/devenv/README.md +++ b/deployment/environment/devenv/README.md @@ -14,11 +14,11 @@ Pre-requisites: #### Setting Up Testconfig with Simulated Private Ethereum Network -To run tests (e.g., [ccip-test](../../integration-tests/smoke/ccip_test.go)), -you need to set up the testconfig following the [testconfig setup instructions](../../integration-tests/testconfig/README.md). +To run tests (e.g., [ccip-test](../../../integration-tests/ccip-tests/smoke/ccip_test.go)), +you need to set up the testconfig following the [testconfig setup instructions](../../../integration-tests/testconfig/README.md). The testconfig specifies the details of the different configurations to set up the environment and run the tests. -Generally, tests are run with the [default](../../integration-tests/testconfig/default.toml) config unless overridden by product-specific config. -For example, the [ccip-test](../../integration-tests/smoke/ccip_test.go) uses [ccip.toml](../../integration-tests/testconfig/ccip/ccip.toml) to specify +Generally, tests are run with the [default](../../../integration-tests/testconfig/default.toml) config unless overridden by product-specific config. +For example, the [ccip-test](../../../integration-tests/ccip-tests/smoke/ccip_test.go) uses [ccip.toml](../../../integration-tests/testconfig/ccip/ccip.toml) to specify CCIP-specific test environment details. There are additional secret configuration parameters required by the `devenv` environment that are not stored in the testconfig. @@ -37,7 +37,7 @@ By default, tests are run with private Ethereum network containers set up in the the Chainlink nodes and job distributor. To run tests against existing testnet/mainnet, set the `selected_network` field in the testconfig with the specific network names. -For example, if running [ccip-smoke](../../integration-tests/smoke/ccip_test.go) tests with Sepolia, Avax, and Binance testnets, +For example, if running [ccip-smoke](../../../integration-tests/ccip-tests/smoke/ccip_test.go) tests with Sepolia, Avax, and Binance testnets, copy the contents of [sepolia_avax_binance.toml](../../integration-tests/testconfig/ccip/overrides/sepolia_avax_binance.toml) to the `overrides.toml` file. @@ -48,4 +48,4 @@ provide necessary secrets applicable to the network you are running the tests ag - `E2E_TEST__RPC_HTTP_URL_` - `E2E_TEST__RPC_WS_URL_` -Now you are all set to run the tests with the existing testnet/mainnet. \ No newline at end of file +Now you are all set to run the tests with the existing testnet/mainnet. diff --git a/deployment/environment/devenv/rmn.go b/deployment/environment/devenv/rmn.go index 63f27f1e422..3e0c6efe0cd 100644 --- a/deployment/environment/devenv/rmn.go +++ b/deployment/environment/devenv/rmn.go @@ -22,7 +22,6 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/lib/docker" "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" - "github.com/smartcontractkit/chainlink-testing-framework/lib/logstream" p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" ) @@ -51,7 +50,6 @@ func NewRage2ProxyComponent( imageVersion string, local ProxyLocalConfig, shared ProxySharedConfig, - logStream *logstream.LogStream, ) (*RageProxy, error) { rageName := fmt.Sprintf("%s-proxy-%s", name, uuid.NewString()[0:8]) @@ -71,7 +69,6 @@ func NewRage2ProxyComponent( ContainerImage: imageName, ContainerVersion: imageVersion, Networks: networks, - LogStream: logStream, }, Passphrase: DefaultAFNPassphrase, proxyListenerPort: listenPort, @@ -193,8 +190,7 @@ func NewAFN2ProxyComponent( imageName, imageVersion string, shared SharedConfig, - local LocalConfig, - logStream *logstream.LogStream) (*AFN2Proxy, error) { + local LocalConfig) (*AFN2Proxy, error) { afnName := fmt.Sprintf("%s-%s", name, uuid.NewString()[0:8]) rmn := &AFN2Proxy{ EnvComponent: test_env.EnvComponent{ @@ -202,7 +198,6 @@ func NewAFN2ProxyComponent( ContainerImage: imageName, ContainerVersion: imageVersion, Networks: networks, - LogStream: logStream, }, AFNPassphrase: DefaultAFNPassphrase, Shared: shared, @@ -343,7 +338,6 @@ func NewRMNCluster( proxyVersion string, rmnImage string, rmnVersion string, - logStream *logstream.LogStream, ) (*RMNCluster, error) { rmn := &RMNCluster{ t: t, @@ -351,7 +345,7 @@ func NewRMNCluster( Nodes: make(map[string]RMNNode), } for name, rmnConfig := range config { - proxy, err := NewRage2ProxyComponent(networks, name, proxyImage, proxyVersion, rmnConfig.ProxyLocal, rmnConfig.ProxyShared, logStream) + proxy, err := NewRage2ProxyComponent(networks, name, proxyImage, proxyVersion, rmnConfig.ProxyLocal, rmnConfig.ProxyShared) if err != nil { return nil, err } @@ -371,7 +365,7 @@ func NewRMNCluster( return nil, err } rmnConfig.Local.Networking.RageProxy = strings.TrimPrefix(fmt.Sprintf("%s:%s", proxyName, port), "/") - afn, err := NewAFN2ProxyComponent(networks, name, rmnImage, rmnVersion, rmnConfig.Shared, rmnConfig.Local, logStream) + afn, err := NewAFN2ProxyComponent(networks, name, rmnImage, rmnVersion, rmnConfig.Shared, rmnConfig.Local) if err != nil { return nil, err } diff --git a/deployment/go.mod b/deployment/go.mod index b9a2fdb255f..fc3d70c3900 100644 --- a/deployment/go.mod +++ b/deployment/go.mod @@ -7,6 +7,10 @@ toolchain go1.23.4 // Make sure we're working with the latest chainlink libs replace github.com/smartcontractkit/chainlink/v2 => ../ +// Using a separate inline `require` here to avoid surrounding line changes +// creating potential merge conflicts. +require github.com/smartcontractkit/chainlink/v2 v2.0.0-20241206210521-125d98cdaf66 + require ( github.com/Khan/genqlient v0.7.0 github.com/Masterminds/semver/v3 v3.3.0 @@ -24,11 +28,10 @@ require ( github.com/sethvargo/go-retry v0.2.4 github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 github.com/smartcontractkit/chain-selectors v1.0.34 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f + github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0 + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.13 - github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20241007185508-adbe57025f12 github.com/stretchr/testify v1.9.0 github.com/test-go/testify v1.1.4 @@ -407,7 +410,7 @@ require ( github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db // indirect github.com/smartcontractkit/chainlink-feeds v0.1.1 // indirect github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2 // indirect - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241204153209-c3a71b0eef99 // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8 // indirect github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 // indirect github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.5 // indirect diff --git a/deployment/go.sum b/deployment/go.sum index 7513309dddf..f9fb767d5da 100644 --- a/deployment/go.sum +++ b/deployment/go.sum @@ -1409,10 +1409,10 @@ github.com/smartcontractkit/chain-selectors v1.0.34 h1:MJ17OGu8+jjl426pcKrJkCf3f github.com/smartcontractkit/chain-selectors v1.0.34/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e h1:GnM6ZWV6vlk2+n6c6o+v/R1LtXzBGVVx7r37nt/h6Uc= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e/go.mod h1:80vGBbOfertJig0xFKsRfm+i17FkjdKkk1dAaGE45Os= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f h1:hH+cAG2zt+WK4I2m572LXAnAJg3wtGEAwzBKR8FiXo8= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0 h1:/1L+v4SxUD2K5RMRbfByyLfePMAgQKeD0onSetPnGmA= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 h1:ZA92CTX9JtEArrxgZw7PNctVxFS+/DmSXumkwf1WiMY= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e/go.mod h1:mUh5/woemsVaHgTorA080hrYmO3syBCmPdnWc/5dOqk= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db h1:N1RH1hSr2ACzOFc9hkCcjE8pRBTdcU3p8nsTJByaLes= @@ -1423,8 +1423,8 @@ github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 h1:0ewLMbAz3 github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0/go.mod h1:/dVVLXrsp+V0AbcYGJo3XMzKg3CkELsweA/TTopCsKE= github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2 h1:onBe3DqNrbtOAzKS4PrPIiJX65BGo1aYiYZxFVEW+jc= github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2/go.mod h1:m/A3lqD7ms/RsQ9BT5P2uceYY0QX5mIt4KQxT2G6qEo= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241204153209-c3a71b0eef99 h1:lvn9Yxah+QD1/PcgijLO0dNRa28HuQWZl8Kkxh46KJc= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241204153209-c3a71b0eef99/go.mod h1:p8aUDfJeley6oer7y+Ucd3edOtRlMTnWg3mN6rhaLWo= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc h1:dssRwJhmzJkUN/OajaDj2GsxBn+Tupk3bI1BkPEoJg0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc/go.mod h1:p8aUDfJeley6oer7y+Ucd3edOtRlMTnWg3mN6rhaLWo= github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8 h1:tNS7U9lrxkFvEuyxQv11HHOiV9LPDGC9wYEy+yM/Jv4= github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8/go.mod h1:EBrEgcdIbwepqguClkv8Ohy7CbyWSJaE4EC9aBJlQK0= github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.13 h1:T0kbw07Vb6xUyA9MIJZfErMgWseWi1zf7cYvRpoq7ug= diff --git a/deployment/helpers.go b/deployment/helpers.go index 50f4c404b09..dfbbccc2698 100644 --- a/deployment/helpers.go +++ b/deployment/helpers.go @@ -146,7 +146,7 @@ func DeployContract[C any]( lggr.Errorw("Failed to confirm deployment", "chain", chain.String(), "Contract", contractDeploy.Tv.String(), "err", err) return nil, err } - lggr.Infow("Deployed contract", "Contract", contractDeploy.Tv.String(), "addr", contractDeploy.Address, "chain", chain.Selector) + lggr.Infow("Deployed contract", "Contract", contractDeploy.Tv.String(), "addr", contractDeploy.Address, "chain", chain.String()) err = addressBook.Save(chain.Selector, contractDeploy.Address.String(), contractDeploy.Tv) if err != nil { lggr.Errorw("Failed to save contract address", "Contract", contractDeploy.Tv.String(), "addr", contractDeploy.Address, "chain", chain.String(), "err", err) diff --git a/deployment/keystone/capability_management.go b/deployment/keystone/capability_management.go index 4e15ea897ab..7e502d4f8ea 100644 --- a/deployment/keystone/capability_management.go +++ b/deployment/keystone/capability_management.go @@ -2,65 +2,54 @@ package keystone import ( "fmt" - "strings" + "math/big" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/deployment" kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" ) // AddCapabilities adds the capabilities to the registry -// it tries to add all capabilities in one go, if that fails, it falls back to adding them one by one -func AddCapabilities(lggr logger.Logger, registry *kcr.CapabilitiesRegistry, chain deployment.Chain, capabilities []kcr.CapabilitiesRegistryCapability) error { +func AddCapabilities(lggr logger.Logger, contractSet *ContractSet, chain deployment.Chain, capabilities []kcr.CapabilitiesRegistryCapability, useMCMS bool) (*timelock.BatchChainOperation, error) { if len(capabilities) == 0 { - return nil + return nil, nil } - // dedup capabilities - var deduped []kcr.CapabilitiesRegistryCapability - seen := make(map[string]struct{}) - for _, cap := range capabilities { - if _, ok := seen[CapabilityID(cap)]; !ok { - seen[CapabilityID(cap)] = struct{}{} - deduped = append(deduped, cap) - } + registry := contractSet.CapabilitiesRegistry + deduped, err := dedupCapabilities(registry, capabilities) + if err != nil { + return nil, fmt.Errorf("failed to dedup capabilities: %w", err) } - - tx, err := registry.AddCapabilities(chain.DeployerKey, deduped) + txOpts := chain.DeployerKey + if useMCMS { + txOpts = deployment.SimTransactOpts() + } + tx, err := registry.AddCapabilities(txOpts, deduped) if err != nil { err = DecodeErr(kcr.CapabilitiesRegistryABI, err) - // no typed errors in the abi, so we have to do string matching - // try to add all capabilities in one go, if that fails, fall back to 1-by-1 - if !strings.Contains(err.Error(), "CapabilityAlreadyExists") { - return fmt.Errorf("failed to call AddCapabilities: %w", err) - } - lggr.Warnw("capabilities already exist, falling back to 1-by-1", "capabilities", deduped) - for _, cap := range deduped { - tx, err = registry.AddCapabilities(chain.DeployerKey, []kcr.CapabilitiesRegistryCapability{cap}) - if err != nil { - err = DecodeErr(kcr.CapabilitiesRegistryABI, err) - if strings.Contains(err.Error(), "CapabilityAlreadyExists") { - lggr.Warnw("capability already exists, skipping", "capability", cap) - continue - } - return fmt.Errorf("failed to call AddCapabilities for capability %v: %w", cap, err) - } - // 1-by-1 tx is pending and we need to wait for it to be mined - _, err = chain.Confirm(tx) - if err != nil { - return fmt.Errorf("failed to confirm AddCapabilities confirm transaction %s: %w", tx.Hash().String(), err) - } - lggr.Debugw("registered capability", "capability", cap) - - } - } else { - // the bulk add tx is pending and we need to wait for it to be mined + return nil, fmt.Errorf("failed to add capabilities: %w", err) + } + var batch *timelock.BatchChainOperation + if !useMCMS { _, err = chain.Confirm(tx) if err != nil { - return fmt.Errorf("failed to confirm AddCapabilities confirm transaction %s: %w", tx.Hash().String(), err) + return nil, fmt.Errorf("failed to confirm AddCapabilities confirm transaction %s: %w", tx.Hash().String(), err) } lggr.Info("registered capabilities", "capabilities", deduped) + } else { + batch = &timelock.BatchChainOperation{ + ChainIdentifier: mcms.ChainIdentifier(chain.Selector), + Batch: []mcms.Operation{ + { + To: registry.Address(), + Data: tx.Data(), + Value: big.NewInt(0), + }, + }, + } } - return nil + return batch, nil } // CapabilityID returns a unique id for the capability @@ -68,3 +57,36 @@ func AddCapabilities(lggr logger.Logger, registry *kcr.CapabilitiesRegistry, cha func CapabilityID(c kcr.CapabilitiesRegistryCapability) string { return fmt.Sprintf("%s@%s", c.LabelledName, c.Version) } + +// dedupCapabilities deduplicates the capabilities +// dedup capabilities with respect to the registry +// contract reverts on adding the same capability twice and that would cause the whole transaction to revert +// which is very bad for us for mcms +func dedupCapabilities(registry *kcr.CapabilitiesRegistry, capabilities []kcr.CapabilitiesRegistryCapability) ([]kcr.CapabilitiesRegistryCapability, error) { + var out []kcr.CapabilitiesRegistryCapability + existing, err := registry.GetCapabilities(nil) + if err != nil { + return nil, fmt.Errorf("failed to call GetCapabilities: %w", err) + } + existingByID := make(map[[32]byte]struct{}) + for _, cap := range existing { + existingByID[cap.HashedId] = struct{}{} + } + seen := make(map[string]struct{}) + for _, candidate := range capabilities { + h, err := registry.GetHashedCapabilityId(nil, candidate.LabelledName, candidate.Version) + if err != nil { + return nil, fmt.Errorf("failed to call GetHashedCapabilityId: %w", err) + } + // dedup input capabilities + if _, exists := seen[CapabilityID(candidate)]; exists { + continue + } + seen[CapabilityID(candidate)] = struct{}{} + // dedup with respect to the registry + if _, exists := existingByID[h]; !exists { + out = append(out, candidate) + } + } + return out, nil +} diff --git a/deployment/keystone/changeset/accept_ownership_test.go b/deployment/keystone/changeset/accept_ownership_test.go index f205adda496..9e9d29e563a 100644 --- a/deployment/keystone/changeset/accept_ownership_test.go +++ b/deployment/keystone/changeset/accept_ownership_test.go @@ -1,16 +1,15 @@ package changeset_test import ( - "math/big" "testing" - owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" "github.com/smartcontractkit/chainlink-common/pkg/logger" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" "github.com/smartcontractkit/chainlink/deployment/common/types" "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/deployment/keystone/changeset" @@ -38,16 +37,14 @@ func TestAcceptAllOwnership(t *testing.T) { Changeset: commonchangeset.WrapChangeSet(changeset.DeployForwarder), Config: registrySel, }, + { + Changeset: commonchangeset.WrapChangeSet(changeset.DeployFeedsConsumer), + Config: &changeset.DeployFeedsConsumerRequest{ChainSelector: registrySel}, + }, { Changeset: commonchangeset.WrapChangeSet(commonchangeset.DeployMCMSWithTimelock), Config: map[uint64]types.MCMSWithTimelockConfig{ - registrySel: { - Canceller: commonchangeset.SingleGroupMCMS(t), - Bypasser: commonchangeset.SingleGroupMCMS(t), - Proposer: commonchangeset.SingleGroupMCMS(t), - TimelockExecutors: env.AllDeployerKeys(), - TimelockMinDelay: big.NewInt(0), - }, + registrySel: proposalutils.SingleGroupTimelockConfig(t), }, }, }) @@ -57,8 +54,11 @@ func TestAcceptAllOwnership(t *testing.T) { timelock, err := commonchangeset.MaybeLoadMCMSWithTimelockState(env.Chains[registrySel], addrs) require.NoError(t, err) - _, err = commonchangeset.ApplyChangesets(t, env, map[uint64]*owner_helpers.RBACTimelock{ - registrySel: timelock.Timelock, + _, err = commonchangeset.ApplyChangesets(t, env, map[uint64]*proposalutils.TimelockExecutionContracts{ + registrySel: &proposalutils.TimelockExecutionContracts{ + Timelock: timelock.Timelock, + CallProxy: timelock.CallProxy, + }, }, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(changeset.AcceptAllOwnershipsProposal), diff --git a/deployment/keystone/changeset/append_node_capbilities.go b/deployment/keystone/changeset/append_node_capabilities.go similarity index 56% rename from deployment/keystone/changeset/append_node_capbilities.go rename to deployment/keystone/changeset/append_node_capabilities.go index 974c4970c51..688d4fd8d2f 100644 --- a/deployment/keystone/changeset/append_node_capbilities.go +++ b/deployment/keystone/changeset/append_node_capabilities.go @@ -3,7 +3,11 @@ package changeset import ( "fmt" + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" kslib "github.com/smartcontractkit/chainlink/deployment/keystone" "github.com/smartcontractkit/chainlink/deployment/keystone/changeset/internal" ) @@ -16,15 +20,39 @@ type AppendNodeCapabilitiesRequest = MutateNodeCapabilitiesRequest // AppendNodeCapabilities adds any new capabilities to the registry, merges the new capabilities with the existing capabilities // of the node, and updates the nodes in the registry host the union of the new and existing capabilities. func AppendNodeCapabilities(env deployment.Environment, req *AppendNodeCapabilitiesRequest) (deployment.ChangesetOutput, error) { - cfg, err := req.convert(env) + c, err := req.convert(env) if err != nil { return deployment.ChangesetOutput{}, err } - _, err = internal.AppendNodeCapabilitiesImpl(env.Logger, cfg) + r, err := internal.AppendNodeCapabilitiesImpl(env.Logger, c) if err != nil { return deployment.ChangesetOutput{}, err } - return deployment.ChangesetOutput{}, nil + out := deployment.ChangesetOutput{} + if req.UseMCMS() { + if r.Ops == nil { + return out, fmt.Errorf("expected MCMS operation to be non-nil") + } + timelocksPerChain := map[uint64]common.Address{ + c.Chain.Selector: c.ContractSet.Timelock.Address(), + } + proposerMCMSes := map[uint64]*gethwrappers.ManyChainMultiSig{ + c.Chain.Selector: c.ContractSet.ProposerMcm, + } + + proposal, err := proposalutils.BuildProposalFromBatches( + timelocksPerChain, + proposerMCMSes, + []timelock.BatchChainOperation{*r.Ops}, + "proposal to set update node capabilities", + req.MCMSConfig.MinDuration, + ) + if err != nil { + return out, fmt.Errorf("failed to build proposal: %w", err) + } + out.Proposals = []timelock.MCMSWithTimelockProposal{*proposal} + } + return out, nil } func (req *AppendNodeCapabilitiesRequest) convert(e deployment.Environment) (*internal.AppendNodeCapabilitiesRequest, error) { @@ -35,21 +63,19 @@ func (req *AppendNodeCapabilitiesRequest) convert(e deployment.Environment) (*in if !ok { return nil, fmt.Errorf("registry chain selector %d does not exist in environment", req.RegistryChainSel) } - contracts, err := kslib.GetContractSets(e.Logger, &kslib.GetContractSetsRequest{ + resp, err := kslib.GetContractSets(e.Logger, &kslib.GetContractSetsRequest{ Chains: map[uint64]deployment.Chain{req.RegistryChainSel: registryChain}, - AddressBook: req.AddressBook, + AddressBook: e.ExistingAddresses, }) if err != nil { return nil, fmt.Errorf("failed to get contract sets: %w", err) } - registry := contracts.ContractSets[req.RegistryChainSel].CapabilitiesRegistry - if registry == nil { - return nil, fmt.Errorf("capabilities registry not found for chain %d", req.RegistryChainSel) - } + contracts := resp.ContractSets[req.RegistryChainSel] return &internal.AppendNodeCapabilitiesRequest{ Chain: registryChain, - Registry: registry, + ContractSet: &contracts, P2pToCapabilities: req.P2pToCapabilities, + UseMCMS: req.UseMCMS(), }, nil } diff --git a/deployment/keystone/changeset/append_node_capabilities_test.go b/deployment/keystone/changeset/append_node_capabilities_test.go new file mode 100644 index 00000000000..bfc01b309f5 --- /dev/null +++ b/deployment/keystone/changeset/append_node_capabilities_test.go @@ -0,0 +1,133 @@ +package changeset_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/exp/maps" + + commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" + "github.com/smartcontractkit/chainlink/deployment/keystone/changeset" + kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" +) + +func TestAppendNodeCapabilities(t *testing.T) { + t.Parallel() + + var ( + capA = kcr.CapabilitiesRegistryCapability{ + LabelledName: "capA", + Version: "0.4.2", + } + capB = kcr.CapabilitiesRegistryCapability{ + LabelledName: "capB", + Version: "3.16.0", + } + caps = []kcr.CapabilitiesRegistryCapability{capA, capB} + ) + t.Run("no mcms", func(t *testing.T) { + te := SetupTestEnv(t, TestConfig{ + WFDonConfig: DonConfig{N: 4}, + AssetDonConfig: DonConfig{N: 4}, + WriterDonConfig: DonConfig{N: 4}, + NumChains: 1, + }) + + newCapabilities := make(map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability) + for id, _ := range te.WFNodes { + k, err := p2pkey.MakePeerID(id) + require.NoError(t, err) + newCapabilities[k] = caps + } + + t.Run("succeeds if existing capabilities not explicit", func(t *testing.T) { + cfg := changeset.AppendNodeCapabilitiesRequest{ + RegistryChainSel: te.RegistrySelector, + P2pToCapabilities: newCapabilities, + } + + csOut, err := changeset.AppendNodeCapabilities(te.Env, &cfg) + require.NoError(t, err) + require.Len(t, csOut.Proposals, 0) + require.Nil(t, csOut.AddressBook) + + validateCapabilityAppends(t, te, newCapabilities) + }) + }) + t.Run("with mcms", func(t *testing.T) { + te := SetupTestEnv(t, TestConfig{ + WFDonConfig: DonConfig{N: 4}, + AssetDonConfig: DonConfig{N: 4}, + WriterDonConfig: DonConfig{N: 4}, + NumChains: 1, + UseMCMS: true, + }) + + newCapabilities := make(map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability) + for id, _ := range te.WFNodes { + k, err := p2pkey.MakePeerID(id) + require.NoError(t, err) + newCapabilities[k] = caps + } + + cfg := changeset.AppendNodeCapabilitiesRequest{ + RegistryChainSel: te.RegistrySelector, + P2pToCapabilities: newCapabilities, + MCMSConfig: &changeset.MCMSConfig{MinDuration: 0}, + } + + csOut, err := changeset.AppendNodeCapabilities(te.Env, &cfg) + require.NoError(t, err) + require.Len(t, csOut.Proposals, 1) + require.Len(t, csOut.Proposals[0].Transactions, 1) + require.Len(t, csOut.Proposals[0].Transactions[0].Batch, 2) // add capabilities, update nodes + require.Nil(t, csOut.AddressBook) + + // now apply the changeset such that the proposal is signed and execed + contracts := te.ContractSets()[te.RegistrySelector] + timelockContracts := map[uint64]*proposalutils.TimelockExecutionContracts{ + te.RegistrySelector: { + Timelock: contracts.Timelock, + CallProxy: contracts.CallProxy, + }, + } + + _, err = commonchangeset.ApplyChangesets(t, te.Env, timelockContracts, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(changeset.AppendNodeCapabilities), + Config: &cfg, + }, + }) + require.NoError(t, err) + validateCapabilityAppends(t, te, newCapabilities) + }) + +} + +// validateUpdate checks reads nodes from the registry and checks they have the expected updates +func validateCapabilityAppends(t *testing.T, te TestEnv, appended map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability) { + registry := te.ContractSets()[te.RegistrySelector].CapabilitiesRegistry + wfP2PIDs := p2pIDs(t, maps.Keys(te.WFNodes)) + nodes, err := registry.GetNodesByP2PIds(nil, wfP2PIDs) + require.NoError(t, err) + require.Len(t, nodes, len(wfP2PIDs)) + for _, node := range nodes { + want := appended[node.P2pId] + require.NotNil(t, want) + assertContainsCapabilities(t, registry, want, node) + } +} + +func assertContainsCapabilities(t *testing.T, registry *kcr.CapabilitiesRegistry, want []kcr.CapabilitiesRegistryCapability, got kcr.INodeInfoProviderNodeInfo) { + wantHashes := make([][32]byte, len(want)) + for i, c := range want { + h, err := registry.GetHashedCapabilityId(nil, c.LabelledName, c.Version) + require.NoError(t, err) + wantHashes[i] = h + assert.Contains(t, got.HashedCapabilityIds, h, "missing capability %v", c) + } + assert.LessOrEqual(t, len(want), len(got.HashedCapabilityIds)) +} diff --git a/deployment/keystone/changeset/deploy_forwarder.go b/deployment/keystone/changeset/deploy_forwarder.go index cf116decd54..1e4066770bd 100644 --- a/deployment/keystone/changeset/deploy_forwarder.go +++ b/deployment/keystone/changeset/deploy_forwarder.go @@ -3,7 +3,11 @@ package changeset import ( "fmt" + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" kslib "github.com/smartcontractkit/chainlink/deployment/keystone" ) @@ -35,7 +39,8 @@ type ConfigureForwardContractsRequest struct { WFNodeIDs []string RegistryChainSel uint64 - UseMCMS bool + // MCMSConfig is optional. If non-nil, the changes will be proposed using MCMS. + MCMSConfig *MCMSConfig } func (r ConfigureForwardContractsRequest) Validate() error { @@ -45,6 +50,10 @@ func (r ConfigureForwardContractsRequest) Validate() error { return nil } +func (r ConfigureForwardContractsRequest) UseMCMS() bool { + return r.MCMSConfig != nil +} + func ConfigureForwardContracts(env deployment.Environment, req ConfigureForwardContractsRequest) (deployment.ChangesetOutput, error) { wfDon, err := kslib.NewRegisteredDon(env, kslib.RegisteredDonConfig{ NodeIDs: req.WFNodeIDs, @@ -56,12 +65,46 @@ func ConfigureForwardContracts(env deployment.Environment, req ConfigureForwardC } r, err := kslib.ConfigureForwardContracts(&env, kslib.ConfigureForwarderContractsRequest{ Dons: []kslib.RegisteredDon{*wfDon}, - UseMCMS: req.UseMCMS, + UseMCMS: req.UseMCMS(), }) if err != nil { return deployment.ChangesetOutput{}, fmt.Errorf("failed to configure forward contracts: %w", err) } - return deployment.ChangesetOutput{ - Proposals: r.Proposals, - }, nil + + cresp, err := kslib.GetContractSets(env.Logger, &kslib.GetContractSetsRequest{ + Chains: env.Chains, + AddressBook: env.ExistingAddresses, + }) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to get contract sets: %w", err) + } + + var out deployment.ChangesetOutput + if req.UseMCMS() { + if len(r.OpsPerChain) == 0 { + return out, fmt.Errorf("expected MCMS operation to be non-nil") + } + for chainSelector, op := range r.OpsPerChain { + contracts := cresp.ContractSets[chainSelector] + timelocksPerChain := map[uint64]common.Address{ + chainSelector: contracts.Timelock.Address(), + } + proposerMCMSes := map[uint64]*gethwrappers.ManyChainMultiSig{ + chainSelector: contracts.ProposerMcm, + } + + proposal, err := proposalutils.BuildProposalFromBatches( + timelocksPerChain, + proposerMCMSes, + []timelock.BatchChainOperation{op}, + "proposal to set update nodes", + req.MCMSConfig.MinDuration, + ) + if err != nil { + return out, fmt.Errorf("failed to build proposal: %w", err) + } + out.Proposals = append(out.Proposals, *proposal) + } + } + return out, nil } diff --git a/deployment/keystone/changeset/deploy_forwarder_test.go b/deployment/keystone/changeset/deploy_forwarder_test.go index 32a53f1cf08..e04bac6d264 100644 --- a/deployment/keystone/changeset/deploy_forwarder_test.go +++ b/deployment/keystone/changeset/deploy_forwarder_test.go @@ -8,10 +8,10 @@ import ( "github.com/stretchr/testify/require" - "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/deployment" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/deployment/keystone/changeset" ) @@ -110,19 +110,23 @@ func TestConfigureForwarders(t *testing.T) { WFDonName: "test-wf-don", WFNodeIDs: wfNodes, RegistryChainSel: te.RegistrySelector, - UseMCMS: true, + MCMSConfig: &changeset.MCMSConfig{MinDuration: 0}, } csOut, err := changeset.ConfigureForwardContracts(te.Env, cfg) require.NoError(t, err) require.Len(t, csOut.Proposals, nChains) require.Nil(t, csOut.AddressBook) - timelocks := make(map[uint64]*gethwrappers.RBACTimelock) + timelockContracts := make(map[uint64]*proposalutils.TimelockExecutionContracts) for selector, contractSet := range te.ContractSets() { require.NotNil(t, contractSet.Timelock) - timelocks[selector] = contractSet.Timelock + require.NotNil(t, contractSet.CallProxy) + timelockContracts[selector] = &proposalutils.TimelockExecutionContracts{ + Timelock: contractSet.Timelock, + CallProxy: contractSet.CallProxy, + } } - _, err = commonchangeset.ApplyChangesets(t, te.Env, timelocks, []commonchangeset.ChangesetApplication{ + _, err = commonchangeset.ApplyChangesets(t, te.Env, timelockContracts, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(changeset.ConfigureForwardContracts), Config: cfg, diff --git a/deployment/keystone/changeset/deploy_ocr3.go b/deployment/keystone/changeset/deploy_ocr3.go index 0ce3d02844b..4dfed1e292c 100644 --- a/deployment/keystone/changeset/deploy_ocr3.go +++ b/deployment/keystone/changeset/deploy_ocr3.go @@ -5,9 +5,12 @@ import ( "fmt" "io" + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" kslib "github.com/smartcontractkit/chainlink/deployment/keystone" ) @@ -38,7 +41,12 @@ type ConfigureOCR3Config struct { DryRun bool WriteGeneratedConfig io.Writer // if not nil, write the generated config to this writer as JSON [OCR2OracleConfig] - UseMCMS bool + // MCMSConfig is optional. If non-nil, the changes will be proposed using MCMS. + MCMSConfig *MCMSConfig +} + +func (cfg ConfigureOCR3Config) UseMCMS() bool { + return cfg.MCMSConfig != nil } func ConfigureOCR3Contract(env deployment.Environment, cfg ConfigureOCR3Config) (deployment.ChangesetOutput, error) { @@ -47,7 +55,7 @@ func ConfigureOCR3Contract(env deployment.Environment, cfg ConfigureOCR3Config) NodeIDs: cfg.NodeIDs, OCR3Config: cfg.OCR3Config, DryRun: cfg.DryRun, - UseMCMS: cfg.UseMCMS, + UseMCMS: cfg.UseMCMS(), }) if err != nil { return deployment.ChangesetOutput{}, fmt.Errorf("failed to configure OCR3Capability: %w", err) @@ -67,11 +75,38 @@ func ConfigureOCR3Contract(env deployment.Environment, cfg ConfigureOCR3Config) } } // does not create any new addresses - var proposals []timelock.MCMSWithTimelockProposal - if cfg.UseMCMS { - proposals = append(proposals, *resp.Proposal) + var out deployment.ChangesetOutput + if cfg.UseMCMS() { + if resp.Ops == nil { + return out, fmt.Errorf("expected MCMS operation to be non-nil") + } + r, err := kslib.GetContractSets(env.Logger, &kslib.GetContractSetsRequest{ + Chains: env.Chains, + AddressBook: env.ExistingAddresses, + }) + if err != nil { + return out, fmt.Errorf("failed to get contract sets: %w", err) + } + contracts := r.ContractSets[cfg.ChainSel] + timelocksPerChain := map[uint64]common.Address{ + cfg.ChainSel: contracts.Timelock.Address(), + } + proposerMCMSes := map[uint64]*gethwrappers.ManyChainMultiSig{ + cfg.ChainSel: contracts.ProposerMcm, + } + + proposal, err := proposalutils.BuildProposalFromBatches( + timelocksPerChain, + proposerMCMSes, + []timelock.BatchChainOperation{*resp.Ops}, + "proposal to set update nodes", + cfg.MCMSConfig.MinDuration, + ) + if err != nil { + return out, fmt.Errorf("failed to build proposal: %w", err) + } + out.Proposals = []timelock.MCMSWithTimelockProposal{*proposal} + } - return deployment.ChangesetOutput{ - Proposals: proposals, - }, nil + return out, nil } diff --git a/deployment/keystone/changeset/deploy_ocr3_test.go b/deployment/keystone/changeset/deploy_ocr3_test.go index 0e5fea6b7c6..7a276886242 100644 --- a/deployment/keystone/changeset/deploy_ocr3_test.go +++ b/deployment/keystone/changeset/deploy_ocr3_test.go @@ -10,10 +10,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/chainlink-common/pkg/logger" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" "github.com/smartcontractkit/chainlink/deployment/environment/memory" kslib "github.com/smartcontractkit/chainlink/deployment/keystone" "github.com/smartcontractkit/chainlink/deployment/keystone/changeset" @@ -46,7 +46,6 @@ func TestDeployOCR3(t *testing.T) { func TestConfigureOCR3(t *testing.T) { t.Parallel() - lggr := logger.Test(t) c := kslib.OracleConfig{ MaxFaultyOracles: 1, @@ -73,7 +72,6 @@ func TestConfigureOCR3(t *testing.T) { NodeIDs: wfNodes, OCR3Config: &c, WriteGeneratedConfig: w, - UseMCMS: false, } csOut, err := changeset.ConfigureOCR3Contract(te.Env, cfg) @@ -106,7 +104,7 @@ func TestConfigureOCR3(t *testing.T) { NodeIDs: wfNodes, OCR3Config: &c, WriteGeneratedConfig: w, - UseMCMS: true, + MCMSConfig: &changeset.MCMSConfig{MinDuration: 0}, } csOut, err := changeset.ConfigureOCR3Contract(te.Env, cfg) @@ -119,18 +117,19 @@ func TestConfigureOCR3(t *testing.T) { assert.NotNil(t, csOut.Proposals) t.Logf("got: %v", csOut.Proposals[0]) - contractSetsResp, err := kslib.GetContractSets(lggr, &kslib.GetContractSetsRequest{ - Chains: te.Env.Chains, - AddressBook: te.Env.ExistingAddresses, - }) + contracts := te.ContractSets()[te.RegistrySelector] require.NoError(t, err) - var timelocks = map[uint64]*gethwrappers.RBACTimelock{ - te.RegistrySelector: contractSetsResp.ContractSets[te.RegistrySelector].Timelock, + var timelockContracts = map[uint64]*proposalutils.TimelockExecutionContracts{ + te.RegistrySelector: { + Timelock: contracts.Timelock, + CallProxy: contracts.CallProxy, + }, } + // now apply the changeset such that the proposal is signed and execed w2 := &bytes.Buffer{} cfg.WriteGeneratedConfig = w2 - _, err = commonchangeset.ApplyChangesets(t, te.Env, timelocks, []commonchangeset.ChangesetApplication{ + _, err = commonchangeset.ApplyChangesets(t, te.Env, timelockContracts, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(changeset.ConfigureOCR3Contract), Config: cfg, diff --git a/deployment/keystone/changeset/helpers_test.go b/deployment/keystone/changeset/helpers_test.go index faf112867ce..d956db991de 100644 --- a/deployment/keystone/changeset/helpers_test.go +++ b/deployment/keystone/changeset/helpers_test.go @@ -8,11 +8,9 @@ import ( "errors" "fmt" "math" - "math/big" "sort" "testing" - "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" @@ -22,6 +20,7 @@ import ( "github.com/smartcontractkit/chainlink/deployment" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/deployment/keystone" @@ -115,6 +114,7 @@ func (te TestEnv) ContractSets() map[uint64]kslib.ContractSet { } // SetupTestEnv sets up a keystone test environment with the given configuration +// TODO: make more configurable; eg many tests don't need all the nodes (like when testing a registry change) func SetupTestEnv(t *testing.T, c TestConfig) TestEnv { require.NoError(t, c.Validate()) lggr := logger.Test(t) @@ -220,15 +220,13 @@ func SetupTestEnv(t *testing.T, c TestConfig) TestEnv { } var allDons = []keystone.DonCapabilities{wfDon, cwDon, assetDon} - _, err = kschangeset.ConfigureInitialContractsChangeset(env, kschangeset.InitialContractsCfg{ + csOut, err := kschangeset.ConfigureInitialContractsChangeset(env, kschangeset.InitialContractsCfg{ RegistryChainSel: registryChainSel, Dons: allDons, OCR3Config: &ocr3Config, }) require.NoError(t, err) - // TODO: KS-rm_deploy_opt - //require.Nil(t, csOut.AddressBook, "no new addresses should be created in configure initial contracts") - //require.NoError(t, env.ExistingAddresses.Merge(csOut.AddressBook)) + require.Nil(t, csOut.AddressBook, "no new addresses should be created in configure initial contracts") req := &keystone.GetContractSetsRequest{ Chains: env.Chains, @@ -256,18 +254,11 @@ func SetupTestEnv(t *testing.T, c TestConfig) TestEnv { validateDon(t, gotRegistry, assetNodes, assetDon) if c.UseMCMS { - // TODO: mcms on all the chains, currently only on the registry chain. need to fix this for forwarders - // deploy, configure and xfer ownership of MCMS + // deploy, configure and xfer ownership of MCMS on all chains timelockCfgs := make(map[uint64]commontypes.MCMSWithTimelockConfig) for sel := range env.Chains { t.Logf("Enabling MCMS on chain %d", sel) - timelockCfgs[sel] = commontypes.MCMSWithTimelockConfig{ - Canceller: commonchangeset.SingleGroupMCMS(t), - Bypasser: commonchangeset.SingleGroupMCMS(t), - Proposer: commonchangeset.SingleGroupMCMS(t), - TimelockExecutors: env.AllDeployerKeys(), - TimelockMinDelay: big.NewInt(0), - } + timelockCfgs[sel] = proposalutils.SingleGroupTimelockConfig(t) } env, err = commonchangeset.ApplyChangesets(t, env, nil, []commonchangeset.ChangesetApplication{ { @@ -288,7 +279,7 @@ func SetupTestEnv(t *testing.T, c TestConfig) TestEnv { require.NoError(t, mcms.Validate()) // transfer ownership of all contracts to the MCMS - env, err = commonchangeset.ApplyChangesets(t, env, map[uint64]*gethwrappers.RBACTimelock{sel: mcms.Timelock}, []commonchangeset.ChangesetApplication{ + env, err = commonchangeset.ApplyChangesets(t, env, map[uint64]*proposalutils.TimelockExecutionContracts{sel: {Timelock: mcms.Timelock, CallProxy: mcms.CallProxy}}, []commonchangeset.ChangesetApplication{ { Changeset: commonchangeset.WrapChangeSet(kschangeset.AcceptAllOwnershipsProposal), Config: &kschangeset.AcceptAllOwnershipRequest{ diff --git a/deployment/keystone/changeset/internal/append_node_capabilities.go b/deployment/keystone/changeset/internal/append_node_capabilities.go index cb28c03c6f5..892aa4c1e16 100644 --- a/deployment/keystone/changeset/internal/append_node_capabilities.go +++ b/deployment/keystone/changeset/internal/append_node_capabilities.go @@ -11,17 +11,18 @@ import ( ) type AppendNodeCapabilitiesRequest struct { - Chain deployment.Chain - Registry *kcr.CapabilitiesRegistry + Chain deployment.Chain + ContractSet *kslib.ContractSet P2pToCapabilities map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability + UseMCMS bool } func (req *AppendNodeCapabilitiesRequest) Validate() error { if len(req.P2pToCapabilities) == 0 { return fmt.Errorf("p2pToCapabilities is empty") } - if req.Registry == nil { + if req.ContractSet.CapabilitiesRegistry == nil { return fmt.Errorf("registry is nil") } return nil @@ -31,30 +32,33 @@ func AppendNodeCapabilitiesImpl(lggr logger.Logger, req *AppendNodeCapabilitiesR if err := req.Validate(); err != nil { return nil, fmt.Errorf("failed to validate request: %w", err) } - // collect all the capabilities and add them to the registry - var capabilities []kcr.CapabilitiesRegistryCapability - for _, cap := range req.P2pToCapabilities { - capabilities = append(capabilities, cap...) - } - err := kslib.AddCapabilities(lggr, req.Registry, req.Chain, capabilities) - if err != nil { - return nil, fmt.Errorf("failed to add capabilities: %w", err) - } // for each node, merge the new capabilities with the existing ones and update the node updatesByPeer := make(map[p2pkey.PeerID]NodeUpdate) for p2pID, caps := range req.P2pToCapabilities { - caps, err := AppendCapabilities(lggr, req.Registry, req.Chain, []p2pkey.PeerID{p2pID}, caps) + caps, err := AppendCapabilities(lggr, req.ContractSet.CapabilitiesRegistry, req.Chain, []p2pkey.PeerID{p2pID}, caps) if err != nil { return nil, fmt.Errorf("failed to append capabilities for p2p %s: %w", p2pID, err) } updatesByPeer[p2pID] = NodeUpdate{Capabilities: caps[p2pID]} } + // collect all the capabilities and add them to the registry + var capabilities []kcr.CapabilitiesRegistryCapability + for _, cap := range req.P2pToCapabilities { + capabilities = append(capabilities, cap...) + } + op, err := kslib.AddCapabilities(lggr, req.ContractSet, req.Chain, capabilities, req.UseMCMS) + if err != nil { + return nil, fmt.Errorf("failed to add capabilities: %w", err) + } + updateNodesReq := &UpdateNodesRequest{ Chain: req.Chain, - Registry: req.Registry, + ContractSet: req.ContractSet, P2pToUpdates: updatesByPeer, + UseMCMS: req.UseMCMS, + Ops: op, } resp, err := UpdateNodes(lggr, updateNodesReq) if err != nil { diff --git a/deployment/keystone/changeset/internal/append_node_capabilities_test.go b/deployment/keystone/changeset/internal/append_node_capabilities_test.go index d28dcd73230..f2ec2bf5c8f 100644 --- a/deployment/keystone/changeset/internal/append_node_capabilities_test.go +++ b/deployment/keystone/changeset/internal/append_node_capabilities_test.go @@ -94,8 +94,8 @@ func TestAppendNodeCapabilities(t *testing.T) { t.Run(tt.name, func(t *testing.T) { setupResp := kstest.SetupTestRegistry(t, lggr, tt.args.initialState) - tt.args.req.Registry = setupResp.Registry tt.args.req.Chain = setupResp.Chain + tt.args.req.ContractSet = setupResp.ContractSet got, err := internal.AppendNodeCapabilitiesImpl(tt.args.lggr, tt.args.req) if (err != nil) != tt.wantErr { diff --git a/deployment/keystone/changeset/internal/test/utils.go b/deployment/keystone/changeset/internal/test/utils.go index 6fe4a8f4a2e..0a23f7e60a7 100644 --- a/deployment/keystone/changeset/internal/test/utils.go +++ b/deployment/keystone/changeset/internal/test/utils.go @@ -33,12 +33,14 @@ type SetupTestRegistryRequest struct { P2pToCapabilities map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability NopToNodes map[kcr.CapabilitiesRegistryNodeOperator][]*internal.P2PSignerEnc Dons []Don + // TODO maybe add support for MCMS at this level } type SetupTestRegistryResponse struct { Registry *kcr.CapabilitiesRegistry Chain deployment.Chain RegistrySelector uint64 + ContractSet *kslib.ContractSet } func SetupTestRegistry(t *testing.T, lggr logger.Logger, req *SetupTestRegistryRequest) *SetupTestRegistryResponse { @@ -99,6 +101,9 @@ func SetupTestRegistry(t *testing.T, lggr logger.Logger, req *SetupTestRegistryR Registry: registry, Chain: chain, RegistrySelector: chain.Selector, + ContractSet: &kslib.ContractSet{ + CapabilitiesRegistry: registry, + }, } } diff --git a/deployment/keystone/changeset/internal/update_don.go b/deployment/keystone/changeset/internal/update_don.go index 4883368dc4d..fc7e410e540 100644 --- a/deployment/keystone/changeset/internal/update_don.go +++ b/deployment/keystone/changeset/internal/update_don.go @@ -6,9 +6,12 @@ import ( "encoding/hex" "encoding/json" "fmt" + "math/big" "sort" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" @@ -26,18 +29,21 @@ type CapabilityConfig struct { } type UpdateDonRequest struct { - Registry *kcr.CapabilitiesRegistry - Chain deployment.Chain + Chain deployment.Chain + ContractSet *kslib.ContractSet // contract set for the given chain P2PIDs []p2pkey.PeerID // this is the unique identifier for the don CapabilityConfigs []CapabilityConfig // if Config subfield is nil, a default config is used + + UseMCMS bool } -func (r *UpdateDonRequest) appendNodeCapabilitiesRequest() *AppendNodeCapabilitiesRequest { +func (r *UpdateDonRequest) AppendNodeCapabilitiesRequest() *AppendNodeCapabilitiesRequest { out := &AppendNodeCapabilitiesRequest{ Chain: r.Chain, - Registry: r.Registry, + ContractSet: r.ContractSet, P2pToCapabilities: make(map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability), + UseMCMS: r.UseMCMS, } for _, p2pid := range r.P2PIDs { if _, exists := out.P2pToCapabilities[p2pid]; !exists { @@ -51,7 +57,7 @@ func (r *UpdateDonRequest) appendNodeCapabilitiesRequest() *AppendNodeCapabiliti } func (r *UpdateDonRequest) Validate() error { - if r.Registry == nil { + if r.ContractSet.CapabilitiesRegistry == nil { return fmt.Errorf("registry is required") } if len(r.P2PIDs) == 0 { @@ -62,6 +68,7 @@ func (r *UpdateDonRequest) Validate() error { type UpdateDonResponse struct { DonInfo kcr.CapabilitiesRegistryDONInfo + Ops *timelock.BatchChainOperation } func UpdateDon(lggr logger.Logger, req *UpdateDonRequest) (*UpdateDonResponse, error) { @@ -69,7 +76,8 @@ func UpdateDon(lggr logger.Logger, req *UpdateDonRequest) (*UpdateDonResponse, e return nil, fmt.Errorf("failed to validate request: %w", err) } - getDonsResp, err := req.Registry.GetDONs(&bind.CallOpts{}) + registry := req.ContractSet.CapabilitiesRegistry + getDonsResp, err := registry.GetDONs(&bind.CallOpts{}) if err != nil { return nil, fmt.Errorf("failed to get Dons: %w", err) } @@ -78,29 +86,42 @@ func UpdateDon(lggr logger.Logger, req *UpdateDonRequest) (*UpdateDonResponse, e if err != nil { return nil, fmt.Errorf("failed to lookup don by p2pIDs: %w", err) } - cfgs, err := computeConfigs(req.Registry, req.CapabilityConfigs, don) + cfgs, err := computeConfigs(registry, req.CapabilityConfigs, don) if err != nil { return nil, fmt.Errorf("failed to compute configs: %w", err) } - _, err = AppendNodeCapabilitiesImpl(lggr, req.appendNodeCapabilitiesRequest()) - if err != nil { - return nil, fmt.Errorf("failed to append node capabilities: %w", err) + txOpts := req.Chain.DeployerKey + if req.UseMCMS { + txOpts = deployment.SimTransactOpts() } - - tx, err := req.Registry.UpdateDON(req.Chain.DeployerKey, don.Id, don.NodeP2PIds, cfgs, don.IsPublic, don.F) + tx, err := registry.UpdateDON(txOpts, don.Id, don.NodeP2PIds, cfgs, don.IsPublic, don.F) if err != nil { err = kslib.DecodeErr(kcr.CapabilitiesRegistryABI, err) return nil, fmt.Errorf("failed to call UpdateDON: %w", err) } - - _, err = req.Chain.Confirm(tx) - if err != nil { - return nil, fmt.Errorf("failed to confirm UpdateDON transaction %s: %w", tx.Hash().String(), err) + var ops *timelock.BatchChainOperation + if !req.UseMCMS { + _, err = req.Chain.Confirm(tx) + if err != nil { + return nil, fmt.Errorf("failed to confirm UpdateDON transaction %s: %w", tx.Hash().String(), err) + } + } else { + ops = &timelock.BatchChainOperation{ + ChainIdentifier: mcms.ChainIdentifier(req.Chain.Selector), + Batch: []mcms.Operation{ + { + To: registry.Address(), + Data: tx.Data(), + Value: big.NewInt(0), + }, + }, + } } + out := don out.CapabilityConfigurations = cfgs - return &UpdateDonResponse{DonInfo: out}, nil + return &UpdateDonResponse{DonInfo: out, Ops: ops}, nil } func PeerIDsToBytes(p2pIDs []p2pkey.PeerID) [][32]byte { diff --git a/deployment/keystone/changeset/internal/update_don_test.go b/deployment/keystone/changeset/internal/update_don_test.go index e500ade60d7..93857b26f78 100644 --- a/deployment/keystone/changeset/internal/update_don_test.go +++ b/deployment/keystone/changeset/internal/update_don_test.go @@ -83,13 +83,13 @@ func TestUpdateDon(t *testing.T) { admin: admin_4, }) // capabilities - cap_A = kcr.CapabilitiesRegistryCapability{ + initialCap = kcr.CapabilitiesRegistryCapability{ LabelledName: "test", Version: "1.0.0", CapabilityType: 0, } - cap_B = kcr.CapabilitiesRegistryCapability{ + capToAdd = kcr.CapabilitiesRegistryCapability{ LabelledName: "cap b", Version: "1.0.0", CapabilityType: 1, @@ -104,7 +104,7 @@ func TestUpdateDon(t *testing.T) { { Name: "don 1", Nodes: []deployment.Node{node_1, node_2, node_3, node_4}, - Capabilities: []kcr.CapabilitiesRegistryCapability{cap_A}, + Capabilities: []kcr.CapabilitiesRegistryCapability{initialCap}, }, }, nops: []keystone.NOP{ @@ -115,14 +115,26 @@ func TestUpdateDon(t *testing.T) { }, } - testCfg := setupUpdateDonTest(t, lggr, cfg) + testCfg := registerTestDon(t, lggr, cfg) + // add the new capabilities to registry + m := make(map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability) + for _, node := range cfg.dons[0].Nodes { + m[node.PeerID] = append(m[node.PeerID], capToAdd) + } + + _, err := internal.AppendNodeCapabilitiesImpl(lggr, &internal.AppendNodeCapabilitiesRequest{ + Chain: testCfg.Chain, + ContractSet: testCfg.ContractSet, + P2pToCapabilities: m, + }) + require.NoError(t, err) req := &internal.UpdateDonRequest{ - Registry: testCfg.Registry, - Chain: testCfg.Chain, - P2PIDs: []p2pkey.PeerID{p2p_1.PeerID(), p2p_2.PeerID(), p2p_3.PeerID(), p2p_4.PeerID()}, + ContractSet: testCfg.ContractSet, + Chain: testCfg.Chain, + P2PIDs: []p2pkey.PeerID{p2p_1.PeerID(), p2p_2.PeerID(), p2p_3.PeerID(), p2p_4.PeerID()}, CapabilityConfigs: []internal.CapabilityConfig{ - {Capability: cap_A}, {Capability: cap_B}, + {Capability: initialCap}, {Capability: capToAdd}, }, } want := &internal.UpdateDonResponse{ @@ -131,8 +143,8 @@ func TestUpdateDon(t *testing.T) { ConfigCount: 1, NodeP2PIds: internal.PeerIDsToBytes([]p2pkey.PeerID{p2p_1.PeerID(), p2p_2.PeerID(), p2p_3.PeerID(), p2p_4.PeerID()}), CapabilityConfigurations: []kcr.CapabilitiesRegistryCapabilityConfiguration{ - {CapabilityId: kstest.MustCapabilityId(t, testCfg.Registry, cap_A)}, - {CapabilityId: kstest.MustCapabilityId(t, testCfg.Registry, cap_B)}, + {CapabilityId: kstest.MustCapabilityId(t, testCfg.Registry, initialCap)}, + {CapabilityId: kstest.MustCapabilityId(t, testCfg.Registry, capToAdd)}, }, }, } @@ -220,10 +232,11 @@ type setupUpdateDonTestResult struct { chain deployment.Chain } -func setupUpdateDonTest(t *testing.T, lggr logger.Logger, cfg setupUpdateDonTestConfig) *kstest.SetupTestRegistryResponse { +func registerTestDon(t *testing.T, lggr logger.Logger, cfg setupUpdateDonTestConfig) *kstest.SetupTestRegistryResponse { t.Helper() req := newSetupTestRegistryRequest(t, cfg.dons, cfg.nops) return kstest.SetupTestRegistry(t, lggr, req) + } func newSetupTestRegistryRequest(t *testing.T, dons []kslib.DonInfo, nops []keystone.NOP) *kstest.SetupTestRegistryRequest { diff --git a/deployment/keystone/changeset/internal/update_node_capabilities.go b/deployment/keystone/changeset/internal/update_node_capabilities.go index 0420c46f27d..fe101c90296 100644 --- a/deployment/keystone/changeset/internal/update_node_capabilities.go +++ b/deployment/keystone/changeset/internal/update_node_capabilities.go @@ -11,17 +11,18 @@ import ( ) type UpdateNodeCapabilitiesImplRequest struct { - Chain deployment.Chain - Registry *kcr.CapabilitiesRegistry - + Chain deployment.Chain + ContractSet *kslib.ContractSet P2pToCapabilities map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability + + UseMCMS bool } func (req *UpdateNodeCapabilitiesImplRequest) Validate() error { if len(req.P2pToCapabilities) == 0 { return fmt.Errorf("p2pToCapabilities is empty") } - if req.Registry == nil { + if req.ContractSet == nil { return fmt.Errorf("registry is nil") } @@ -37,7 +38,7 @@ func UpdateNodeCapabilitiesImpl(lggr logger.Logger, req *UpdateNodeCapabilitiesI for _, cap := range req.P2pToCapabilities { capabilities = append(capabilities, cap...) } - err := kslib.AddCapabilities(lggr, req.Registry, req.Chain, capabilities) + op, err := kslib.AddCapabilities(lggr, req.ContractSet, req.Chain, capabilities, req.UseMCMS) if err != nil { return nil, fmt.Errorf("failed to add capabilities: %w", err) } @@ -49,8 +50,10 @@ func UpdateNodeCapabilitiesImpl(lggr logger.Logger, req *UpdateNodeCapabilitiesI updateNodesReq := &UpdateNodesRequest{ Chain: req.Chain, - Registry: req.Registry, P2pToUpdates: p2pToUpdates, + ContractSet: req.ContractSet, + Ops: op, + UseMCMS: req.UseMCMS, } resp, err := UpdateNodes(lggr, updateNodesReq) if err != nil { diff --git a/deployment/keystone/changeset/internal/update_node_capabilities_test.go b/deployment/keystone/changeset/internal/update_node_capabilities_test.go index 0346ff20dd6..ac39e57b32d 100644 --- a/deployment/keystone/changeset/internal/update_node_capabilities_test.go +++ b/deployment/keystone/changeset/internal/update_node_capabilities_test.go @@ -92,8 +92,8 @@ func TestUpdateNodeCapabilities(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { setupResp := kstest.SetupTestRegistry(t, lggr, tt.args.initialState) - tt.args.req.Registry = setupResp.Registry tt.args.req.Chain = setupResp.Chain + tt.args.req.ContractSet = setupResp.ContractSet got, err := kslib.UpdateNodeCapabilitiesImpl(tt.args.lggr, tt.args.req) if (err != nil) != tt.wantErr { diff --git a/deployment/keystone/changeset/internal/update_nodes.go b/deployment/keystone/changeset/internal/update_nodes.go index b8a08c37e50..3480f39b084 100644 --- a/deployment/keystone/changeset/internal/update_nodes.go +++ b/deployment/keystone/changeset/internal/update_nodes.go @@ -5,10 +5,13 @@ import ( "encoding/hex" "errors" "fmt" + "math/big" "sort" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink-common/pkg/logger" kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" @@ -26,14 +29,19 @@ type NodeUpdate struct { } type UpdateNodesRequest struct { - Chain deployment.Chain - Registry *kcr.CapabilitiesRegistry + Chain deployment.Chain + ContractSet *kslib.ContractSet // contract set for the given chain P2pToUpdates map[p2pkey.PeerID]NodeUpdate + + UseMCMS bool + // If UseMCMS is true, and Ops is not nil then the UpdateNodes contract operation + // will be added to the Ops.Batch + Ops *timelock.BatchChainOperation } func (req *UpdateNodesRequest) NodeParams() ([]kcr.CapabilitiesRegistryNodeParams, error) { - return makeNodeParams(req.Registry, req.P2pToUpdates) + return makeNodeParams(req.ContractSet.CapabilitiesRegistry, req.P2pToUpdates) } // P2PSignerEnc represent the key fields in kcr.CapabilitiesRegistryNodeParams @@ -71,7 +79,7 @@ func (req *UpdateNodesRequest) Validate() error { } } - if req.Registry == nil { + if req.ContractSet.CapabilitiesRegistry == nil { return errors.New("registry is nil") } @@ -80,10 +88,14 @@ func (req *UpdateNodesRequest) Validate() error { type UpdateNodesResponse struct { NodeParams []kcr.CapabilitiesRegistryNodeParams + // MCMS operation to update the nodes + // The operation is added to the Batch of the given Ops if not nil + Ops *timelock.BatchChainOperation } // UpdateNodes updates the nodes in the registry -// the update sets the signer and capabilities for each node. it does not append capabilities to the existing ones +// the update sets the signer and capabilities for each node. +// The nodes and capabilities must already exist in the registry. func UpdateNodes(lggr logger.Logger, req *UpdateNodesRequest) (*UpdateNodesResponse, error) { if err := req.Validate(); err != nil { return nil, fmt.Errorf("failed to validate request: %w", err) @@ -94,17 +106,43 @@ func UpdateNodes(lggr logger.Logger, req *UpdateNodesRequest) (*UpdateNodesRespo err = kslib.DecodeErr(kcr.CapabilitiesRegistryABI, err) return nil, fmt.Errorf("failed to make node params: %w", err) } - tx, err := req.Registry.UpdateNodes(req.Chain.DeployerKey, params) + txOpts := req.Chain.DeployerKey + if req.UseMCMS { + txOpts = deployment.SimTransactOpts() + } + registry := req.ContractSet.CapabilitiesRegistry + tx, err := registry.UpdateNodes(txOpts, params) if err != nil { err = kslib.DecodeErr(kcr.CapabilitiesRegistryABI, err) return nil, fmt.Errorf("failed to call UpdateNodes: %w", err) } - _, err = req.Chain.Confirm(tx) - if err != nil { - return nil, fmt.Errorf("failed to confirm UpdateNodes confirm transaction %s: %w", tx.Hash().String(), err) + ops := req.Ops + if !req.UseMCMS { + _, err = req.Chain.Confirm(tx) + if err != nil { + return nil, fmt.Errorf("failed to confirm UpdateNodes confirm transaction %s: %w", tx.Hash().String(), err) + } + } else { + op := mcms.Operation{ + To: registry.Address(), + Data: tx.Data(), + Value: big.NewInt(0), + } + + if ops == nil { + ops = &timelock.BatchChainOperation{ + ChainIdentifier: mcms.ChainIdentifier(req.Chain.Selector), + Batch: []mcms.Operation{ + op, + }, + } + } else { + ops.Batch = append(ops.Batch, op) + } } - return &UpdateNodesResponse{NodeParams: params}, nil + + return &UpdateNodesResponse{NodeParams: params, Ops: ops}, nil } // AppendCapabilities appends the capabilities to the existing capabilities of the nodes listed in p2pIds in the registry diff --git a/deployment/keystone/changeset/internal/update_nodes_test.go b/deployment/keystone/changeset/internal/update_nodes_test.go index b167f210811..e730668f806 100644 --- a/deployment/keystone/changeset/internal/update_nodes_test.go +++ b/deployment/keystone/changeset/internal/update_nodes_test.go @@ -30,7 +30,7 @@ func Test_UpdateNodesRequest_validate(t *testing.T) { p2pToUpdates map[p2pkey.PeerID]internal.NodeUpdate nopToNodes map[kcr.CapabilitiesRegistryNodeOperator][]*internal.P2PSignerEnc chain deployment.Chain - registry *kcr.CapabilitiesRegistry + contractSet *kslib.ContractSet } tests := []struct { name string @@ -43,7 +43,7 @@ func Test_UpdateNodesRequest_validate(t *testing.T) { p2pToUpdates: map[p2pkey.PeerID]internal.NodeUpdate{}, nopToNodes: nil, chain: deployment.Chain{}, - registry: nil, + contractSet: nil, }, wantErr: true, }, @@ -55,9 +55,9 @@ func Test_UpdateNodesRequest_validate(t *testing.T) { EncryptionPublicKey: "jk", }, }, - nopToNodes: nil, - chain: deployment.Chain{}, - registry: nil, + nopToNodes: nil, + chain: deployment.Chain{}, + contractSet: nil, }, wantErr: true, }, @@ -69,9 +69,9 @@ func Test_UpdateNodesRequest_validate(t *testing.T) { EncryptionPublicKey: "aabb", }, }, - nopToNodes: nil, - chain: deployment.Chain{}, - registry: nil, + nopToNodes: nil, + chain: deployment.Chain{}, + contractSet: nil, }, wantErr: true, }, @@ -81,7 +81,7 @@ func Test_UpdateNodesRequest_validate(t *testing.T) { req := &internal.UpdateNodesRequest{ P2pToUpdates: tt.fields.p2pToUpdates, Chain: tt.fields.chain, - Registry: tt.fields.registry, + ContractSet: tt.fields.contractSet, } if err := req.Validate(); (err != nil) != tt.wantErr { t.Errorf("internal.UpdateNodesRequest.validate() error = %v, wantErr %v", err, tt.wantErr) @@ -130,8 +130,7 @@ func TestUpdateNodes(t *testing.T) { }, }, }, - Chain: chain, - Registry: nil, // set in test to ensure no conflicts + Chain: chain, }, nopsToNodes: map[kcr.CapabilitiesRegistryNodeOperator][]*internal.P2PSignerEnc{ testNop(t, "nop1"): []*internal.P2PSignerEnc{ @@ -177,8 +176,7 @@ func TestUpdateNodes(t *testing.T) { }, }, }, - Chain: chain, - Registry: nil, // set in test to ensure no conflicts + Chain: chain, }, nopsToNodes: map[kcr.CapabilitiesRegistryNodeOperator][]*internal.P2PSignerEnc{ testNop(t, "nop1"): []*internal.P2PSignerEnc{ @@ -235,8 +233,7 @@ func TestUpdateNodes(t *testing.T) { }, }, }, - Chain: chain, - Registry: nil, // set in test to ensure no conflicts + Chain: chain, }, nopsToNodes: map[kcr.CapabilitiesRegistryNodeOperator][]*internal.P2PSignerEnc{ testNop(t, "nopA"): []*internal.P2PSignerEnc{ @@ -300,8 +297,7 @@ func TestUpdateNodes(t *testing.T) { }, }, }, - Chain: chain, - Registry: nil, // set in test to ensure no conflicts + Chain: chain, }, nopsToNodes: map[kcr.CapabilitiesRegistryNodeOperator][]*internal.P2PSignerEnc{ testNop(t, "nopA"): []*internal.P2PSignerEnc{ @@ -350,8 +346,8 @@ func TestUpdateNodes(t *testing.T) { EncryptionPublicKey: newKeyStr, }, }, - Chain: chain, - Registry: nil, // set in test to ensure no conflicts + Chain: chain, + ContractSet: nil, // set in test to ensure no conflicts }, nopsToNodes: map[kcr.CapabilitiesRegistryNodeOperator][]*internal.P2PSignerEnc{ testNop(t, "nop1"): []*internal.P2PSignerEnc{ @@ -385,8 +381,8 @@ func TestUpdateNodes(t *testing.T) { Signer: [32]byte{0: 2, 1: 3}, }, }, - Chain: chain, - Registry: nil, // set in test to ensure no conflicts + Chain: chain, + ContractSet: nil, // set in test to ensure no conflicts }, nopsToNodes: map[kcr.CapabilitiesRegistryNodeOperator][]*internal.P2PSignerEnc{ testNop(t, "nop1"): []*internal.P2PSignerEnc{ @@ -420,8 +416,7 @@ func TestUpdateNodes(t *testing.T) { NodeOperatorID: 2, }, }, - Chain: chain, - Registry: nil, // set in test to ensure no conflicts + Chain: chain, }, nopsToNodes: map[kcr.CapabilitiesRegistryNodeOperator][]*internal.P2PSignerEnc{ testNop(t, "nop1"): []*internal.P2PSignerEnc{ @@ -463,7 +458,7 @@ func TestUpdateNodes(t *testing.T) { NopToNodes: tt.args.nopsToNodes, }) registry := setupResp.Registry - tt.args.req.Registry = setupResp.Registry + tt.args.req.ContractSet = setupResp.ContractSet tt.args.req.Chain = setupResp.Chain id, err := registry.GetHashedCapabilityId(&bind.CallOpts{}, phonyCap.LabelledName, phonyCap.Version) @@ -581,8 +576,8 @@ func TestUpdateNodes(t *testing.T) { Capabilities: toRegister, }, }, - Chain: chain, - Registry: registry, + Chain: chain, + ContractSet: setupResp.ContractSet, } _, err = internal.UpdateNodes(lggr, req) require.NoError(t, err) diff --git a/deployment/keystone/changeset/update_don.go b/deployment/keystone/changeset/update_don.go index 1ab40d5a935..3f43ea513be 100644 --- a/deployment/keystone/changeset/update_don.go +++ b/deployment/keystone/changeset/update_don.go @@ -4,8 +4,11 @@ import ( "fmt" "github.com/smartcontractkit/chainlink/deployment" + kslib "github.com/smartcontractkit/chainlink/deployment/keystone" + "github.com/smartcontractkit/chainlink/deployment/keystone/changeset/internal" kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" ) var _ deployment.ChangeSet[*UpdateDonRequest] = UpdateDon @@ -13,7 +16,28 @@ var _ deployment.ChangeSet[*UpdateDonRequest] = UpdateDon // CapabilityConfig is a struct that holds a capability and its configuration type CapabilityConfig = internal.CapabilityConfig -type UpdateDonRequest = internal.UpdateDonRequest +type UpdateDonRequest struct { + RegistryChainSel uint64 + P2PIDs []p2pkey.PeerID // this is the unique identifier for the don + CapabilityConfigs []CapabilityConfig // if Config subfield is nil, a default config is used + + // MCMSConfig is optional. If non-nil, the changes will be proposed using MCMS. + MCMSConfig *MCMSConfig +} + +func (r *UpdateDonRequest) Validate() error { + if len(r.P2PIDs) == 0 { + return fmt.Errorf("p2pIDs is required") + } + if len(r.CapabilityConfigs) == 0 { + return fmt.Errorf("capabilityConfigs is required") + } + return nil +} + +func (r UpdateDonRequest) UseMCMS() bool { + return r.MCMSConfig != nil +} type UpdateDonResponse struct { DonInfo kcr.CapabilitiesRegistryDONInfo @@ -23,9 +47,73 @@ type UpdateDonResponse struct { // This a complex action in practice that involves registering missing capabilities, adding the nodes, and updating // the capabilities of the DON func UpdateDon(env deployment.Environment, req *UpdateDonRequest) (deployment.ChangesetOutput, error) { - _, err := internal.UpdateDon(env.Logger, req) + appendResult, err := AppendNodeCapabilities(env, appendRequest(req)) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to append node capabilities: %w", err) + } + + ur, err := updateDonRequest(env, req) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to create update don request: %w", err) + } + updateResult, err := internal.UpdateDon(env.Logger, ur) if err != nil { return deployment.ChangesetOutput{}, fmt.Errorf("failed to update don: %w", err) } - return deployment.ChangesetOutput{}, nil + + out := deployment.ChangesetOutput{} + if req.UseMCMS() { + if updateResult.Ops == nil { + return out, fmt.Errorf("expected MCMS operation to be non-nil") + } + if len(appendResult.Proposals) == 0 { + return out, fmt.Errorf("expected append node capabilities to return proposals") + } + + out.Proposals = appendResult.Proposals + + // add the update don to the existing batch + // this makes the proposal all-or-nothing because all the operations are in the same batch, there is only one tr + // transaction and only one proposal + out.Proposals[0].Transactions[0].Batch = append(out.Proposals[0].Transactions[0].Batch, updateResult.Ops.Batch...) + + } + return out, nil + +} + +func appendRequest(r *UpdateDonRequest) *AppendNodeCapabilitiesRequest { + out := &AppendNodeCapabilitiesRequest{ + RegistryChainSel: r.RegistryChainSel, + P2pToCapabilities: make(map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability), + MCMSConfig: r.MCMSConfig, + } + for _, p2pid := range r.P2PIDs { + if _, exists := out.P2pToCapabilities[p2pid]; !exists { + out.P2pToCapabilities[p2pid] = make([]kcr.CapabilitiesRegistryCapability, 0) + } + for _, cc := range r.CapabilityConfigs { + out.P2pToCapabilities[p2pid] = append(out.P2pToCapabilities[p2pid], cc.Capability) + } + } + return out +} + +func updateDonRequest(env deployment.Environment, r *UpdateDonRequest) (*internal.UpdateDonRequest, error) { + resp, err := kslib.GetContractSets(env.Logger, &kslib.GetContractSetsRequest{ + Chains: env.Chains, + AddressBook: env.ExistingAddresses, + }) + if err != nil { + return nil, fmt.Errorf("failed to get contract sets: %w", err) + } + contractSet := resp.ContractSets[r.RegistryChainSel] + + return &internal.UpdateDonRequest{ + Chain: env.Chains[r.RegistryChainSel], + ContractSet: &contractSet, + P2PIDs: r.P2PIDs, + CapabilityConfigs: r.CapabilityConfigs, + UseMCMS: r.UseMCMS(), + }, nil } diff --git a/deployment/keystone/changeset/update_don_test.go b/deployment/keystone/changeset/update_don_test.go new file mode 100644 index 00000000000..64cb41c14e5 --- /dev/null +++ b/deployment/keystone/changeset/update_don_test.go @@ -0,0 +1,166 @@ +package changeset_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" + "github.com/smartcontractkit/chainlink/deployment/keystone/changeset" + "github.com/smartcontractkit/chainlink/deployment/keystone/changeset/internal" + kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" +) + +func TestUpdateDon(t *testing.T) { + t.Parallel() + + var ( + capA = kcr.CapabilitiesRegistryCapability{ + LabelledName: "capA", + Version: "0.4.2", + } + capB = kcr.CapabilitiesRegistryCapability{ + LabelledName: "capB", + Version: "3.16.0", + } + caps = []kcr.CapabilitiesRegistryCapability{capA, capB} + ) + t.Run("no mcms", func(t *testing.T) { + te := SetupTestEnv(t, TestConfig{ + WFDonConfig: DonConfig{N: 4}, + AssetDonConfig: DonConfig{N: 4}, + WriterDonConfig: DonConfig{N: 4}, + NumChains: 1, + }) + + // contract set is already deployed with capabilities + // we have to keep track of the existing capabilities to add to the new ones + var p2pIDs []p2pkey.PeerID + newCapabilities := make(map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability) + for id, _ := range te.WFNodes { + k, err := p2pkey.MakePeerID(id) + require.NoError(t, err) + p2pIDs = append(p2pIDs, k) + newCapabilities[k] = caps + } + + t.Run("succeeds if update sets new and existing capabilities", func(t *testing.T) { + cfg := changeset.UpdateDonRequest{ + RegistryChainSel: te.RegistrySelector, + P2PIDs: p2pIDs, + CapabilityConfigs: []changeset.CapabilityConfig{ + { + Capability: capA, + }, + { + Capability: capB, + }, + }, + } + + csOut, err := changeset.UpdateDon(te.Env, &cfg) + require.NoError(t, err) + require.Len(t, csOut.Proposals, 0) + require.Nil(t, csOut.AddressBook) + + assertDonContainsCapabilities(t, te.ContractSets()[te.RegistrySelector].CapabilitiesRegistry, caps, p2pIDs) + }) + }) + t.Run("with mcms", func(t *testing.T) { + te := SetupTestEnv(t, TestConfig{ + WFDonConfig: DonConfig{N: 4}, + AssetDonConfig: DonConfig{N: 4}, + WriterDonConfig: DonConfig{N: 4}, + NumChains: 1, + UseMCMS: true, + }) + + // contract set is already deployed with capabilities + // we have to keep track of the existing capabilities to add to the new ones + var p2pIDs []p2pkey.PeerID + for id, _ := range te.WFNodes { + k, err := p2pkey.MakePeerID(id) + require.NoError(t, err) + p2pIDs = append(p2pIDs, k) + } + + cfg := changeset.UpdateDonRequest{ + RegistryChainSel: te.RegistrySelector, + P2PIDs: p2pIDs, + CapabilityConfigs: []changeset.CapabilityConfig{ + { + Capability: capA, + }, + { + Capability: capB, + }, + }, + MCMSConfig: &changeset.MCMSConfig{MinDuration: 0}, + } + + csOut, err := changeset.UpdateDon(te.Env, &cfg) + require.NoError(t, err) + + if true { + require.Len(t, csOut.Proposals, 1) + require.Len(t, csOut.Proposals[0].Transactions, 1) // append node capabilties cs, update don + require.Len(t, csOut.Proposals[0].Transactions[0].Batch, 3) // add capabilities, update nodes, update don + require.Nil(t, csOut.AddressBook) + } else { + require.Len(t, csOut.Proposals, 1) + require.Len(t, csOut.Proposals[0].Transactions, 2) // append node capabilties cs, update don + require.Len(t, csOut.Proposals[0].Transactions[0].Batch, 2) // add capabilities, update nodes + require.Len(t, csOut.Proposals[0].Transactions[1].Batch, 1) // update don + require.Nil(t, csOut.AddressBook) + } + + // now apply the changeset such that the proposal is signed and execed + contracts := te.ContractSets()[te.RegistrySelector] + timelockContracts := map[uint64]*proposalutils.TimelockExecutionContracts{ + te.RegistrySelector: { + Timelock: contracts.Timelock, + CallProxy: contracts.CallProxy, + }, + } + _, err = commonchangeset.ApplyChangesets(t, te.Env, timelockContracts, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(changeset.UpdateDon), + Config: &cfg, + }, + }) + require.NoError(t, err) + assertDonContainsCapabilities(t, te.ContractSets()[te.RegistrySelector].CapabilitiesRegistry, caps, p2pIDs) + }) +} + +func assertDonContainsCapabilities(t *testing.T, registry *kcr.CapabilitiesRegistry, want []kcr.CapabilitiesRegistryCapability, p2pIDs []p2pkey.PeerID) { + dons, err := registry.GetDONs(nil) + require.NoError(t, err) + var got *kcr.CapabilitiesRegistryDONInfo + for i, don := range dons { + if internal.SortedHash(internal.PeerIDsToBytes(p2pIDs)) == internal.SortedHash(don.NodeP2PIds) { + got = &dons[i] + break + } + } + require.NotNil(t, got, "missing don with p2pIDs %v", p2pIDs) + wantHashes := make([][32]byte, len(want)) + for i, c := range want { + h, err := registry.GetHashedCapabilityId(nil, c.LabelledName, c.Version) + require.NoError(t, err) + wantHashes[i] = h + assert.Contains(t, capIDsFromCapCfgs(got.CapabilityConfigurations), h, "missing capability %v", c) + } + assert.LessOrEqual(t, len(want), len(got.CapabilityConfigurations), "too many capabilities") +} + +func capIDsFromCapCfgs(cfgs []kcr.CapabilitiesRegistryCapabilityConfiguration) [][32]byte { + out := make([][32]byte, len(cfgs)) + for i, c := range cfgs { + out[i] = c.CapabilityId + } + return out +} diff --git a/deployment/keystone/changeset/update_node_capabilities.go b/deployment/keystone/changeset/update_node_capabilities.go index 1d6dde6af5a..9c9d5585fc2 100644 --- a/deployment/keystone/changeset/update_node_capabilities.go +++ b/deployment/keystone/changeset/update_node_capabilities.go @@ -1,13 +1,16 @@ package changeset import ( - "encoding/json" "fmt" "strconv" + "github.com/ethereum/go-ethereum/common" chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" kslib "github.com/smartcontractkit/chainlink/deployment/keystone" "github.com/smartcontractkit/chainlink/deployment/keystone/changeset/internal" @@ -50,16 +53,14 @@ type UpdateNodeCapabilitiesRequest = MutateNodeCapabilitiesRequest // MutateNodeCapabilitiesRequest is a request to change the capabilities of nodes in the registry type MutateNodeCapabilitiesRequest struct { - AddressBook deployment.AddressBook - RegistryChainSel uint64 - + RegistryChainSel uint64 P2pToCapabilities map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability + + // MCMSConfig is optional. If non-nil, the changes will be proposed using MCMS. + MCMSConfig *MCMSConfig } func (req *MutateNodeCapabilitiesRequest) Validate() error { - if req.AddressBook == nil { - return fmt.Errorf("address book is nil") - } if len(req.P2pToCapabilities) == 0 { return fmt.Errorf("p2pToCapabilities is empty") } @@ -71,6 +72,10 @@ func (req *MutateNodeCapabilitiesRequest) Validate() error { return nil } +func (req *MutateNodeCapabilitiesRequest) UseMCMS() bool { + return req.MCMSConfig != nil +} + func (req *MutateNodeCapabilitiesRequest) updateNodeCapabilitiesImplRequest(e deployment.Environment) (*internal.UpdateNodeCapabilitiesImplRequest, error) { if err := req.Validate(); err != nil { return nil, fmt.Errorf("failed to validate UpdateNodeCapabilitiesRequest: %w", err) @@ -79,38 +84,61 @@ func (req *MutateNodeCapabilitiesRequest) updateNodeCapabilitiesImplRequest(e de if !ok { return nil, fmt.Errorf("registry chain selector %d does not exist in environment", req.RegistryChainSel) } - contracts, err := kslib.GetContractSets(e.Logger, &kslib.GetContractSetsRequest{ + resp, err := kslib.GetContractSets(e.Logger, &kslib.GetContractSetsRequest{ Chains: map[uint64]deployment.Chain{req.RegistryChainSel: registryChain}, - AddressBook: req.AddressBook, + AddressBook: e.ExistingAddresses, }) if err != nil { return nil, fmt.Errorf("failed to get contract sets: %w", err) } - registry := contracts.ContractSets[req.RegistryChainSel].CapabilitiesRegistry - if registry == nil { - return nil, fmt.Errorf("capabilities registry not found for chain %d", req.RegistryChainSel) + contractSet, exists := resp.ContractSets[req.RegistryChainSel] + if !exists { + return nil, fmt.Errorf("contract set not found for chain %d", req.RegistryChainSel) } return &internal.UpdateNodeCapabilitiesImplRequest{ Chain: registryChain, - Registry: registry, + ContractSet: &contractSet, P2pToCapabilities: req.P2pToCapabilities, + UseMCMS: req.UseMCMS(), }, nil } // UpdateNodeCapabilities updates the capabilities of nodes in the registry -func UpdateNodeCapabilities(env deployment.Environment, req *MutateNodeCapabilitiesRequest) (deployment.ChangesetOutput, error) { +func UpdateNodeCapabilities(env deployment.Environment, req *UpdateNodeCapabilitiesRequest) (deployment.ChangesetOutput, error) { c, err := req.updateNodeCapabilitiesImplRequest(env) if err != nil { return deployment.ChangesetOutput{}, fmt.Errorf("failed to convert request: %w", err) } r, err := internal.UpdateNodeCapabilitiesImpl(env.Logger, c) - if err == nil { - b, err2 := json.Marshal(r) - if err2 != nil { - env.Logger.Debugf("Updated node capabilities '%s'", b) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to update nodes: %w", err) + } + + out := deployment.ChangesetOutput{} + if req.UseMCMS() { + if r.Ops == nil { + return out, fmt.Errorf("expected MCMS operation to be non-nil") + } + timelocksPerChain := map[uint64]common.Address{ + c.Chain.Selector: c.ContractSet.Timelock.Address(), + } + proposerMCMSes := map[uint64]*gethwrappers.ManyChainMultiSig{ + c.Chain.Selector: c.ContractSet.ProposerMcm, + } + + proposal, err := proposalutils.BuildProposalFromBatches( + timelocksPerChain, + proposerMCMSes, + []timelock.BatchChainOperation{*r.Ops}, + "proposal to set update node capabilities", + req.MCMSConfig.MinDuration, + ) + if err != nil { + return out, fmt.Errorf("failed to build proposal: %w", err) } + out.Proposals = []timelock.MCMSWithTimelockProposal{*proposal} } - return deployment.ChangesetOutput{}, err + return out, nil } diff --git a/deployment/keystone/changeset/update_node_capabilities_test.go b/deployment/keystone/changeset/update_node_capabilities_test.go new file mode 100644 index 00000000000..87b49acf614 --- /dev/null +++ b/deployment/keystone/changeset/update_node_capabilities_test.go @@ -0,0 +1,207 @@ +package changeset_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/exp/maps" + + commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" + "github.com/smartcontractkit/chainlink/deployment/keystone/changeset" + kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" +) + +func TestUpdateNodeCapabilities(t *testing.T) { + t.Parallel() + + var ( + capA = kcr.CapabilitiesRegistryCapability{ + LabelledName: "capA", + Version: "0.4.2", + } + capB = kcr.CapabilitiesRegistryCapability{ + LabelledName: "capB", + Version: "3.16.0", + } + caps = []kcr.CapabilitiesRegistryCapability{capA, capB} + ) + t.Run("no mcms", func(t *testing.T) { + te := SetupTestEnv(t, TestConfig{ + WFDonConfig: DonConfig{N: 4}, + AssetDonConfig: DonConfig{N: 4}, + WriterDonConfig: DonConfig{N: 4}, + NumChains: 1, + }) + + // contract set is already deployed with capabilities + // we have to keep track of the existing capabilities to add to the new ones + var p2pIDs []p2pkey.PeerID + newCapabilities := make(map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability) + for id, _ := range te.WFNodes { + k, err := p2pkey.MakePeerID(id) + require.NoError(t, err) + p2pIDs = append(p2pIDs, k) + newCapabilities[k] = caps + } + + t.Run("fails if update drops existing capabilities", func(t *testing.T) { + + cfg := changeset.UpdateNodeCapabilitiesRequest{ + RegistryChainSel: te.RegistrySelector, + P2pToCapabilities: newCapabilities, + } + + _, err := changeset.UpdateNodeCapabilities(te.Env, &cfg) + require.Error(t, err) + assert.Contains(t, err.Error(), "CapabilityRequiredByDON") + }) + t.Run("succeeds if update sets new and existing capabilities", func(t *testing.T) { + existing := getNodeCapabilities(te.ContractSets()[te.RegistrySelector].CapabilitiesRegistry, p2pIDs) + + capabiltiesToSet := existing + for k, v := range newCapabilities { + capabiltiesToSet[k] = append(capabiltiesToSet[k], v...) + } + cfg := changeset.UpdateNodeCapabilitiesRequest{ + RegistryChainSel: te.RegistrySelector, + P2pToCapabilities: capabiltiesToSet, + } + + csOut, err := changeset.UpdateNodeCapabilities(te.Env, &cfg) + require.NoError(t, err) + require.Len(t, csOut.Proposals, 0) + require.Nil(t, csOut.AddressBook) + + validateCapabilityUpdates(t, te, capabiltiesToSet) + }) + }) + t.Run("with mcms", func(t *testing.T) { + te := SetupTestEnv(t, TestConfig{ + WFDonConfig: DonConfig{N: 4}, + AssetDonConfig: DonConfig{N: 4}, + WriterDonConfig: DonConfig{N: 4}, + NumChains: 1, + UseMCMS: true, + }) + + // contract set is already deployed with capabilities + // we have to keep track of the existing capabilities to add to the new ones + var p2pIDs []p2pkey.PeerID + newCapabilities := make(map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability) + for id, _ := range te.WFNodes { + k, err := p2pkey.MakePeerID(id) + require.NoError(t, err) + p2pIDs = append(p2pIDs, k) + newCapabilities[k] = caps + } + + existing := getNodeCapabilities(te.ContractSets()[te.RegistrySelector].CapabilitiesRegistry, p2pIDs) + + capabiltiesToSet := existing + for k, v := range newCapabilities { + capabiltiesToSet[k] = append(capabiltiesToSet[k], v...) + } + cfg := changeset.UpdateNodeCapabilitiesRequest{ + RegistryChainSel: te.RegistrySelector, + P2pToCapabilities: capabiltiesToSet, + MCMSConfig: &changeset.MCMSConfig{MinDuration: 0}, + } + + csOut, err := changeset.UpdateNodeCapabilities(te.Env, &cfg) + require.NoError(t, err) + require.Len(t, csOut.Proposals, 1) + require.Len(t, csOut.Proposals[0].Transactions, 1) + require.Len(t, csOut.Proposals[0].Transactions[0].Batch, 2) // add capabilities, update nodes + require.Nil(t, csOut.AddressBook) + + // now apply the changeset such that the proposal is signed and execed + contracts := te.ContractSets()[te.RegistrySelector] + timelockContracts := map[uint64]*proposalutils.TimelockExecutionContracts{ + te.RegistrySelector: { + Timelock: contracts.Timelock, + CallProxy: contracts.CallProxy, + }, + } + + _, err = commonchangeset.ApplyChangesets(t, te.Env, timelockContracts, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(changeset.UpdateNodeCapabilities), + Config: &cfg, + }, + }) + require.NoError(t, err) + validateCapabilityUpdates(t, te, capabiltiesToSet) + + }) + +} + +// validateUpdate checks reads nodes from the registry and checks they have the expected updates +func validateCapabilityUpdates(t *testing.T, te TestEnv, expected map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability) { + registry := te.ContractSets()[te.RegistrySelector].CapabilitiesRegistry + wfP2PIDs := p2pIDs(t, maps.Keys(te.WFNodes)) + nodes, err := registry.GetNodesByP2PIds(nil, wfP2PIDs) + require.NoError(t, err) + require.Len(t, nodes, len(wfP2PIDs)) + for _, node := range nodes { + want := expected[node.P2pId] + require.NotNil(t, want) + assertEqualCapabilities(t, registry, want, node) + } +} + +func assertEqualCapabilities(t *testing.T, registry *kcr.CapabilitiesRegistry, want []kcr.CapabilitiesRegistryCapability, got kcr.INodeInfoProviderNodeInfo) { + wantHashes := make([][32]byte, len(want)) + for i, c := range want { + h, err := registry.GetHashedCapabilityId(nil, c.LabelledName, c.Version) + require.NoError(t, err) + wantHashes[i] = h + } + assert.Equal(t, len(want), len(got.HashedCapabilityIds)) + assert.ElementsMatch(t, wantHashes, got.HashedCapabilityIds) +} + +func getNodeCapabilities(registry *kcr.CapabilitiesRegistry, p2pIDs []p2pkey.PeerID) map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability { + m := make(map[p2pkey.PeerID][]kcr.CapabilitiesRegistryCapability) + caps, err := registry.GetCapabilities(nil) + if err != nil { + panic(err) + } + var capMap = make(map[[32]byte]kcr.CapabilitiesRegistryCapability) + for _, c := range caps { + capMap[c.HashedId] = kcr.CapabilitiesRegistryCapability{ + LabelledName: c.LabelledName, + Version: c.Version, + CapabilityType: c.CapabilityType, + ResponseType: c.ResponseType, + ConfigurationContract: c.ConfigurationContract, + } + } + nodes, err := registry.GetNodesByP2PIds(nil, peerIDsToBytes(p2pIDs)) + if err != nil { + panic(err) + } + for _, n := range nodes { + caps := make([]kcr.CapabilitiesRegistryCapability, len(n.HashedCapabilityIds)) + for i, h := range n.HashedCapabilityIds { + c, ok := capMap[h] + if !ok { + panic("capability not found") + } + caps[i] = c + } + m[n.P2pId] = caps + } + return m +} + +func peerIDsToBytes(p2pIDs []p2pkey.PeerID) [][32]byte { + bs := make([][32]byte, len(p2pIDs)) + for i, p := range p2pIDs { + bs[i] = p + } + return bs +} diff --git a/deployment/keystone/changeset/update_nodes.go b/deployment/keystone/changeset/update_nodes.go index 7e436160d2e..bb12f32cb94 100644 --- a/deployment/keystone/changeset/update_nodes.go +++ b/deployment/keystone/changeset/update_nodes.go @@ -2,23 +2,100 @@ package changeset import ( "fmt" + "time" + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" + + kslib "github.com/smartcontractkit/chainlink/deployment/keystone" "github.com/smartcontractkit/chainlink/deployment/keystone/changeset/internal" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" ) +type MCMSConfig struct { + MinDuration time.Duration +} + var _ deployment.ChangeSet[*UpdateNodesRequest] = UpdateNodes -type UpdateNodesRequest = internal.UpdateNodesRequest +type UpdateNodesRequest struct { + RegistryChainSel uint64 + P2pToUpdates map[p2pkey.PeerID]NodeUpdate + + // MCMSConfig is optional. If non-nil, the changes will be proposed using MCMS. + MCMSConfig *MCMSConfig +} + +func (r *UpdateNodesRequest) Validate() error { + if r.P2pToUpdates == nil { + return fmt.Errorf("P2pToUpdates must be non-nil") + } + return nil +} + +func (r UpdateNodesRequest) UseMCMS() bool { + return r.MCMSConfig != nil +} + type NodeUpdate = internal.NodeUpdate // UpdateNodes updates the a set of nodes. -// This a complex action in practice that involves registering missing capabilities, adding the nodes, and updating -// the capabilities of the DON +// The nodes and capabilities in the request must already exist in the registry contract. func UpdateNodes(env deployment.Environment, req *UpdateNodesRequest) (deployment.ChangesetOutput, error) { - _, err := internal.UpdateNodes(env.Logger, req) + // extract the registry contract and chain from the environment + registryChain, ok := env.Chains[req.RegistryChainSel] + if !ok { + return deployment.ChangesetOutput{}, fmt.Errorf("registry chain selector %d does not exist in environment", req.RegistryChainSel) + } + cresp, err := kslib.GetContractSets(env.Logger, &kslib.GetContractSetsRequest{ + Chains: env.Chains, + AddressBook: env.ExistingAddresses, + }) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to get contract sets: %w", err) + } + contracts, exists := cresp.ContractSets[req.RegistryChainSel] + if !exists { + return deployment.ChangesetOutput{}, fmt.Errorf("contract set not found for chain %d", req.RegistryChainSel) + } + + resp, err := internal.UpdateNodes(env.Logger, &internal.UpdateNodesRequest{ + Chain: registryChain, + ContractSet: &contracts, + P2pToUpdates: req.P2pToUpdates, + UseMCMS: req.UseMCMS(), + }) if err != nil { return deployment.ChangesetOutput{}, fmt.Errorf("failed to update don: %w", err) } - return deployment.ChangesetOutput{}, nil + + out := deployment.ChangesetOutput{} + if req.UseMCMS() { + if resp.Ops == nil { + return out, fmt.Errorf("expected MCMS operation to be non-nil") + } + timelocksPerChain := map[uint64]common.Address{ + req.RegistryChainSel: contracts.Timelock.Address(), + } + proposerMCMSes := map[uint64]*gethwrappers.ManyChainMultiSig{ + req.RegistryChainSel: contracts.ProposerMcm, + } + + proposal, err := proposalutils.BuildProposalFromBatches( + timelocksPerChain, + proposerMCMSes, + []timelock.BatchChainOperation{*resp.Ops}, + "proposal to set update nodes", + req.MCMSConfig.MinDuration, + ) + if err != nil { + return out, fmt.Errorf("failed to build proposal: %w", err) + } + out.Proposals = []timelock.MCMSWithTimelockProposal{*proposal} + } + + return out, nil } diff --git a/deployment/keystone/changeset/update_nodes_test.go b/deployment/keystone/changeset/update_nodes_test.go new file mode 100644 index 00000000000..31f71cd9603 --- /dev/null +++ b/deployment/keystone/changeset/update_nodes_test.go @@ -0,0 +1,128 @@ +package changeset_test + +import ( + "encoding/hex" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/exp/maps" + + commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" + "github.com/smartcontractkit/chainlink/deployment/keystone/changeset" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" +) + +func TestUpdateNodes(t *testing.T) { + t.Parallel() + + t.Run("no mcms", func(t *testing.T) { + te := SetupTestEnv(t, TestConfig{ + WFDonConfig: DonConfig{N: 4}, + AssetDonConfig: DonConfig{N: 4}, + WriterDonConfig: DonConfig{N: 4}, + NumChains: 1, + }) + + updates := make(map[p2pkey.PeerID]changeset.NodeUpdate) + i := uint8(0) + for id, _ := range te.WFNodes { + k, err := p2pkey.MakePeerID(id) + require.NoError(t, err) + pubKey := [32]byte{31: i + 1} + // don't set capabilities or nop b/c those must already exist in the contract + // those ops must be a different proposal when using MCMS + updates[k] = changeset.NodeUpdate{ + EncryptionPublicKey: hex.EncodeToString(pubKey[:]), + Signer: [32]byte{0: i + 1}, + } + i++ + } + + cfg := changeset.UpdateNodesRequest{ + RegistryChainSel: te.RegistrySelector, + P2pToUpdates: updates, + } + + csOut, err := changeset.UpdateNodes(te.Env, &cfg) + require.NoError(t, err) + require.Len(t, csOut.Proposals, 0) + require.Nil(t, csOut.AddressBook) + + validateUpdate(t, te, updates) + }) + + t.Run("with mcms", func(t *testing.T) { + te := SetupTestEnv(t, TestConfig{ + WFDonConfig: DonConfig{N: 4}, + AssetDonConfig: DonConfig{N: 4}, + WriterDonConfig: DonConfig{N: 4}, + NumChains: 1, + UseMCMS: true, + }) + + updates := make(map[p2pkey.PeerID]changeset.NodeUpdate) + i := uint8(0) + for id, _ := range te.WFNodes { + k, err := p2pkey.MakePeerID(id) + require.NoError(t, err) + pubKey := [32]byte{31: i + 1} + // don't set capabilities or nop b/c those must already exist in the contract + // those ops must be a different proposal when using MCMS + updates[k] = changeset.NodeUpdate{ + EncryptionPublicKey: hex.EncodeToString(pubKey[:]), + Signer: [32]byte{0: i + 1}, + } + i++ + } + + cfg := changeset.UpdateNodesRequest{ + RegistryChainSel: te.RegistrySelector, + P2pToUpdates: updates, + MCMSConfig: &changeset.MCMSConfig{MinDuration: 0}, + } + + csOut, err := changeset.UpdateNodes(te.Env, &cfg) + require.NoError(t, err) + require.Len(t, csOut.Proposals, 1) + require.Nil(t, csOut.AddressBook) + + // now apply the changeset such that the proposal is signed and execed + contracts := te.ContractSets()[te.RegistrySelector] + timelockContracts := map[uint64]*proposalutils.TimelockExecutionContracts{ + te.RegistrySelector: { + Timelock: contracts.Timelock, + CallProxy: contracts.CallProxy, + }, + } + _, err = commonchangeset.ApplyChangesets(t, te.Env, timelockContracts, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(changeset.UpdateNodes), + Config: &changeset.UpdateNodesRequest{ + RegistryChainSel: te.RegistrySelector, + P2pToUpdates: updates, + MCMSConfig: &changeset.MCMSConfig{MinDuration: 0}, + }, + }, + }) + require.NoError(t, err) + + validateUpdate(t, te, updates) + }) + +} + +// validateUpdate checks reads nodes from the registry and checks they have the expected updates +func validateUpdate(t *testing.T, te TestEnv, expected map[p2pkey.PeerID]changeset.NodeUpdate) { + registry := te.ContractSets()[te.RegistrySelector].CapabilitiesRegistry + wfP2PIDs := p2pIDs(t, maps.Keys(te.WFNodes)) + nodes, err := registry.GetNodesByP2PIds(nil, wfP2PIDs) + require.NoError(t, err) + require.Len(t, nodes, len(wfP2PIDs)) + for _, node := range nodes { + // only check the fields that were updated + assert.Equal(t, expected[node.P2pId].EncryptionPublicKey, hex.EncodeToString(node.EncryptionPublicKey[:])) + assert.Equal(t, expected[node.P2pId].Signer, node.Signer) + } +} diff --git a/deployment/keystone/deploy.go b/deployment/keystone/deploy.go index 9bd291e9c1e..7d3e5391219 100644 --- a/deployment/keystone/deploy.go +++ b/deployment/keystone/deploy.go @@ -14,16 +14,12 @@ import ( "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/rpc" "golang.org/x/exp/maps" - "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" - "github.com/smartcontractkit/chainlink/deployment" - "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/durationpb" @@ -170,7 +166,7 @@ func DonInfos(dons []DonCapabilities, jd deployment.OffchainClient) ([]DonInfo, return donInfos, nil } -func GetRegistryContract(e *deployment.Environment, registryChainSel uint64, addrBook deployment.AddressBook) (*kcr.CapabilitiesRegistry, deployment.Chain, error) { +func GetRegistryContract(e *deployment.Environment, registryChainSel uint64) (*kcr.CapabilitiesRegistry, deployment.Chain, error) { registryChain, ok := e.Chains[registryChainSel] if !ok { return nil, deployment.Chain{}, fmt.Errorf("chain %d not found in environment", registryChainSel) @@ -178,7 +174,7 @@ func GetRegistryContract(e *deployment.Environment, registryChainSel uint64, add contractSetsResp, err := GetContractSets(e.Logger, &GetContractSetsRequest{ Chains: e.Chains, - AddressBook: addrBook, + AddressBook: e.ExistingAddresses, }) if err != nil { return nil, deployment.Chain{}, fmt.Errorf("failed to get contract sets: %w", err) @@ -349,7 +345,7 @@ func ConfigureOCR3Contract(env *deployment.Environment, chainSel uint64, dons [] type ConfigureOCR3Resp struct { OCR2OracleConfig - Proposal *timelock.MCMSWithTimelockProposal + Ops *timelock.BatchChainOperation } type ConfigureOCR3Config struct { @@ -406,7 +402,7 @@ func ConfigureOCR3ContractFromJD(env *deployment.Environment, cfg ConfigureOCR3C } return &ConfigureOCR3Resp{ OCR2OracleConfig: r.ocrConfig, - Proposal: r.proposal, + Ops: r.ops, }, nil } @@ -427,7 +423,7 @@ type RegisteredCapability struct { } func FromCapabilitiesRegistryCapability(cap *kcr.CapabilitiesRegistryCapability, e deployment.Environment, registryChainSelector uint64) (*RegisteredCapability, error) { - registry, _, err := GetRegistryContract(&e, registryChainSelector, e.ExistingAddresses) + registry, _, err := GetRegistryContract(&e, registryChainSelector) if err != nil { return nil, fmt.Errorf("failed to get registry: %w", err) } @@ -446,10 +442,14 @@ func RegisterCapabilities(lggr logger.Logger, req RegisterCapabilitiesRequest) ( if len(req.DonToCapabilities) == 0 { return nil, fmt.Errorf("no capabilities to register") } - registry, registryChain, err := GetRegistryContract(req.Env, req.RegistryChainSelector, req.Env.ExistingAddresses) - if err != nil { - return nil, fmt.Errorf("failed to get registry: %w", err) - } + cresp, err := GetContractSets(req.Env.Logger, &GetContractSetsRequest{ + Chains: req.Env.Chains, + AddressBook: req.Env.ExistingAddresses, + }) + contracts := cresp.ContractSets[req.RegistryChainSelector] + registry := contracts.CapabilitiesRegistry + registryChain := req.Env.Chains[req.RegistryChainSelector] + lggr.Infow("registering capabilities...", "len", len(req.DonToCapabilities)) resp := &RegisterCapabilitiesResponse{ DonToCapabilities: make(map[string][]RegisteredCapability), @@ -483,8 +483,8 @@ func RegisterCapabilities(lggr logger.Logger, req RegisterCapabilitiesRequest) ( for cap := range uniqueCaps { capabilities = append(capabilities, cap) } - - err = AddCapabilities(lggr, registry, registryChain, capabilities) + // not using mcms; ignore proposals + _, err = AddCapabilities(lggr, &contracts, registryChain, capabilities, false) if err != nil { return nil, fmt.Errorf("failed to add capabilities: %w", err) } @@ -502,7 +502,7 @@ type RegisterNOPSResponse struct { } func RegisterNOPS(ctx context.Context, lggr logger.Logger, req RegisterNOPSRequest) (*RegisterNOPSResponse, error) { - registry, registryChain, err := GetRegistryContract(req.Env, req.RegistryChainSelector, req.Env.ExistingAddresses) + registry, registryChain, err := GetRegistryContract(req.Env, req.RegistryChainSelector) if err != nil { return nil, fmt.Errorf("failed to get registry: %w", err) } @@ -641,7 +641,7 @@ type RegisterNodesResponse struct { // can sign the transactions update the contract state // TODO: 467 refactor to support MCMS. Specifically need to separate the call data generation from the actual contract call func RegisterNodes(lggr logger.Logger, req *RegisterNodesRequest) (*RegisterNodesResponse, error) { - registry, registryChain, err := GetRegistryContract(req.Env, req.RegistryChainSelector, req.Env.ExistingAddresses) + registry, registryChain, err := GetRegistryContract(req.Env, req.RegistryChainSelector) if err != nil { return nil, fmt.Errorf("failed to get registry: %w", err) } @@ -809,7 +809,7 @@ func sortedHash(p2pids [][32]byte) string { } func RegisterDons(lggr logger.Logger, req RegisterDonsRequest) (*RegisterDonsResponse, error) { - registry, registryChain, err := GetRegistryContract(req.Env, req.RegistryChainSelector, req.Env.ExistingAddresses) + registry, registryChain, err := GetRegistryContract(req.Env, req.RegistryChainSelector) if err != nil { return nil, fmt.Errorf("failed to get registry: %w", err) } @@ -938,13 +938,13 @@ func containsAllDONs(donInfos []kcr.CapabilitiesRegistryDONInfo, p2pIdsToDon map // configureForwarder sets the config for the forwarder contract on the chain for all Dons that accept workflows // dons that don't accept workflows are not registered with the forwarder -func configureForwarder(lggr logger.Logger, chain deployment.Chain, contractSet ContractSet, dons []RegisteredDon, useMCMS bool) ([]timelock.MCMSWithTimelockProposal, error) { +func configureForwarder(lggr logger.Logger, chain deployment.Chain, contractSet ContractSet, dons []RegisteredDon, useMCMS bool) (map[uint64]timelock.BatchChainOperation, error) { if contractSet.Forwarder == nil { return nil, errors.New("nil forwarder contract") } var ( - fwdr = contractSet.Forwarder - proposals []timelock.MCMSWithTimelockProposal + fwdr = contractSet.Forwarder + opMap = make(map[uint64]timelock.BatchChainOperation) ) for _, dn := range dons { if !dn.Info.AcceptsWorkflows { @@ -979,26 +979,9 @@ func configureForwarder(lggr logger.Logger, chain deployment.Chain, contractSet }, }, } - timelocksPerChain := map[uint64]common.Address{ - chain.Selector: contractSet.Timelock.Address(), - } - proposerMCMSes := map[uint64]*gethwrappers.ManyChainMultiSig{ - chain.Selector: contractSet.ProposerMcm, - } - - proposal, err := proposalutils.BuildProposalFromBatches( - timelocksPerChain, - proposerMCMSes, - []timelock.BatchChainOperation{ops}, - "proposal to set forward config", - 0, - ) - if err != nil { - return nil, fmt.Errorf("failed to build proposal: %w", err) - } - proposals = append(proposals, *proposal) + opMap[chain.Selector] = ops } lggr.Debugw("configured forwarder", "forwarder", fwdr.Address().String(), "donId", dn.Info.Id, "version", ver, "f", dn.Info.F, "signers", signers) } - return proposals, nil + return opMap, nil } diff --git a/deployment/keystone/forwarder_deployer.go b/deployment/keystone/forwarder_deployer.go index d7cfa7991f4..7c7b3a1ed93 100644 --- a/deployment/keystone/forwarder_deployer.go +++ b/deployment/keystone/forwarder_deployer.go @@ -64,7 +64,7 @@ type ConfigureForwarderContractsRequest struct { UseMCMS bool } type ConfigureForwarderContractsResponse struct { - Proposals []timelock.MCMSWithTimelockProposal + OpsPerChain map[uint64]timelock.BatchChainOperation } // Depreciated: use [changeset.ConfigureForwarders] instead @@ -79,7 +79,7 @@ func ConfigureForwardContracts(env *deployment.Environment, req ConfigureForward return nil, fmt.Errorf("failed to get contract sets: %w", err) } - var allProposals []timelock.MCMSWithTimelockProposal + opPerChain := make(map[uint64]timelock.BatchChainOperation) // configure forwarders on all chains for _, chain := range env.Chains { // get the forwarder contract for the chain @@ -87,13 +87,15 @@ func ConfigureForwardContracts(env *deployment.Environment, req ConfigureForward if !ok { return nil, fmt.Errorf("failed to get contract set for chain %d", chain.Selector) } - proposals, err := configureForwarder(env.Logger, chain, contracts, req.Dons, req.UseMCMS) + ops, err := configureForwarder(env.Logger, chain, contracts, req.Dons, req.UseMCMS) if err != nil { return nil, fmt.Errorf("failed to configure forwarder for chain selector %d: %w", chain.Selector, err) } - allProposals = append(allProposals, proposals...) + for k, op := range ops { + opPerChain[k] = op + } } return &ConfigureForwarderContractsResponse{ - Proposals: allProposals, + OpsPerChain: opPerChain, }, nil } diff --git a/deployment/keystone/ocr3config.go b/deployment/keystone/ocr3config.go index ccd738636ed..aed142ea116 100644 --- a/deployment/keystone/ocr3config.go +++ b/deployment/keystone/ocr3config.go @@ -18,12 +18,10 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink/deployment" - "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" kocr3 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/ocr3_capability" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" @@ -300,7 +298,7 @@ func (r configureOCR3Request) generateOCR3Config() (OCR2OracleConfig, error) { type configureOCR3Response struct { ocrConfig OCR2OracleConfig - proposal *timelock.MCMSWithTimelockProposal + ops *timelock.BatchChainOperation } func configureOCR3contract(req configureOCR3Request) (*configureOCR3Response, error) { @@ -333,7 +331,7 @@ func configureOCR3contract(req configureOCR3Request) (*configureOCR3Response, er return nil, fmt.Errorf("failed to call SetConfig for OCR3 contract %s using mcms: %T: %w", req.contract.Address().String(), req.useMCMS, err) } - var proposal *timelock.MCMSWithTimelockProposal + var ops *timelock.BatchChainOperation if !req.useMCMS { _, err = req.chain.Confirm(tx) if err != nil { @@ -341,7 +339,7 @@ func configureOCR3contract(req configureOCR3Request) (*configureOCR3Response, er return nil, fmt.Errorf("failed to confirm SetConfig for OCR3 contract %s: %w", req.contract.Address().String(), err) } } else { - ops := timelock.BatchChainOperation{ + ops = &timelock.BatchChainOperation{ ChainIdentifier: mcms.ChainIdentifier(req.chain.Selector), Batch: []mcms.Operation{ { @@ -351,24 +349,7 @@ func configureOCR3contract(req configureOCR3Request) (*configureOCR3Response, er }, }, } - timelocksPerChain := map[uint64]common.Address{ - req.chain.Selector: req.contractSet.Timelock.Address(), - } - proposerMCMSes := map[uint64]*gethwrappers.ManyChainMultiSig{ - req.chain.Selector: req.contractSet.ProposerMcm, - } - - proposal, err = proposalutils.BuildProposalFromBatches( - timelocksPerChain, - proposerMCMSes, - []timelock.BatchChainOperation{ops}, - "proposal to set ocr3 config", - 0, - ) - if err != nil { - return nil, fmt.Errorf("failed to build proposal: %w", err) - } } - return &configureOCR3Response{ocrConfig, proposal}, nil + return &configureOCR3Response{ocrConfig, ops}, nil } diff --git a/deployment/solana_chain.go b/deployment/solana_chain.go new file mode 100644 index 00000000000..338642e3e32 --- /dev/null +++ b/deployment/solana_chain.go @@ -0,0 +1,5 @@ +package deployment + +// SolChain represents a Solana chain. +type SolChain struct { +} diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 52276f027bc..946703695eb 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -5902,6 +5902,214 @@ GasLimitDefault = 400000

+
Ronin Mainnet (2020)

+ +```toml +AutoCreateKey = true +BlockBackfillDepth = 10 +BlockBackfillSkip = false +FinalityDepth = 50 +FinalityTagEnabled = true +LinkContractAddress = '0x3902228D6A3d2Dc44731fD9d45FeE6a61c722D0b' +LogBackfillBatchSize = 1000 +LogPollInterval = '3s' +LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 +BackupLogPollerBlockDelay = 100 +MinIncomingConfirmations = 3 +MinContractPayment = '0.00001 link' +NonceAutoSync = true +NoNewHeadsThreshold = '3m0s' +LogBroadcasterEnabled = true +RPCDefaultBatchSize = 250 +RPCBlockQueryDelay = 1 +FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' + +[Transactions] +ForwardersEnabled = false +MaxInFlight = 16 +MaxQueued = 250 +ReaperInterval = '1h0m0s' +ReaperThreshold = '168h0m0s' +ResendAfterThreshold = '1m0s' + +[Transactions.AutoPurge] +Enabled = false + +[BalanceMonitor] +Enabled = true + +[GasEstimator] +Mode = 'FeeHistory' +PriceDefault = '20 gwei' +PriceMax = '1 micro' +PriceMin = '1 gwei' +LimitDefault = 500000 +LimitMax = 500000 +LimitMultiplier = '1' +LimitTransfer = 21000 +EstimateLimit = false +BumpMin = '5 gwei' +BumpPercent = 20 +BumpThreshold = 3 +EIP1559DynamicFees = false +FeeCapDefault = '100 gwei' +TipCapDefault = '1 wei' +TipCapMin = '1 wei' + +[GasEstimator.BlockHistory] +BatchSize = 25 +BlockHistorySize = 8 +CheckInclusionBlocks = 12 +CheckInclusionPercentile = 90 +TransactionPercentile = 60 + +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + +[HeadTracker] +HistoryDepth = 100 +MaxBufferSize = 3 +SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true +PersistenceEnabled = true + +[NodePool] +PollFailureThreshold = 5 +PollInterval = '10s' +SelectionMode = 'HighestHead' +SyncThreshold = 5 +LeaseDuration = '0s' +NodeIsSyncingEnabled = false +FinalizedBlockPollInterval = '5s' +EnforceRepeatableRead = true +DeathDeclarationDelay = '1m0s' +NewHeadsPollInterval = '0s' + +[OCR] +ContractConfirmations = 4 +ContractTransmitterTransmitTimeout = '10s' +DatabaseTimeout = '10s' +DeltaCOverride = '168h0m0s' +DeltaCJitterOverride = '1h0m0s' +ObservationGracePeriod = '1s' + +[OCR2] +[OCR2.Automation] +GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 +``` + +

+ +
Ronin Saigon (2021)

+ +```toml +AutoCreateKey = true +BlockBackfillDepth = 10 +BlockBackfillSkip = false +FinalityDepth = 50 +FinalityTagEnabled = true +LinkContractAddress = '0x5bB50A6888ee6a67E22afFDFD9513be7740F1c15' +LogBackfillBatchSize = 1000 +LogPollInterval = '3s' +LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 +BackupLogPollerBlockDelay = 100 +MinIncomingConfirmations = 3 +MinContractPayment = '0.00001 link' +NonceAutoSync = true +NoNewHeadsThreshold = '3m0s' +LogBroadcasterEnabled = true +RPCDefaultBatchSize = 250 +RPCBlockQueryDelay = 1 +FinalizedBlockOffset = 0 +NoNewFinalizedHeadsThreshold = '0s' + +[Transactions] +ForwardersEnabled = false +MaxInFlight = 16 +MaxQueued = 250 +ReaperInterval = '1h0m0s' +ReaperThreshold = '168h0m0s' +ResendAfterThreshold = '1m0s' + +[Transactions.AutoPurge] +Enabled = false + +[BalanceMonitor] +Enabled = true + +[GasEstimator] +Mode = 'FeeHistory' +PriceDefault = '20 gwei' +PriceMax = '1 micro' +PriceMin = '1 gwei' +LimitDefault = 500000 +LimitMax = 500000 +LimitMultiplier = '1' +LimitTransfer = 21000 +EstimateLimit = false +BumpMin = '5 gwei' +BumpPercent = 20 +BumpThreshold = 3 +EIP1559DynamicFees = false +FeeCapDefault = '100 gwei' +TipCapDefault = '1 wei' +TipCapMin = '1 wei' + +[GasEstimator.BlockHistory] +BatchSize = 25 +BlockHistorySize = 8 +CheckInclusionBlocks = 12 +CheckInclusionPercentile = 90 +TransactionPercentile = 60 + +[GasEstimator.FeeHistory] +CacheTimeout = '10s' + +[HeadTracker] +HistoryDepth = 100 +MaxBufferSize = 3 +SamplingInterval = '1s' +MaxAllowedFinalityDepth = 10000 +FinalityTagBypass = true +PersistenceEnabled = true + +[NodePool] +PollFailureThreshold = 5 +PollInterval = '10s' +SelectionMode = 'HighestHead' +SyncThreshold = 5 +LeaseDuration = '0s' +NodeIsSyncingEnabled = false +FinalizedBlockPollInterval = '5s' +EnforceRepeatableRead = true +DeathDeclarationDelay = '1m0s' +NewHeadsPollInterval = '0s' + +[OCR] +ContractConfirmations = 4 +ContractTransmitterTransmitTimeout = '10s' +DatabaseTimeout = '10s' +DeltaCOverride = '168h0m0s' +DeltaCJitterOverride = '1h0m0s' +ObservationGracePeriod = '1s' + +[OCR2] +[OCR2.Automation] +GasLimit = 5400000 + +[Workflow] +GasLimitDefault = 400000 +``` + +

+
Kroma Sepolia (2358)

```toml diff --git a/go.mod b/go.mod index 35069d38bbf..0f8a161768f 100644 --- a/go.mod +++ b/go.mod @@ -78,13 +78,13 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.34 github.com/smartcontractkit/chainlink-automation v0.8.1 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f + github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0 + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db github.com/smartcontractkit/chainlink-feeds v0.1.1 github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2 - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241204153209-c3a71b0eef99 + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8 github.com/smartcontractkit/libocr v0.0.0-20241007185508-adbe57025f12 github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20241009055228-33d0c0bf38de diff --git a/go.sum b/go.sum index caa877d66fa..76127a91b4b 100644 --- a/go.sum +++ b/go.sum @@ -1123,10 +1123,10 @@ github.com/smartcontractkit/chain-selectors v1.0.34 h1:MJ17OGu8+jjl426pcKrJkCf3f github.com/smartcontractkit/chain-selectors v1.0.34/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e h1:GnM6ZWV6vlk2+n6c6o+v/R1LtXzBGVVx7r37nt/h6Uc= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e/go.mod h1:80vGBbOfertJig0xFKsRfm+i17FkjdKkk1dAaGE45Os= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f h1:hH+cAG2zt+WK4I2m572LXAnAJg3wtGEAwzBKR8FiXo8= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0 h1:/1L+v4SxUD2K5RMRbfByyLfePMAgQKeD0onSetPnGmA= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 h1:ZA92CTX9JtEArrxgZw7PNctVxFS+/DmSXumkwf1WiMY= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e/go.mod h1:mUh5/woemsVaHgTorA080hrYmO3syBCmPdnWc/5dOqk= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db h1:N1RH1hSr2ACzOFc9hkCcjE8pRBTdcU3p8nsTJByaLes= @@ -1135,8 +1135,8 @@ github.com/smartcontractkit/chainlink-feeds v0.1.1 h1:JzvUOM/OgGQA1sOqTXXl52R6An github.com/smartcontractkit/chainlink-feeds v0.1.1/go.mod h1:55EZ94HlKCfAsUiKUTNI7QlE/3d3IwTlsU3YNa/nBb4= github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2 h1:onBe3DqNrbtOAzKS4PrPIiJX65BGo1aYiYZxFVEW+jc= github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2/go.mod h1:m/A3lqD7ms/RsQ9BT5P2uceYY0QX5mIt4KQxT2G6qEo= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241204153209-c3a71b0eef99 h1:lvn9Yxah+QD1/PcgijLO0dNRa28HuQWZl8Kkxh46KJc= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241204153209-c3a71b0eef99/go.mod h1:p8aUDfJeley6oer7y+Ucd3edOtRlMTnWg3mN6rhaLWo= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc h1:dssRwJhmzJkUN/OajaDj2GsxBn+Tupk3bI1BkPEoJg0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc/go.mod h1:p8aUDfJeley6oer7y+Ucd3edOtRlMTnWg3mN6rhaLWo= github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8 h1:tNS7U9lrxkFvEuyxQv11HHOiV9LPDGC9wYEy+yM/Jv4= github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8/go.mod h1:EBrEgcdIbwepqguClkv8Ohy7CbyWSJaE4EC9aBJlQK0= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= diff --git a/integration-tests/ccip-tests/contracts/contract_deployer.go b/integration-tests/ccip-tests/contracts/contract_deployer.go index c97e7bbc0aa..1f2859ae0db 100644 --- a/integration-tests/ccip-tests/contracts/contract_deployer.go +++ b/integration-tests/ccip-tests/contracts/contract_deployer.go @@ -57,7 +57,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers/testhelpers_1_4_0" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" ) @@ -1415,16 +1414,6 @@ func NewCommitOffchainConfig( InflightCacheExpiry, priceReportingDisabled, ), nil - case V1_2_0: - return testhelpers_1_4_0.NewCommitOffchainConfig( - GasPriceHeartBeat, - DAGasPriceDeviationPPB, - ExecGasPriceDeviationPPB, - TokenPriceHeartBeat, - TokenPriceDeviationPPB, - InflightCacheExpiry, - priceReportingDisabled, - ), nil default: return nil, fmt.Errorf("version not supported: %s", VersionMap[CommitStoreContract]) } @@ -1436,8 +1425,6 @@ func NewCommitOnchainConfig( switch VersionMap[CommitStoreContract] { case Latest: return testhelpers.NewCommitOnchainConfig(PriceRegistry), nil - case V1_2_0: - return testhelpers_1_4_0.NewCommitOnchainConfig(PriceRegistry), nil default: return nil, fmt.Errorf("version not supported: %s", VersionMap[CommitStoreContract]) } @@ -1454,15 +1441,6 @@ func NewExecOnchainConfig( switch VersionMap[OffRampContract] { case Latest: return testhelpers.NewExecOnchainConfig(PermissionLessExecutionThresholdSeconds, Router, PriceRegistry, MaxNumberOfTokensPerMsg, MaxDataBytes), nil - case V1_2_0: - return testhelpers_1_4_0.NewExecOnchainConfig( - PermissionLessExecutionThresholdSeconds, - Router, - PriceRegistry, - MaxNumberOfTokensPerMsg, - MaxDataBytes, - MaxPoolReleaseOrMintGas, - ), nil default: return nil, fmt.Errorf("version not supported: %s", VersionMap[OffRampContract]) } @@ -1487,15 +1465,6 @@ func NewExecOffchainConfig( rootSnoozeTime, batchingStrategyID, ), nil - case V1_2_0: - return testhelpers_1_4_0.NewExecOffchainConfig( - destOptimisticConfirmations, - batchGasLimit, - relativeBoostPerWaitHour, - inflightCacheExpiry, - rootSnoozeTime, - batchingStrategyID, - ), nil default: return nil, fmt.Errorf("version not supported: %s", VersionMap[OffRampContract]) } diff --git a/integration-tests/ccip-tests/contracts/contract_models.go b/integration-tests/ccip-tests/contracts/contract_models.go index 376f70192d2..257670dbaa1 100644 --- a/integration-tests/ccip-tests/contracts/contract_models.go +++ b/integration-tests/ccip-tests/contracts/contract_models.go @@ -503,8 +503,13 @@ func (w TokenPoolWrapper) ApplyChainUpdates(opts *bind.TransactOpts, update []to } func (w TokenPoolWrapper) SetChainRateLimiterConfig(opts *bind.TransactOpts, selector uint64, out token_pool.RateLimiterConfig, in token_pool.RateLimiterConfig) (*types.Transaction, error) { + if w.Latest != nil && w.Latest.PoolInterface != nil { - return w.Latest.PoolInterface.SetChainRateLimiterConfig(opts, selector, out, in) + selectors := []uint64{selector} + out := []token_pool.RateLimiterConfig{out} + in := []token_pool.RateLimiterConfig{in} + + return w.Latest.PoolInterface.SetChainRateLimiterConfigs(opts, selectors, out, in) } if w.V1_4_0 != nil && w.V1_4_0.PoolInterface != nil { return w.V1_4_0.PoolInterface.SetChainRateLimiterConfig(opts, selector, diff --git a/integration-tests/ccip-tests/testconfig/README.md b/integration-tests/ccip-tests/testconfig/README.md index ff57ecaa220..d614ed62ea4 100644 --- a/integration-tests/ccip-tests/testconfig/README.md +++ b/integration-tests/ccip-tests/testconfig/README.md @@ -430,32 +430,6 @@ Example usage: TTL = "11h" ``` -### CCIP.Env.Logging - -Specifies the logging configuration for the test. Imported from [LoggingConfig](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/config/logging.go#L11) in chainlink-testing-framework. -Example usage: - -```toml -[CCIP.Env.Logging] -test_log_collect = false # if set to true will save logs even if test did not fail - -[CCIP.Env.Logging.LogStream] -# supported targets: file, loki, in-memory. if empty no logs will be persistet -log_targets = ["file"] -# context timeout for starting log producer and also time-frame for requesting logs -log_producer_timeout = "10s" -# number of retries before log producer gives up and stops listening to logs -log_producer_retry_limit = 10 - -[CCIP.Env.Logging.Loki] -tenant_id = "..." -endpoint = "https://loki...." - -[CCIP.Env.Logging.Grafana] -base_url = "https://grafana..../" -dashboard_url = "/d/6vjVx-1V8/ccip-long-running-tests" -``` - ### CCIP.Env.Lane.LeaderLaneEnabled Specifies whether to enable the leader lane feature. This setting is only applicable for new deployments. diff --git a/integration-tests/ccip-tests/testconfig/global.go b/integration-tests/ccip-tests/testconfig/global.go index 4caa8a9ac00..8866d31705a 100644 --- a/integration-tests/ccip-tests/testconfig/global.go +++ b/integration-tests/ccip-tests/testconfig/global.go @@ -175,120 +175,6 @@ type Common struct { func (p *Common) ReadFromEnvVar() error { logger := logging.GetTestLogger(nil) - testLogCollect := ctfconfig.MustReadEnvVar_Boolean(ctfconfig.E2E_TEST_LOG_COLLECT_ENV) - if testLogCollect != nil { - if p.Logging == nil { - p.Logging = &ctfconfig.LoggingConfig{} - } - logger.Debug().Msgf("Using %s env var to override Logging.TestLogCollect", ctfconfig.E2E_TEST_LOG_COLLECT_ENV) - p.Logging.TestLogCollect = testLogCollect - } - - loggingRunID := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_LOGGING_RUN_ID_ENV) - if loggingRunID != "" { - if p.Logging == nil { - p.Logging = &ctfconfig.LoggingConfig{} - } - logger.Debug().Msgf("Using %s env var to override Logging.RunID", ctfconfig.E2E_TEST_LOGGING_RUN_ID_ENV) - p.Logging.RunId = &loggingRunID - } - - logstreamLogTargets := ctfconfig.MustReadEnvVar_Strings(ctfconfig.E2E_TEST_LOG_STREAM_LOG_TARGETS_ENV, ",") - if len(logstreamLogTargets) > 0 { - if p.Logging == nil { - p.Logging = &ctfconfig.LoggingConfig{} - } - if p.Logging.LogStream == nil { - p.Logging.LogStream = &ctfconfig.LogStreamConfig{} - } - logger.Debug().Msgf("Using %s env var to override Logging.LogStream.LogTargets", ctfconfig.E2E_TEST_LOG_STREAM_LOG_TARGETS_ENV) - p.Logging.LogStream.LogTargets = logstreamLogTargets - } - - lokiTenantID := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_LOKI_TENANT_ID_ENV) - if lokiTenantID != "" { - if p.Logging == nil { - p.Logging = &ctfconfig.LoggingConfig{} - } - if p.Logging.Loki == nil { - p.Logging.Loki = &ctfconfig.LokiConfig{} - } - logger.Debug().Msgf("Using %s env var to override Logging.Loki.TenantId", ctfconfig.E2E_TEST_LOKI_TENANT_ID_ENV) - p.Logging.Loki.TenantId = &lokiTenantID - } - - lokiEndpoint := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_LOKI_ENDPOINT_ENV) - if lokiEndpoint != "" { - if p.Logging == nil { - p.Logging = &ctfconfig.LoggingConfig{} - } - if p.Logging.Loki == nil { - p.Logging.Loki = &ctfconfig.LokiConfig{} - } - logger.Debug().Msgf("Using %s env var to override Logging.Loki.Endpoint", ctfconfig.E2E_TEST_LOKI_ENDPOINT_ENV) - p.Logging.Loki.Endpoint = &lokiEndpoint - } - - lokiBasicAuth := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_LOKI_BASIC_AUTH_ENV) - if lokiBasicAuth != "" { - if p.Logging == nil { - p.Logging = &ctfconfig.LoggingConfig{} - } - if p.Logging.Loki == nil { - p.Logging.Loki = &ctfconfig.LokiConfig{} - } - logger.Debug().Msgf("Using %s env var to override Logging.Loki.BasicAuth", ctfconfig.E2E_TEST_LOKI_BASIC_AUTH_ENV) - p.Logging.Loki.BasicAuth = &lokiBasicAuth - } - - lokiBearerToken := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_LOKI_BEARER_TOKEN_ENV) - if lokiBearerToken != "" { - if p.Logging == nil { - p.Logging = &ctfconfig.LoggingConfig{} - } - if p.Logging.Loki == nil { - p.Logging.Loki = &ctfconfig.LokiConfig{} - } - logger.Debug().Msgf("Using %s env var to override Logging.Loki.BearerToken", ctfconfig.E2E_TEST_LOKI_BEARER_TOKEN_ENV) - p.Logging.Loki.BearerToken = &lokiBearerToken - } - - grafanaBaseUrl := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_GRAFANA_BASE_URL_ENV) - if grafanaBaseUrl != "" { - if p.Logging == nil { - p.Logging = &ctfconfig.LoggingConfig{} - } - if p.Logging.Grafana == nil { - p.Logging.Grafana = &ctfconfig.GrafanaConfig{} - } - logger.Debug().Msgf("Using %s env var to override Logging.Grafana.BaseUrl", ctfconfig.E2E_TEST_GRAFANA_BASE_URL_ENV) - p.Logging.Grafana.BaseUrl = &grafanaBaseUrl - } - - grafanaDashboardUrl := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_GRAFANA_DASHBOARD_URL_ENV) - if grafanaDashboardUrl != "" { - if p.Logging == nil { - p.Logging = &ctfconfig.LoggingConfig{} - } - if p.Logging.Grafana == nil { - p.Logging.Grafana = &ctfconfig.GrafanaConfig{} - } - logger.Debug().Msgf("Using %s env var to override Logging.Grafana.DashboardUrl", ctfconfig.E2E_TEST_GRAFANA_DASHBOARD_URL_ENV) - p.Logging.Grafana.DashboardUrl = &grafanaDashboardUrl - } - - grafanaBearerToken := ctfconfig.MustReadEnvVar_String(ctfconfig.E2E_TEST_GRAFANA_BEARER_TOKEN_ENV) - if grafanaBearerToken != "" { - if p.Logging == nil { - p.Logging = &ctfconfig.LoggingConfig{} - } - if p.Logging.Grafana == nil { - p.Logging.Grafana = &ctfconfig.GrafanaConfig{} - } - logger.Debug().Msgf("Using %s env var to override Logging.Grafana.BearerToken", ctfconfig.E2E_TEST_GRAFANA_BEARER_TOKEN_ENV) - p.Logging.Grafana.BearerToken = &grafanaBearerToken - } - selectedNetworks := ctfconfig.MustReadEnvVar_Strings(ctfconfig.E2E_TEST_SELECTED_NETWORK_ENV, ",") if len(selectedNetworks) > 0 { if p.Network == nil { @@ -421,9 +307,6 @@ func (p *Common) GetSethConfig() *seth.Config { } func (p *Common) Validate() error { - if err := p.Logging.Validate(); err != nil { - return fmt.Errorf("error validating logging config %w", err) - } if p.Network == nil { return errors.New("no networks specified") } diff --git a/integration-tests/ccip-tests/testconfig/tomls/ccip-default.toml b/integration-tests/ccip-tests/testconfig/tomls/ccip-default.toml index c82e2f930be..89858a94ddb 100644 --- a/integration-tests/ccip-tests/testconfig/tomls/ccip-default.toml +++ b/integration-tests/ccip-tests/testconfig/tomls/ccip-default.toml @@ -73,17 +73,6 @@ addresses_to_fund = [ [CCIP.Env.PrivateEthereumNetworks.SIMULATED_2.EthereumChainConfig.HardForkEpochs] Deneb = 500 -[CCIP.Env.Logging] -test_log_collect = false # if set to true will save logs even if test did not fail - -[CCIP.Env.Logging.LogStream] -# supported targets: file, loki, in-memory. if empty no logs will be persistet -log_targets = ["file"] -# context timeout for starting log producer and also time-frame for requesting logs -log_producer_timeout = "10s" -# number of retries before log producer gives up and stops listening to logs -log_producer_retry_limit = 10 - # these values will be used to set up chainlink DON # along with these values, the secrets needs to be specified as part of .env variables # diff --git a/integration-tests/ccip-tests/testsetups/test_env.go b/integration-tests/ccip-tests/testsetups/test_env.go index 263d291453d..3c3406a3e5a 100644 --- a/integration-tests/ccip-tests/testsetups/test_env.go +++ b/integration-tests/ccip-tests/testsetups/test_env.go @@ -352,7 +352,6 @@ func DeployLocalCluster( pointer.GetString(clNode.ChainlinkImage.Image), pointer.GetString(clNode.ChainlinkImage.Version), toml, - env.LogStream, test_env.WithPgDBOptions( ctftestenv.WithPostgresImageName(clNode.DBImage), ctftestenv.WithPostgresImageVersion(clNode.DBTag), @@ -381,7 +380,6 @@ func DeployLocalCluster( pointer.GetString(testInputs.EnvInput.NewCLCluster.Common.ChainlinkImage.Image), pointer.GetString(testInputs.EnvInput.NewCLCluster.Common.ChainlinkImage.Version), toml, - env.LogStream, test_env.WithPgDBOptions( ctftestenv.WithPostgresImageName(testInputs.EnvInput.NewCLCluster.Common.DBImage), ctftestenv.WithPostgresImageVersion(testInputs.EnvInput.NewCLCluster.Common.DBTag), diff --git a/integration-tests/contracts/ccipreader_test.go b/integration-tests/contracts/ccipreader_test.go index 3028f4707a4..3b0ac1d79a1 100644 --- a/integration-tests/contracts/ccipreader_test.go +++ b/integration-tests/contracts/ccipreader_test.go @@ -183,6 +183,123 @@ func emitCommitReports(ctx context.Context, t *testing.T, s *testSetupData, numR return firstReportTs } +func TestCCIPReader_GetOffRampConfigDigest(t *testing.T) { + t.Parallel() + ctx := tests.Context(t) + sb, auth := setupSimulatedBackendAndAuth(t) + + addr, _, _, err := offramp.DeployOffRamp(auth, sb.Client(), offramp.OffRampStaticConfig{ + ChainSelector: uint64(chainD), + GasForCallExactCheck: 5_000, + RmnRemote: utils.RandomAddress(), + TokenAdminRegistry: utils.RandomAddress(), + NonceManager: utils.RandomAddress(), + }, offramp.OffRampDynamicConfig{ + FeeQuoter: utils.RandomAddress(), + PermissionLessExecutionThresholdSeconds: 1, + IsRMNVerificationDisabled: true, + MessageInterceptor: utils.RandomAddress(), + }, []offramp.OffRampSourceChainConfigArgs{}) + require.NoError(t, err) + sb.Commit() + + offRamp, err := offramp.NewOffRamp(addr, sb.Client()) + require.NoError(t, err) + + commitConfigDigest := utils.RandomBytes32() + execConfigDigest := utils.RandomBytes32() + + _, err = offRamp.SetOCR3Configs(auth, []offramp.MultiOCR3BaseOCRConfigArgs{ + { + ConfigDigest: commitConfigDigest, + OcrPluginType: consts.PluginTypeCommit, + F: 1, + IsSignatureVerificationEnabled: true, + Signers: []common.Address{utils.RandomAddress(), utils.RandomAddress(), utils.RandomAddress(), utils.RandomAddress()}, + Transmitters: []common.Address{utils.RandomAddress(), utils.RandomAddress(), utils.RandomAddress(), utils.RandomAddress()}, + }, + { + ConfigDigest: execConfigDigest, + OcrPluginType: consts.PluginTypeExecute, + F: 1, + IsSignatureVerificationEnabled: false, + Signers: []common.Address{utils.RandomAddress(), utils.RandomAddress(), utils.RandomAddress(), utils.RandomAddress()}, + Transmitters: []common.Address{utils.RandomAddress(), utils.RandomAddress(), utils.RandomAddress(), utils.RandomAddress()}, + }, + }) + require.NoError(t, err) + sb.Commit() + + commitConfigDetails, err := offRamp.LatestConfigDetails(&bind.CallOpts{ + Context: ctx, + }, consts.PluginTypeCommit) + require.NoError(t, err) + require.Equal(t, commitConfigDigest, commitConfigDetails.ConfigInfo.ConfigDigest) + + execConfigDetails, err := offRamp.LatestConfigDetails(&bind.CallOpts{ + Context: ctx, + }, consts.PluginTypeExecute) + require.NoError(t, err) + require.Equal(t, execConfigDigest, execConfigDetails.ConfigInfo.ConfigDigest) + + db := pgtest.NewSqlxDB(t) + lggr := logger.TestLogger(t) + lggr.SetLogLevel(zapcore.ErrorLevel) + lpOpts := logpoller.Opts{ + PollPeriod: time.Millisecond, + FinalityDepth: 1, + BackfillBatchSize: 10, + RpcBatchSize: 10, + KeepFinalizedBlocksDepth: 100000, + } + cl := client.NewSimulatedBackendClient(t, sb, big.NewInt(1337)) + headTracker := headtracker.NewSimulatedHeadTracker(cl, lpOpts.UseFinalityTag, lpOpts.FinalityDepth) + orm := logpoller.NewORM(big.NewInt(1337), db, lggr) + lp := logpoller.NewLogPoller( + orm, + cl, + lggr, + headTracker, + lpOpts, + ) + require.NoError(t, lp.Start(ctx)) + t.Cleanup(func() { require.NoError(t, lp.Close()) }) + + cr, err := evm.NewChainReaderService(ctx, lggr, lp, headTracker, cl, evmconfig.DestReaderConfig) + require.NoError(t, err) + err = cr.Start(ctx) + require.NoError(t, err) + t.Cleanup(func() { require.NoError(t, cr.Close()) }) + + extendedCr := contractreader.NewExtendedContractReader(cr) + err = extendedCr.Bind(ctx, []types.BoundContract{ + { + Address: addr.Hex(), + Name: consts.ContractNameOffRamp, + }, + }) + require.NoError(t, err) + + reader := ccipreaderpkg.NewCCIPReaderWithExtendedContractReaders( + ctx, + lggr, + map[cciptypes.ChainSelector]contractreader.Extended{ + chainD: extendedCr, + }, + nil, + chainD, + addr.Bytes(), + ) + + ccipReaderCommitDigest, err := reader.GetOffRampConfigDigest(ctx, consts.PluginTypeCommit) + require.NoError(t, err) + require.Equal(t, commitConfigDigest, ccipReaderCommitDigest) + + ccipReaderExecDigest, err := reader.GetOffRampConfigDigest(ctx, consts.PluginTypeExecute) + require.NoError(t, err) + require.Equal(t, execConfigDigest, ccipReaderExecDigest) +} + func TestCCIPReader_CommitReportsGTETimestamp(t *testing.T) { t.Parallel() ctx := tests.Context(t) @@ -473,11 +590,7 @@ func TestCCIPReader_GetExpectedNextSequenceNumber(t *testing.T) { t.Parallel() ctx := tests.Context(t) //env := NewMemoryEnvironmentContractsOnly(t, logger.TestLogger(t), 2, 4, nil) - env := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), memory.MemoryEnvironmentConfig{ - Chains: 2, - Nodes: 4, - Bootstraps: 1, - }, nil) + env := changeset.NewMemoryEnvironment(t) state, err := changeset.LoadOnchainState(env.Env) require.NoError(t, err) @@ -587,11 +700,7 @@ func TestCCIPReader_Nonces(t *testing.T) { func Test_GetChainFeePriceUpdates(t *testing.T) { t.Parallel() ctx := tests.Context(t) - env := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), memory.MemoryEnvironmentConfig{ - Chains: 2, - Nodes: 4, - Bootstraps: 1, - }, nil) + env := changeset.NewMemoryEnvironment(t) state, err := changeset.LoadOnchainState(env.Env) require.NoError(t, err) @@ -647,11 +756,7 @@ func Test_GetChainFeePriceUpdates(t *testing.T) { func Test_LinkPriceUSD(t *testing.T) { t.Parallel() ctx := tests.Context(t) - env := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), memory.MemoryEnvironmentConfig{ - Chains: 2, - Nodes: 4, - Bootstraps: 1, - }, nil) + env := changeset.NewMemoryEnvironment(t) state, err := changeset.LoadOnchainState(env.Env) require.NoError(t, err) @@ -686,11 +791,7 @@ func Test_LinkPriceUSD(t *testing.T) { func Test_GetMedianDataAvailabilityGasConfig(t *testing.T) { t.Parallel() ctx := tests.Context(t) - env := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), memory.MemoryEnvironmentConfig{ - Chains: 4, - Nodes: 4, - Bootstraps: 1, - }, nil) + env := changeset.NewMemoryEnvironment(t, changeset.WithChains(4)) state, err := changeset.LoadOnchainState(env.Env) require.NoError(t, err) @@ -749,11 +850,7 @@ func Test_GetMedianDataAvailabilityGasConfig(t *testing.T) { func Test_GetWrappedNativeTokenPriceUSD(t *testing.T) { t.Parallel() ctx := tests.Context(t) - env := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), memory.MemoryEnvironmentConfig{ - Chains: 2, - Nodes: 4, - Bootstraps: 1, - }, nil) + env := changeset.NewMemoryEnvironment(t) state, err := changeset.LoadOnchainState(env.Env) require.NoError(t, err) diff --git a/integration-tests/docker/test_env/cl_node.go b/integration-tests/docker/test_env/cl_node.go index b5c2505b252..8ebaf579d0a 100644 --- a/integration-tests/docker/test_env/cl_node.go +++ b/integration-tests/docker/test_env/cl_node.go @@ -24,7 +24,6 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/lib/docker" "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" - "github.com/smartcontractkit/chainlink-testing-framework/lib/logstream" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" @@ -126,11 +125,11 @@ func WithPgDBOptions(opts ...test_env.PostgresDbOption) ClNodeOption { } } -func NewClNode(networks []string, imageName, imageVersion string, nodeConfig *chainlink.Config, logStream *logstream.LogStream, opts ...ClNodeOption) (*ClNode, error) { +func NewClNode(networks []string, imageName, imageVersion string, nodeConfig *chainlink.Config, opts ...ClNodeOption) (*ClNode, error) { nodeDefaultCName := fmt.Sprintf("%s-%s", "cl-node", uuid.NewString()[0:8]) pgDefaultCName := fmt.Sprintf("pg-%s", nodeDefaultCName) - pgDb, err := test_env.NewPostgresDb(networks, test_env.WithPostgresDbContainerName(pgDefaultCName), test_env.WithPostgresDbLogStream(logStream)) + pgDb, err := test_env.NewPostgresDb(networks, test_env.WithPostgresDbContainerName(pgDefaultCName)) if err != nil { return nil, err } @@ -140,7 +139,6 @@ func NewClNode(networks []string, imageName, imageVersion string, nodeConfig *ch ContainerImage: imageName, ContainerVersion: imageVersion, Networks: networks, - LogStream: logStream, StartupTimeout: 3 * time.Minute, }, UserEmail: "local@local.com", @@ -490,28 +488,6 @@ func (n *ClNode) getContainerRequest(secrets string) ( FileMode: 0644, }, }, - LifecycleHooks: []tc.ContainerLifecycleHooks{ - { - PostStarts: []tc.ContainerHook{ - func(ctx context.Context, c tc.Container) error { - if n.LogStream != nil { - return n.LogStream.ConnectContainer(ctx, c, "") - } - return nil - }, - }, - PreStops: []tc.ContainerHook{ - func(ctx context.Context, c tc.Container) error { - if n.LogStream != nil { - return n.LogStream.DisconnectContainer(c) - } - return nil - }, - }, - PostStops: n.PostStopsHooks, - PreTerminates: n.PreTerminatesHooks, - }, - }, }, nil } diff --git a/integration-tests/docker/test_env/test_env.go b/integration-tests/docker/test_env/test_env.go index 1ca50760d17..a37b7f813a7 100644 --- a/integration-tests/docker/test_env/test_env.go +++ b/integration-tests/docker/test_env/test_env.go @@ -20,8 +20,6 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/lib/docker" "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" - "github.com/smartcontractkit/chainlink-testing-framework/lib/logstream" - "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/runid" "github.com/smartcontractkit/chainlink/integration-tests/testconfig/ccip" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" @@ -36,7 +34,6 @@ var ( type CLClusterTestEnv struct { Cfg *TestEnvConfig DockerNetwork *tc.DockerNetwork - LogStream *logstream.LogStream TestConfig ctf_config.GlobalTestConfig /* components */ @@ -69,7 +66,7 @@ func (te *CLClusterTestEnv) WithTestEnvConfig(cfg *TestEnvConfig) *CLClusterTest te.Cfg = cfg if cfg.MockAdapter.ContainerName != "" { n := []string{te.DockerNetwork.Name} - te.MockAdapter = test_env.NewKillgrave(n, te.Cfg.MockAdapter.ImpostersPath, test_env.WithContainerName(te.Cfg.MockAdapter.ContainerName), test_env.WithLogStream(te.LogStream)) + te.MockAdapter = test_env.NewKillgrave(n, te.Cfg.MockAdapter.ImpostersPath, test_env.WithContainerName(te.Cfg.MockAdapter.ContainerName)) } return te } @@ -99,7 +96,6 @@ func (te *CLClusterTestEnv) StartEthereumNetwork(cfg *ctf_config.EthereumNetwork builder := test_env.NewEthereumNetworkBuilder() c, err := builder.WithExistingConfig(*cfg). WithTest(te.t). - WithLogStream(te.LogStream). Build() if err != nil { return blockchain.EVMNetwork{}, test_env.RpcProvider{}, err @@ -132,7 +128,6 @@ func (te *CLClusterTestEnv) StartJobDistributor(cfg *ccip.JDConfig) error { job_distributor.WithVersion(cfg.GetJDVersion()), job_distributor.WithDBURL(jdDB.InternalURL.String()), ) - jd.LogStream = te.LogStream err = jd.StartContainer() if err != nil { return fmt.Errorf("failed to start job-distributor: %w", err) @@ -160,7 +155,7 @@ func (te *CLClusterTestEnv) StartClCluster(nodeConfig *chainlink.Config, count i opts = append(opts, WithSecrets(secretsConfig)) te.ClCluster = &ClCluster{} for i := 0; i < count; i++ { - ocrNode, err := NewClNode([]string{te.DockerNetwork.Name}, *testconfig.GetChainlinkImageConfig().Image, *testconfig.GetChainlinkImageConfig().Version, nodeConfig, te.LogStream, opts...) + ocrNode, err := NewClNode([]string{te.DockerNetwork.Name}, *testconfig.GetChainlinkImageConfig().Image, *testconfig.GetChainlinkImageConfig().Version, nodeConfig, opts...) if err != nil { return err } @@ -193,11 +188,6 @@ type CleanupOpts struct { func (te *CLClusterTestEnv) Cleanup(opts CleanupOpts) error { te.l.Info().Msg("Cleaning up test environment") - runIdErr := runid.RemoveLocalRunId(te.TestConfig.GetLoggingConfig().RunId) - if runIdErr != nil { - te.l.Warn().Msgf("Failed to remove .run.id file due to: %s (not a big deal, you can still remove it manually)", runIdErr.Error()) - } - if te.t == nil { return fmt.Errorf("cannot cleanup test environment without a testing.T") } diff --git a/integration-tests/docker/test_env/test_env_builder.go b/integration-tests/docker/test_env/test_env_builder.go index cdce826f2c2..e11a3c96095 100644 --- a/integration-tests/docker/test_env/test_env_builder.go +++ b/integration-tests/docker/test_env/test_env_builder.go @@ -2,28 +2,25 @@ package test_env import ( "fmt" - "math" "os" "path/filepath" - "slices" "strings" + "sync" "testing" "time" "github.com/rs/zerolog" "github.com/rs/zerolog/log" "go.uber.org/zap/zapcore" - - "github.com/smartcontractkit/chainlink-testing-framework/seth" + "golang.org/x/sync/errgroup" "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" + ctf_docker "github.com/smartcontractkit/chainlink-testing-framework/lib/docker" "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" - "github.com/smartcontractkit/chainlink-testing-framework/lib/logstream" "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" - "github.com/smartcontractkit/chainlink-testing-framework/lib/testsummary" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/osutil" "github.com/smartcontractkit/chainlink/integration-tests/testconfig/ccip" @@ -46,7 +43,6 @@ type ChainlinkNodeLogScannerSettings struct { } type CLTestEnvBuilder struct { - hasLogStream bool hasKillgrave bool jdConfig *ccip.JDConfig clNodeConfig *chainlink.Config @@ -90,7 +86,6 @@ func GetDefaultChainlinkNodeLogScannerSettingsWithExtraAllowedMessages(extraAllo func NewCLTestEnvBuilder() *CLTestEnvBuilder { return &CLTestEnvBuilder{ l: log.Logger, - hasLogStream: true, isEVM: true, chainlinkNodeLogScannerSettings: &DefaultChainlinkNodeLogScannerSettings, } @@ -134,12 +129,6 @@ func (b *CLTestEnvBuilder) WithTestInstance(t *testing.T) *CLTestEnvBuilder { return b } -// WithoutLogStream disables LogStream logging component -func (b *CLTestEnvBuilder) WithoutLogStream() *CLTestEnvBuilder { - b.hasLogStream = false - return b -} - func (b *CLTestEnvBuilder) WithoutChainlinkNodeLogScanner() *CLTestEnvBuilder { b.chainlinkNodeLogScannerSettings = &ChainlinkNodeLogScannerSettings{} return b @@ -250,102 +239,105 @@ func (b *CLTestEnvBuilder) Build() (*CLClusterTestEnv, error) { b.te.WithTestInstance(b.t) } - if b.hasLogStream { - loggingConfig := b.testConfig.GetLoggingConfig() - // we need to enable logging to file if we want to scan logs - if b.chainlinkNodeLogScannerSettings != nil && !slices.Contains(loggingConfig.LogStream.LogTargets, string(logstream.File)) { - b.l.Debug().Msg("Enabling logging to file in order to support Chainlink node log scanning") - loggingConfig.LogStream.LogTargets = append(loggingConfig.LogStream.LogTargets, string(logstream.File)) - } - b.te.LogStream, err = logstream.NewLogStream(b.te.t, b.testConfig.GetLoggingConfig()) - if err != nil { - return nil, err - } - - // this clean up has to be added as the FIRST one, because cleanup functions are executed in reverse order (LIFO) - if b.t != nil && b.cleanUpType != CleanUpTypeNone { - b.t.Cleanup(func() { - b.l.Info().Msg("Shutting down LogStream") - logPath, err := osutil.GetAbsoluteFolderPath("logs") - if err == nil { - b.l.Info().Str("Absolute path", logPath).Msg("LogStream logs folder location") - } - - // flush logs when test failed or when we are explicitly told to collect logs - flushLogStream := b.t.Failed() || *b.testConfig.GetLoggingConfig().TestLogCollect + // this clean up has to be added as the FIRST one, because cleanup functions are executed in reverse order (LIFO) + if b.t != nil && b.cleanUpType != CleanUpTypeNone { + b.t.Cleanup(func() { + logsDir := fmt.Sprintf("logs/%s-%s", b.t.Name(), time.Now().Format("2006-01-02T15-04-05")) + loggingErr := ctf_docker.WriteAllContainersLogs(b.l, logsDir) + if loggingErr != nil { + b.l.Error().Err(loggingErr).Msg("Error writing all Docker containers logs") + } - // run even if test has failed, as we might be able to catch additional problems without running the test again - if b.chainlinkNodeLogScannerSettings != nil { - logProcessor := logstream.NewLogProcessor[int](b.te.LogStream) + if b == nil || b.te == nil || b.te.ClCluster == nil || b.te.ClCluster.Nodes == nil { + log.Warn().Msg("Won't dump container and postgres logs, because test environment doesn't have any nodes") + return + } - processFn := func(log logstream.LogContent, count *int) error { - countSoFar := count - if *countSoFar < 0 { - return fmt.Errorf("negative count: %d", *countSoFar) - } - newCount, err := testreporters.ScanLogLine(b.l, string(log.Content), b.chainlinkNodeLogScannerSettings.FailingLogLevel, uint(*countSoFar), b.chainlinkNodeLogScannerSettings.Threshold, b.chainlinkNodeLogScannerSettings.AllowedMessages) - if err != nil { - return err - } - if newCount > math.MaxInt { - return fmt.Errorf("new count overflows int: %d", newCount) - } - *count = int(newCount) - return nil - } + if b.chainlinkNodeLogScannerSettings != nil { + var logFiles []*os.File - // we cannot do parallel processing here, because ProcessContainerLogs() locks a mutex that controls whether - // new logs can be added to the log stream, so parallel processing would get stuck on waiting for it to be unlocked - LogScanningLoop: - for i := 0; i < b.clNodesCount; i++ { - // if something went wrong during environment setup we might not have all nodes, and we don't want an NPE - if b == nil || b.te == nil || b.te.ClCluster == nil || b.te.ClCluster.Nodes == nil || len(b.te.ClCluster.Nodes)-1 < i || b.te.ClCluster.Nodes[i] == nil { + // when tests run in parallel, we need to make sure that we only process logs that belong to nodes created by the current test + // that is required, because some tests might have custom log messages that are allowed, but only for that test (e.g. because they restart the CL node) + var belongsToCurrentEnv = func(filePath string) bool { + for _, clNode := range b.te.ClCluster.Nodes { + if clNode == nil { continue } - // ignore count return, because we are only interested in the error - _, err := logProcessor.ProcessContainerLogs(b.te.ClCluster.Nodes[i].ContainerName, processFn) - if err != nil && !strings.Contains(err.Error(), testreporters.MultipleLogsAtLogLevelErr) && !strings.Contains(err.Error(), testreporters.OneLogAtLogLevelErr) { - b.l.Error().Err(err).Msg("Error processing CL node logs") - continue - } else if err != nil && (strings.Contains(err.Error(), testreporters.MultipleLogsAtLogLevelErr) || strings.Contains(err.Error(), testreporters.OneLogAtLogLevelErr)) { - flushLogStream = true - b.t.Errorf("Found a concerning log in Chainklink Node logs: %v", err) - break LogScanningLoop + if strings.EqualFold(filePath, clNode.ContainerName+".log") { + return true } } - b.l.Info().Msg("Finished scanning Chainlink Node logs for concerning errors") + return false } - if flushLogStream { - b.l.Info().Msg("Flushing LogStream logs") - // we can't do much if this fails, so we just log the error in LogStream - if err := b.te.LogStream.FlushAndShutdown(); err != nil { - b.l.Error().Err(err).Msg("Error flushing and shutting down LogStream") + fileWalkErr := filepath.Walk(logsDir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err } - b.te.LogStream.PrintLogTargetsLocations() - b.te.LogStream.SaveLogLocationInTestSummary() - } - b.l.Info().Msg("Finished shutting down LogStream") + if !info.IsDir() && belongsToCurrentEnv(info.Name()) { + file, fileErr := os.Open(path) + if fileErr != nil { + return fmt.Errorf("failed to open file %s: %w", path, fileErr) + } + logFiles = append(logFiles, file) + } + return nil + }) - if b.t.Failed() || *b.testConfig.GetLoggingConfig().TestLogCollect { - b.l.Info().Msg("Dump state of all Postgres DBs used by Chainlink Nodes") + if len(logFiles) != len(b.te.ClCluster.Nodes) { + b.l.Warn().Int("Expected", len(b.te.ClCluster.Nodes)).Int("Got", len(logFiles)).Msg("Number of log files does not match number of nodes. Some logs might be missing.") + } - dbDumpFolder := "db_dumps" - dbDumpPath := fmt.Sprintf("%s/%s-%s", dbDumpFolder, b.t.Name(), time.Now().Format("2006-01-02T15-04-05")) - if err := os.MkdirAll(dbDumpPath, os.ModePerm); err != nil { - b.l.Error().Err(err).Msg("Error creating folder for Postgres DB dump") - return + if fileWalkErr != nil { + b.l.Error().Err(fileWalkErr).Msg("Error walking through log files. Skipping log verification.") + } else { + verifyLogsGroup := &errgroup.Group{} + for _, f := range logFiles { + file := f + verifyLogsGroup.Go(func() error { + verifyErr := testreporters.VerifyLogFile(file, b.chainlinkNodeLogScannerSettings.FailingLogLevel, b.chainlinkNodeLogScannerSettings.Threshold, b.chainlinkNodeLogScannerSettings.AllowedMessages...) + _ = file.Close() + // ignore processing errors + if verifyErr != nil && !strings.Contains(verifyErr.Error(), testreporters.MultipleLogsAtLogLevelErr) && !strings.Contains(verifyErr.Error(), testreporters.OneLogAtLogLevelErr) { + b.l.Error().Err(verifyErr).Msg("Error processing CL node logs") + + return nil + + // if it's not a processing error, we want to fail the test; we also can stop processing logs all together at this point + } else if verifyErr != nil && (strings.Contains(verifyErr.Error(), testreporters.MultipleLogsAtLogLevelErr) || strings.Contains(verifyErr.Error(), testreporters.OneLogAtLogLevelErr)) { + + return verifyErr + } + return nil + }) } - absDbDumpPath, err := osutil.GetAbsoluteFolderPath(dbDumpFolder) - if err == nil { - b.l.Info().Str("Absolute path", absDbDumpPath).Msg("PostgresDB dump folder location") + if logVerificationErr := verifyLogsGroup.Wait(); logVerificationErr != nil { + b.t.Errorf("Found a concerning log in Chainklink Node logs: %v", logVerificationErr) } + } + } - for i := 0; i < b.clNodesCount; i++ { + b.l.Info().Msg("Staring to dump state of all Postgres DBs used by Chainlink Nodes") + + dbDumpFolder := "db_dumps" + dbDumpPath := fmt.Sprintf("%s/%s-%s", dbDumpFolder, b.t.Name(), time.Now().Format("2006-01-02T15-04-05")) + if err := os.MkdirAll(dbDumpPath, os.ModePerm); err != nil { + b.l.Error().Err(err).Msg("Error creating folder for Postgres DB dump") + } else { + absDbDumpPath, err := osutil.GetAbsoluteFolderPath(dbDumpFolder) + if err == nil { + b.l.Info().Str("Absolute path", absDbDumpPath).Msg("PostgresDB dump folder location") + } + + dbDumpGroup := sync.WaitGroup{} + for i := 0; i < b.clNodesCount; i++ { + dbDumpGroup.Add(1) + go func() { + defer dbDumpGroup.Done() // if something went wrong during environment setup we might not have all nodes, and we don't want an NPE if b == nil || b.te == nil || b.te.ClCluster == nil || b.te.ClCluster.Nodes == nil || len(b.te.ClCluster.Nodes)-1 < i || b.te.ClCluster.Nodes[i] == nil || b.te.ClCluster.Nodes[i].PostgresDb == nil { - continue + return } filePath := filepath.Join(dbDumpPath, fmt.Sprintf("postgres_db_dump_%s.sql", b.te.ClCluster.Nodes[i].ContainerName)) @@ -353,24 +345,23 @@ func (b *CLTestEnvBuilder) Build() (*CLClusterTestEnv, error) { if err != nil { b.l.Error().Err(err).Msg("Error creating localDbDumpFile for Postgres DB dump") _ = localDbDumpFile.Close() - continue + return } if err := b.te.ClCluster.Nodes[i].PostgresDb.ExecPgDumpFromContainer(localDbDumpFile); err != nil { b.l.Error().Err(err).Msg("Error dumping Postgres DB") } _ = localDbDumpFile.Close() - } - b.l.Info().Msg("Finished dumping state of all Postgres DBs used by Chainlink Nodes") + }() } - if b.testConfig.GetSethConfig() != nil && ((b.t.Failed() && slices.Contains(b.testConfig.GetSethConfig().TraceOutputs, seth.TraceOutput_DOT) && b.testConfig.GetSethConfig().TracingLevel != seth.TracingLevel_None) || (!b.t.Failed() && slices.Contains(b.testConfig.GetSethConfig().TraceOutputs, seth.TraceOutput_DOT) && b.testConfig.GetSethConfig().TracingLevel == seth.TracingLevel_All)) { - _ = testsummary.AddEntry(b.t.Name(), "dot_graphs", "true") - } - }) - } else { - b.l.Warn().Msg("LogStream won't be cleaned up, because either test instance is not set or cleanup type is set to none") - } + dbDumpGroup.Wait() + + b.l.Info().Msg("Finished dumping state of all Postgres DBs used by Chainlink Nodes") + } + }) + } else { + b.l.Warn().Msg("Won't dump container and postgres logs, because either test instance is not set or cleanup type is set to none") } if b.hasKillgrave { @@ -378,7 +369,7 @@ func (b *CLTestEnvBuilder) Build() (*CLClusterTestEnv, error) { return nil, fmt.Errorf("test environment builder failed: %w", fmt.Errorf("cannot start mock adapter without a network")) } - b.te.MockAdapter = test_env.NewKillgrave([]string{b.te.DockerNetwork.Name}, "", test_env.WithLogStream(b.te.LogStream)) + b.te.MockAdapter = test_env.NewKillgrave([]string{b.te.DockerNetwork.Name}, "") err = b.te.StartMockAdapter() if err != nil { @@ -406,10 +397,6 @@ func (b *CLTestEnvBuilder) Build() (*CLClusterTestEnv, error) { return b.te, fmt.Errorf("test environment builder failed: %w", fmt.Errorf("explicit cleanup type must be set when building test environment")) } - if b.te.LogStream == nil && b.chainlinkNodeLogScannerSettings != nil { - log.Warn().Msg("Chainlink node log scanner settings provided, but LogStream is not enabled. Ignoring Chainlink node log scanner settings, as no logs will be available.") - } - if b.jdConfig != nil { err := b.te.StartJobDistributor(b.jdConfig) if err != nil { diff --git a/integration-tests/go.mod b/integration-tests/go.mod index f4e6a9720e8..b87192af47e 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -9,6 +9,13 @@ replace github.com/smartcontractkit/chainlink/v2 => ../ replace github.com/smartcontractkit/chainlink/deployment => ../deployment +// Using a separate `require` here to avoid surrounding line changes +// creating potential merge conflicts. +require ( + github.com/smartcontractkit/chainlink/deployment v0.0.0-20241206210521-125d98cdaf66 + github.com/smartcontractkit/chainlink/v2 v2.0.0-20241206210521-125d98cdaf66 +) + require ( dario.cat/mergo v1.0.1 github.com/AlekSi/pointer v1.1.0 @@ -37,19 +44,16 @@ require ( github.com/segmentio/ksuid v1.0.4 github.com/shopspring/decimal v1.4.0 github.com/slack-go/slack v0.15.0 - github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 github.com/smartcontractkit/chain-selectors v1.0.34 github.com/smartcontractkit/chainlink-automation v0.8.1 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f + github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0 + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.2 - github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.18 + github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.19 github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.9 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.2 - github.com/smartcontractkit/chainlink/deployment v0.0.0-00010101000000-000000000000 - github.com/smartcontractkit/chainlink/v2 v2.14.0-mercury-20240807.0.20241120195829-bd7a1943ad07 github.com/smartcontractkit/libocr v0.0.0-20241007185508-adbe57025f12 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 @@ -419,11 +423,12 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect + github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 // indirect github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e // indirect github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db // indirect github.com/smartcontractkit/chainlink-feeds v0.1.1 // indirect github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2 // indirect - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241204153209-c3a71b0eef99 // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8 // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20241009055228-33d0c0bf38de // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 9e0e176190d..75f4e862f61 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1430,10 +1430,10 @@ github.com/smartcontractkit/chain-selectors v1.0.34 h1:MJ17OGu8+jjl426pcKrJkCf3f github.com/smartcontractkit/chain-selectors v1.0.34/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e h1:GnM6ZWV6vlk2+n6c6o+v/R1LtXzBGVVx7r37nt/h6Uc= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e/go.mod h1:80vGBbOfertJig0xFKsRfm+i17FkjdKkk1dAaGE45Os= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f h1:hH+cAG2zt+WK4I2m572LXAnAJg3wtGEAwzBKR8FiXo8= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0 h1:/1L+v4SxUD2K5RMRbfByyLfePMAgQKeD0onSetPnGmA= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 h1:ZA92CTX9JtEArrxgZw7PNctVxFS+/DmSXumkwf1WiMY= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e/go.mod h1:mUh5/woemsVaHgTorA080hrYmO3syBCmPdnWc/5dOqk= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db h1:N1RH1hSr2ACzOFc9hkCcjE8pRBTdcU3p8nsTJByaLes= @@ -1444,14 +1444,14 @@ github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 h1:0ewLMbAz3 github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0/go.mod h1:/dVVLXrsp+V0AbcYGJo3XMzKg3CkELsweA/TTopCsKE= github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2 h1:onBe3DqNrbtOAzKS4PrPIiJX65BGo1aYiYZxFVEW+jc= github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2/go.mod h1:m/A3lqD7ms/RsQ9BT5P2uceYY0QX5mIt4KQxT2G6qEo= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241204153209-c3a71b0eef99 h1:lvn9Yxah+QD1/PcgijLO0dNRa28HuQWZl8Kkxh46KJc= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241204153209-c3a71b0eef99/go.mod h1:p8aUDfJeley6oer7y+Ucd3edOtRlMTnWg3mN6rhaLWo= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc h1:dssRwJhmzJkUN/OajaDj2GsxBn+Tupk3bI1BkPEoJg0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc/go.mod h1:p8aUDfJeley6oer7y+Ucd3edOtRlMTnWg3mN6rhaLWo= github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8 h1:tNS7U9lrxkFvEuyxQv11HHOiV9LPDGC9wYEy+yM/Jv4= github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8/go.mod h1:EBrEgcdIbwepqguClkv8Ohy7CbyWSJaE4EC9aBJlQK0= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.2 h1:GDGrC5OGiV0RyM1znYWehSQXyZQWTOzrEeJRYmysPCE= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.2/go.mod h1:DsT43c1oTBmp3iQkMcoZOoKThwZvt8X3Pz6UmznJ4GY= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.18 h1:a3xetGZh2nFO1iX5xd9OuqiCkgbWLvW6fTN6fgVubPo= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.18/go.mod h1:NwmlNKqrb02v4Sci4b5KW644nfH2BW+FrKbWwTN5r6M= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.19 h1:9PMwKNqFKc5FXf4VchyD3CGzZelnSgi13fgVdT2X7T4= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.19/go.mod h1:ag7LEgejsVtPXaUNkcoFPpAoDkl1J8V2HSbqVUxfEtk= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 h1:VIxK8u0Jd0Q/VuhmsNm6Bls6Tb31H/sA3A/rbc5hnhg= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0/go.mod h1:lyAu+oMXdNUzEDScj2DXB2IueY+SDXPPfyl/kb63tMM= github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.9 h1:yB1x5UXvpZNka+5h57yo1/GrKfXKCqMzChCISpldZx4= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 23f840a67f3..3d240cccc9e 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -11,6 +11,14 @@ replace github.com/smartcontractkit/chainlink/deployment => ../../deployment replace github.com/smartcontractkit/chainlink/integration-tests => ../ +// Using a separate `require` here to avoid surrounding line changes +// creating potential merge conflicts. +require ( + github.com/smartcontractkit/chainlink/deployment v0.0.0-20241206210521-125d98cdaf66 + github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20241206210521-125d98cdaf66 + github.com/smartcontractkit/chainlink/v2 v2.0.0-20241206210521-125d98cdaf66 +) + require ( github.com/K-Phoen/grabana v0.22.2 github.com/ethereum/go-ethereum v1.14.11 @@ -19,13 +27,10 @@ require ( github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.15.0 - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f - github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.18 + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 + github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.19 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.9 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.2 - github.com/smartcontractkit/chainlink/deployment v0.0.0-20241120141814-47da13e86197 - github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20241030133659-9ec788e78b4f - github.com/smartcontractkit/chainlink/v2 v2.14.0-mercury-20240807.0.20241120195829-bd7a1943ad07 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20241009055228-33d0c0bf38de github.com/stretchr/testify v1.9.0 github.com/wiremock/go-wiremock v1.9.0 @@ -401,12 +406,12 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.34 // indirect github.com/smartcontractkit/chainlink-automation v0.8.1 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0 // indirect github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e // indirect github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db // indirect github.com/smartcontractkit/chainlink-feeds v0.1.1 // indirect github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2 // indirect - github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241204153209-c3a71b0eef99 // indirect + github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8 // indirect github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.2 // indirect github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index e9eaaf81dad..96861fdc048 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1421,10 +1421,10 @@ github.com/smartcontractkit/chain-selectors v1.0.34 h1:MJ17OGu8+jjl426pcKrJkCf3f github.com/smartcontractkit/chain-selectors v1.0.34/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e h1:GnM6ZWV6vlk2+n6c6o+v/R1LtXzBGVVx7r37nt/h6Uc= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20241204015713-8956bb614e9e/go.mod h1:80vGBbOfertJig0xFKsRfm+i17FkjdKkk1dAaGE45Os= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f h1:hH+cAG2zt+WK4I2m572LXAnAJg3wtGEAwzBKR8FiXo8= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241206011233-b6684ee6508f/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0 h1:/1L+v4SxUD2K5RMRbfByyLfePMAgQKeD0onSetPnGmA= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 h1:ZA92CTX9JtEArrxgZw7PNctVxFS+/DmSXumkwf1WiMY= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e/go.mod h1:mUh5/woemsVaHgTorA080hrYmO3syBCmPdnWc/5dOqk= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db h1:N1RH1hSr2ACzOFc9hkCcjE8pRBTdcU3p8nsTJByaLes= @@ -1435,14 +1435,14 @@ github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 h1:0ewLMbAz3 github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0/go.mod h1:/dVVLXrsp+V0AbcYGJo3XMzKg3CkELsweA/TTopCsKE= github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2 h1:onBe3DqNrbtOAzKS4PrPIiJX65BGo1aYiYZxFVEW+jc= github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2/go.mod h1:m/A3lqD7ms/RsQ9BT5P2uceYY0QX5mIt4KQxT2G6qEo= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241204153209-c3a71b0eef99 h1:lvn9Yxah+QD1/PcgijLO0dNRa28HuQWZl8Kkxh46KJc= -github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241204153209-c3a71b0eef99/go.mod h1:p8aUDfJeley6oer7y+Ucd3edOtRlMTnWg3mN6rhaLWo= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc h1:dssRwJhmzJkUN/OajaDj2GsxBn+Tupk3bI1BkPEoJg0= +github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc/go.mod h1:p8aUDfJeley6oer7y+Ucd3edOtRlMTnWg3mN6rhaLWo= github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8 h1:tNS7U9lrxkFvEuyxQv11HHOiV9LPDGC9wYEy+yM/Jv4= github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8/go.mod h1:EBrEgcdIbwepqguClkv8Ohy7CbyWSJaE4EC9aBJlQK0= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.2 h1:GDGrC5OGiV0RyM1znYWehSQXyZQWTOzrEeJRYmysPCE= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.2/go.mod h1:DsT43c1oTBmp3iQkMcoZOoKThwZvt8X3Pz6UmznJ4GY= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.18 h1:a3xetGZh2nFO1iX5xd9OuqiCkgbWLvW6fTN6fgVubPo= -github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.18/go.mod h1:NwmlNKqrb02v4Sci4b5KW644nfH2BW+FrKbWwTN5r6M= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.19 h1:9PMwKNqFKc5FXf4VchyD3CGzZelnSgi13fgVdT2X7T4= +github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.19/go.mod h1:ag7LEgejsVtPXaUNkcoFPpAoDkl1J8V2HSbqVUxfEtk= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 h1:VIxK8u0Jd0Q/VuhmsNm6Bls6Tb31H/sA3A/rbc5hnhg= github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0/go.mod h1:lyAu+oMXdNUzEDScj2DXB2IueY+SDXPPfyl/kb63tMM= github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.9 h1:yB1x5UXvpZNka+5h57yo1/GrKfXKCqMzChCISpldZx4= diff --git a/integration-tests/smoke/ccip/ccip_batching_test.go b/integration-tests/smoke/ccip/ccip_batching_test.go index 8c3615fbb20..58f4e922ac5 100644 --- a/integration-tests/smoke/ccip/ccip_batching_test.go +++ b/integration-tests/smoke/ccip/ccip_batching_test.go @@ -14,7 +14,8 @@ import ( "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink-common/pkg/merklemulti" - "github.com/smartcontractkit/chainlink/deployment/environment/memory" + + testsetups "github.com/smartcontractkit/chainlink/integration-tests/testsetups/ccip" "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" @@ -22,7 +23,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/multicall3" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) const ( @@ -39,18 +39,11 @@ type batchTestSetup struct { func newBatchTestSetup(t *testing.T) batchTestSetup { // Setup 3 chains, with 2 lanes going to the dest. - e := changeset.NewMemoryEnvironmentWithJobsAndContracts( + e, _ := testsetups.NewIntegrationEnvironment( t, - logger.TestLogger(t), - memory.MemoryEnvironmentConfig{ - Chains: 3, - Nodes: 4, - Bootstraps: 1, - NumOfUsersPerChain: 2, - }, - &changeset.TestConfigs{ - IsMultiCall3: true, - }, + changeset.WithMultiCall3(), + changeset.WithChains(3), + changeset.WithUsersPerChain(2), ) state, err := changeset.LoadOnchainState(e.Env) diff --git a/integration-tests/smoke/ccip/ccip_fee_boosting_test.go b/integration-tests/smoke/ccip/ccip_fee_boosting_test.go index 1fe9d5817c9..48d9061ec63 100644 --- a/integration-tests/smoke/ccip/ccip_fee_boosting_test.go +++ b/integration-tests/smoke/ccip/ccip_fee_boosting_test.go @@ -9,8 +9,8 @@ import ( "github.com/pkg/errors" - "github.com/smartcontractkit/chainlink-common/pkg/config" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" + testsetups "github.com/smartcontractkit/chainlink/integration-tests/testsetups/ccip" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" @@ -20,7 +20,6 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" - "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ccipevm" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" @@ -30,7 +29,6 @@ import ( "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) var ( @@ -39,13 +37,10 @@ var ( ) func Test_CCIPFeeBoosting(t *testing.T) { - e := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), - memory.MemoryEnvironmentConfig{ - Chains: 2, - Nodes: 4, - Bootstraps: 1, - }, &changeset.TestConfigs{ - OCRConfigOverride: func(params changeset.CCIPOCRParams) changeset.CCIPOCRParams { + e, _ := testsetups.NewIntegrationEnvironment( + t, + // TODO check if test should use these overrides + /* changeset.WithOCRConfigOverride(func(params changeset.CCIPOCRParams) changeset.CCIPOCRParams { // Only 1 boost (=OCR round) is enough to cover the fee params.ExecuteOffChainConfig.RelativeBoostPerWaitHour = 10 // Disable token price updates @@ -55,8 +50,10 @@ func Test_CCIPFeeBoosting(t *testing.T) { // Disable token price updates params.CommitOffChainConfig.TokenInfo = nil return params - }, - }) + }), + + */ + ) state, err := changeset.LoadOnchainState(e.Env) require.NoError(t, err) diff --git a/integration-tests/smoke/ccip/ccip_fees_test.go b/integration-tests/smoke/ccip/ccip_fees_test.go index 791ba8f2619..55788a4aa5f 100644 --- a/integration-tests/smoke/ccip/ccip_fees_test.go +++ b/integration-tests/smoke/ccip/ccip_fees_test.go @@ -14,7 +14,7 @@ import ( "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" - "github.com/smartcontractkit/chainlink/deployment/environment/memory" + testsetups "github.com/smartcontractkit/chainlink/integration-tests/testsetups/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/weth9_wrapper" @@ -101,11 +101,10 @@ func setupTokens( func Test_CCIPFees(t *testing.T) { t.Parallel() - tenv := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), memory.MemoryEnvironmentConfig{ - Chains: 2, - Nodes: 4, - Bootstraps: 1, - }, nil) + tenv, _ := testsetups.NewIntegrationEnvironment( + t, + changeset.WithMultiCall3(), + ) e := tenv.Env allChains := tenv.Env.AllChainSelectors() diff --git a/integration-tests/smoke/ccip/ccip_gas_price_updates_test.go b/integration-tests/smoke/ccip/ccip_gas_price_updates_test.go index 221d35bd992..d11e4304366 100644 --- a/integration-tests/smoke/ccip/ccip_gas_price_updates_test.go +++ b/integration-tests/smoke/ccip/ccip_gas_price_updates_test.go @@ -12,27 +12,26 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" testsetups "github.com/smartcontractkit/chainlink/integration-tests/testsetups/ccip" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) // Test_CCIPGasPriceUpdates tests that chain fee price updates are propagated correctly when // price reaches some deviation threshold or when the price has expired. func Test_CCIPGasPriceUpdates(t *testing.T) { - lggr := logger.TestLogger(t) ctx := changeset.Context(t) callOpts := &bind.CallOpts{Context: ctx} var gasPriceExpiry = 5 * time.Second - e, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr, &changeset.TestConfigs{ - OCRConfigOverride: func(params changeset.CCIPOCRParams) changeset.CCIPOCRParams { + e, _ := testsetups.NewIntegrationEnvironment(t, + changeset.WithOCRConfigOverride(func(params changeset.CCIPOCRParams) changeset.CCIPOCRParams { params.CommitOffChainConfig.RemoteGasPriceBatchWriteFrequency = *config.MustNewDuration(gasPriceExpiry) return params - }, - }) + }), + ) state, err := changeset.LoadOnchainState(e.Env) require.NoError(t, err) require.NoError(t, changeset.AddLanesForAll(e.Env, state)) diff --git a/integration-tests/smoke/ccip/ccip_message_limitations_test.go b/integration-tests/smoke/ccip/ccip_message_limitations_test.go index 902d07aec5c..9398fd9f932 100644 --- a/integration-tests/smoke/ccip/ccip_message_limitations_test.go +++ b/integration-tests/smoke/ccip/ccip_message_limitations_test.go @@ -17,15 +17,13 @@ import ( "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" testsetups "github.com/smartcontractkit/chainlink/integration-tests/testsetups/ccip" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) func Test_CCIPMessageLimitations(t *testing.T) { - lggr := logger.TestLogger(t) ctx := testcontext.Get(t) callOpts := &bind.CallOpts{Context: ctx} - testEnv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr, &changeset.TestConfigs{}) + testEnv, _ := testsetups.NewIntegrationEnvironment(t) chains := maps.Keys(testEnv.Env.Chains) onChainState, err := changeset.LoadOnchainState(testEnv.Env) diff --git a/integration-tests/smoke/ccip/ccip_messaging_test.go b/integration-tests/smoke/ccip/ccip_messaging_test.go index 07e237451c8..13f14fcda16 100644 --- a/integration-tests/smoke/ccip/ccip_messaging_test.go +++ b/integration-tests/smoke/ccip/ccip_messaging_test.go @@ -18,11 +18,10 @@ import ( "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" - "github.com/smartcontractkit/chainlink/deployment/environment/memory" + testsetups "github.com/smartcontractkit/chainlink/integration-tests/testsetups/ccip" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) type testCaseSetup struct { @@ -48,11 +47,7 @@ type messagingTestCaseOutput struct { func Test_CCIPMessaging(t *testing.T) { // Setup 2 chains and a single lane. ctx := changeset.Context(t) - e := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), memory.MemoryEnvironmentConfig{ - Chains: 2, - Nodes: 4, - Bootstraps: 1, - }, nil) + e, _ := testsetups.NewIntegrationEnvironment(t) state, err := changeset.LoadOnchainState(e.Env) require.NoError(t, err) diff --git a/integration-tests/smoke/ccip/ccip_ooo_execution_test.go b/integration-tests/smoke/ccip/ccip_ooo_execution_test.go index 86ddd07ec85..19c36c6e021 100644 --- a/integration-tests/smoke/ccip/ccip_ooo_execution_test.go +++ b/integration-tests/smoke/ccip/ccip_ooo_execution_test.go @@ -12,9 +12,10 @@ import ( "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" - "github.com/smartcontractkit/chainlink/deployment/environment/memory" + testsetups "github.com/smartcontractkit/chainlink/integration-tests/testsetups/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -32,16 +33,12 @@ import ( func Test_OutOfOrderExecution(t *testing.T) { lggr := logger.TestLogger(t) ctx := tests.Context(t) - config := &changeset.TestConfigs{ - IsUSDC: true, - IsUSDCAttestationMissing: true, - } - tenv := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), memory.MemoryEnvironmentConfig{ - Chains: 2, - Nodes: 4, - Bootstraps: 1, - NumOfUsersPerChain: 2, - }, config) + tenv, _ := testsetups.NewIntegrationEnvironment( + t, + changeset.WithUSDC(), + changeset.WithUSDCAttestationMissing(), + changeset.WithUsersPerChain(2), + ) e := tenv.Env state, err := changeset.LoadOnchainState(e) diff --git a/integration-tests/smoke/ccip/ccip_rmn_test.go b/integration-tests/smoke/ccip/ccip_rmn_test.go index 6cd6bd9d63f..c22f9bcf20e 100644 --- a/integration-tests/smoke/ccip/ccip_rmn_test.go +++ b/integration-tests/smoke/ccip/ccip_rmn_test.go @@ -22,9 +22,9 @@ import ( "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/osutil" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" - "github.com/smartcontractkit/chainlink/deployment/environment/devenv" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" + "github.com/smartcontractkit/chainlink/deployment/environment/devenv" "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_home" @@ -32,10 +32,10 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" testsetups "github.com/smartcontractkit/chainlink/integration-tests/testsetups/ccip" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) func TestRMN_TwoMessagesOnTwoLanesIncludingBatching(t *testing.T) { + t.Skip("This test is flaky and needs to be fixed") runRmnTestCase(t, rmnTestCase{ name: "messages on two lanes including batching", waitForExec: true, @@ -59,6 +59,7 @@ func TestRMN_TwoMessagesOnTwoLanesIncludingBatching(t *testing.T) { } func TestRMN_MultipleMessagesOnOneLaneNoWaitForExec(t *testing.T) { + t.Skip("This test is flaky and needs to be fixed") runRmnTestCase(t, rmnTestCase{ name: "multiple messages for rmn batching inspection and one rmn node down", waitForExec: false, // do not wait for execution reports @@ -81,6 +82,7 @@ func TestRMN_MultipleMessagesOnOneLaneNoWaitForExec(t *testing.T) { } func TestRMN_NotEnoughObservers(t *testing.T) { + t.Skip("This test is flaky and needs to be fixed") runRmnTestCase(t, rmnTestCase{ name: "one message but not enough observers, should not get a commit report", passIfNoCommitAfter: 15 * time.Second, @@ -103,6 +105,7 @@ func TestRMN_NotEnoughObservers(t *testing.T) { } func TestRMN_DifferentSigners(t *testing.T) { + t.Skip("This test is flaky and needs to be fixed") runRmnTestCase(t, rmnTestCase{ name: "different signers and different observers", homeChainConfig: homeChainConfig{ @@ -127,6 +130,7 @@ func TestRMN_DifferentSigners(t *testing.T) { } func TestRMN_NotEnoughSigners(t *testing.T) { + t.Skip("This test is flaky and needs to be fixed") runRmnTestCase(t, rmnTestCase{ name: "different signers and different observers", passIfNoCommitAfter: 15 * time.Second, @@ -152,6 +156,7 @@ func TestRMN_NotEnoughSigners(t *testing.T) { } func TestRMN_DifferentRmnNodesForDifferentChains(t *testing.T) { + t.Skip("This test is flaky and needs to be fixed") runRmnTestCase(t, rmnTestCase{ name: "different rmn nodes support different chains", waitForExec: false, @@ -178,6 +183,7 @@ func TestRMN_DifferentRmnNodesForDifferentChains(t *testing.T) { } func TestRMN_TwoMessagesOneSourceChainCursed(t *testing.T) { + t.Skip("This test is flaky and needs to be fixed") runRmnTestCase(t, rmnTestCase{ name: "two messages, one source chain is cursed", passIfNoCommitAfter: 15 * time.Second, @@ -204,6 +210,7 @@ func TestRMN_TwoMessagesOneSourceChainCursed(t *testing.T) { } func TestRMN_GlobalCurseTwoMessagesOnTwoLanes(t *testing.T) { + t.Skip("This test is flaky and needs to be fixed") runRmnTestCase(t, rmnTestCase{ name: "global curse messages on two lanes", waitForExec: false, @@ -244,7 +251,9 @@ func runRmnTestCase(t *testing.T, tc rmnTestCase) { ctx := testcontext.Get(t) t.Logf("Running RMN test case: %s", tc.name) - envWithRMN, rmnCluster := testsetups.NewLocalDevEnvironmentWithRMN(t, logger.TestLogger(t), len(tc.rmnNodes)) + envWithRMN, rmnCluster := testsetups.NewIntegrationEnvironment(t, + changeset.WithRMNEnabled(len(tc.rmnNodes)), + ) t.Logf("envWithRmn: %#v", envWithRMN) tc.populateFields(t, envWithRMN, rmnCluster) diff --git a/integration-tests/smoke/ccip/ccip_test.go b/integration-tests/smoke/ccip/ccip_test.go deleted file mode 100644 index ca30c9281c4..00000000000 --- a/integration-tests/smoke/ccip/ccip_test.go +++ /dev/null @@ -1,83 +0,0 @@ -package smoke - -import ( - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" - - "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" - testsetups "github.com/smartcontractkit/chainlink/integration-tests/testsetups/ccip" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/logger" -) - -func TestInitialDeployOnLocal(t *testing.T) { - t.Parallel() - lggr := logger.TestLogger(t) - config := &changeset.TestConfigs{} - tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr, config) - e := tenv.Env - state, err := changeset.LoadOnchainState(e) - require.NoError(t, err) - - // Add all lanes - require.NoError(t, changeset.AddLanesForAll(e, state)) - // Need to keep track of the block number for each chain so that event subscription can be done from that block. - startBlocks := make(map[uint64]*uint64) - // Send a message from each chain to every other chain. - expectedSeqNum := make(map[changeset.SourceDestPair]uint64) - expectedSeqNumExec := make(map[changeset.SourceDestPair][]uint64) - for src := range e.Chains { - for dest, destChain := range e.Chains { - if src == dest { - continue - } - latesthdr, err := destChain.Client.HeaderByNumber(testcontext.Get(t), nil) - require.NoError(t, err) - block := latesthdr.Number.Uint64() - startBlocks[dest] = &block - require.GreaterOrEqual(t, len(tenv.Users[src]), 2) - msgSentEvent, err := changeset.DoSendRequest(t, e, state, - changeset.WithSender(tenv.Users[src][1]), - changeset.WithSourceChain(src), - changeset.WithDestChain(dest), - changeset.WithTestRouter(false), - changeset.WithEvm2AnyMessage(router.ClientEVM2AnyMessage{ - Receiver: common.LeftPadBytes(state.Chains[dest].Receiver.Address().Bytes(), 32), - Data: []byte("hello world"), - TokenAmounts: nil, - FeeToken: common.HexToAddress("0x0"), - ExtraArgs: nil, - })) - require.NoError(t, err) - expectedSeqNum[changeset.SourceDestPair{ - SourceChainSelector: src, - DestChainSelector: dest, - }] = msgSentEvent.SequenceNumber - expectedSeqNumExec[changeset.SourceDestPair{ - SourceChainSelector: src, - DestChainSelector: dest, - }] = []uint64{msgSentEvent.SequenceNumber} - } - } - - // Wait for all commit reports to land. - changeset.ConfirmCommitForAllWithExpectedSeqNums(t, e, state, expectedSeqNum, startBlocks) - - // After commit is reported on all chains, token prices should be updated in FeeQuoter. - for dest := range e.Chains { - linkAddress := state.Chains[dest].LinkToken.Address() - feeQuoter := state.Chains[dest].FeeQuoter - timestampedPrice, err := feeQuoter.GetTokenPrice(nil, linkAddress) - require.NoError(t, err) - require.Equal(t, changeset.MockLinkPrice, timestampedPrice.Value) - } - - // Wait for all exec reports to land - changeset.ConfirmExecWithSeqNrsForAll(t, e, state, expectedSeqNumExec, startBlocks) - - // TODO: Apply the proposal. -} diff --git a/integration-tests/smoke/ccip/ccip_token_price_updates_test.go b/integration-tests/smoke/ccip/ccip_token_price_updates_test.go index 6a193397d7e..e3496b6f407 100644 --- a/integration-tests/smoke/ccip/ccip_token_price_updates_test.go +++ b/integration-tests/smoke/ccip/ccip_token_price_updates_test.go @@ -16,25 +16,23 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" + "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" testsetups "github.com/smartcontractkit/chainlink/integration-tests/testsetups/ccip" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" - "github.com/smartcontractkit/chainlink/v2/core/logger" ) func Test_CCIPTokenPriceUpdates(t *testing.T) { - lggr := logger.TestLogger(t) ctx := changeset.Context(t) callOpts := &bind.CallOpts{Context: ctx} var tokenPriceExpiry = 5 * time.Second - e, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr, &changeset.TestConfigs{ - OCRConfigOverride: func(params changeset.CCIPOCRParams) changeset.CCIPOCRParams { + e, _ := testsetups.NewIntegrationEnvironment(t, + changeset.WithOCRConfigOverride(func(params changeset.CCIPOCRParams) changeset.CCIPOCRParams { params.CommitOffChainConfig.TokenPriceBatchWriteFrequency = *config.MustNewDuration(tokenPriceExpiry) return params - }, - }) + })) state, err := changeset.LoadOnchainState(e.Env) require.NoError(t, err) require.NoError(t, changeset.AddLanesForAll(e.Env, state)) diff --git a/integration-tests/smoke/ccip/ccip_token_transfer_test.go b/integration-tests/smoke/ccip/ccip_token_transfer_test.go index 13abe33fe7c..2088960639e 100644 --- a/integration-tests/smoke/ccip/ccip_token_transfer_test.go +++ b/integration-tests/smoke/ccip/ccip_token_transfer_test.go @@ -10,8 +10,9 @@ import ( "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" - "github.com/smartcontractkit/chainlink/deployment/environment/memory" + testsetups "github.com/smartcontractkit/chainlink/integration-tests/testsetups/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -20,14 +21,9 @@ import ( func TestTokenTransfer(t *testing.T) { lggr := logger.TestLogger(t) ctx := tests.Context(t) - config := &changeset.TestConfigs{} - tenv := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), memory.MemoryEnvironmentConfig{ - Chains: 2, - Nodes: 4, - Bootstraps: 1, - NumOfUsersPerChain: 3, - }, config) + tenv, _ := testsetups.NewIntegrationEnvironment(t, + changeset.WithUsersPerChain(3)) e := tenv.Env state, err := changeset.LoadOnchainState(e) @@ -214,7 +210,7 @@ func TestTokenTransfer(t *testing.T) { t, e, state, - changeset.SeqNumberRageToSlice(expectedSeqNums), + changeset.SeqNumberRangeToSlice(expectedSeqNums), startBlocks, ) require.Equal(t, expectedExecutionStates, execStates) diff --git a/integration-tests/smoke/ccip/ccip_usdc_test.go b/integration-tests/smoke/ccip/ccip_usdc_test.go index 2dae3f3c48e..174ab941387 100644 --- a/integration-tests/smoke/ccip/ccip_usdc_test.go +++ b/integration-tests/smoke/ccip/ccip_usdc_test.go @@ -11,9 +11,10 @@ import ( "golang.org/x/sync/errgroup" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" - "github.com/smartcontractkit/chainlink/deployment/environment/memory" + testsetups "github.com/smartcontractkit/chainlink/integration-tests/testsetups/ccip" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" @@ -31,15 +32,11 @@ import ( func TestUSDCTokenTransfer(t *testing.T) { lggr := logger.TestLogger(t) ctx := tests.Context(t) - config := &changeset.TestConfigs{ - IsUSDC: true, - } - tenv := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, lggr, memory.MemoryEnvironmentConfig{ - Chains: 3, - NumOfUsersPerChain: 3, - Nodes: 4, - Bootstraps: 1, - }, config) + tenv, _ := testsetups.NewIntegrationEnvironment(t, + changeset.WithUsersPerChain(3), + changeset.WithChains(3), + changeset.WithUSDC(), + ) e := tenv.Env state, err := changeset.LoadOnchainState(e) @@ -228,7 +225,7 @@ func TestUSDCTokenTransfer(t *testing.T) { t, e, state, - changeset.SeqNumberRageToSlice(expectedSeqNums), + changeset.SeqNumberRangeToSlice(expectedSeqNums), startBlocks, ) require.Equal(t, expectedExecutionStates, execStates) diff --git a/integration-tests/smoke/ocr2_test.go b/integration-tests/smoke/ocr2_test.go index a011dfdffc6..8416ec05c7e 100644 --- a/integration-tests/smoke/ocr2_test.go +++ b/integration-tests/smoke/ocr2_test.go @@ -1,14 +1,19 @@ package smoke import ( + "bufio" "fmt" "math/big" "net/http" + "os" + "path/filepath" + "regexp" "strings" + "sync" "testing" "time" - "github.com/smartcontractkit/chainlink/integration-tests/utils" + "github.com/onsi/gomega" "github.com/ethereum/go-ethereum/common" "github.com/rs/zerolog" @@ -16,8 +21,8 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/seth" + ctf_docker "github.com/smartcontractkit/chainlink-testing-framework/lib/docker" "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" - "github.com/smartcontractkit/chainlink-testing-framework/lib/logstream" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" "github.com/smartcontractkit/chainlink/v2/core/config/env" @@ -26,6 +31,7 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" + "github.com/smartcontractkit/chainlink/integration-tests/utils" ) type ocr2test struct { @@ -224,33 +230,150 @@ func prepareORCv2SmokeTestEnv(t *testing.T, testData ocr2test, l zerolog.Logger, } func assertCorrectNodeConfiguration(t *testing.T, l zerolog.Logger, totalNodeCount int, testData ocr2test, testEnv *test_env.CLClusterTestEnv) { - expectedNodesWithConfiguration := totalNodeCount - 1 // minus bootstrap node - var expectedPatterns []string + l.Info().Msg("Checking if all nodes have correct plugin configuration applied") - if testData.env[string(env.MedianPlugin.Cmd)] != "" { - expectedPatterns = append(expectedPatterns, "Registered loopp.*OCR2.*Median.*") - } + // we have to use gomega here, because sometimes there's a delay in the logs being written (especially in the CI) + // and this check fails on the first execution, and we don't want to add any hardcoded sleeps - if testData.chainReaderAndCodec { - expectedPatterns = append(expectedPatterns, "relayConfig\\.chainReader") - } else { - expectedPatterns = append(expectedPatterns, "ChainReader missing from RelayConfig; falling back to internal MedianContract") - } + gom := gomega.NewGomegaWithT(t) + gom.Eventually(func(g gomega.Gomega) { + allNodesHaveCorrectConfig := false + + var expectedPatterns []string + expectedNodeCount := totalNodeCount - 1 + + if testData.env[string(env.MedianPlugin.Cmd)] != "" { + expectedPatterns = append(expectedPatterns, `Registered loopp.*OCR2.*Median.*`) + } + + if testData.chainReaderAndCodec { + expectedPatterns = append(expectedPatterns, `relayConfig.chainReader`) + } else { + expectedPatterns = append(expectedPatterns, "ChainReader missing from RelayConfig; falling back to internal MedianContract") + } + + logFilePaths := make(map[string]string) + tempLogsDir := os.TempDir() + + var nodesToInclude []string + for i := 1; i < totalNodeCount; i++ { + nodesToInclude = append(nodesToInclude, testEnv.ClCluster.Nodes[i].ContainerName+".log") + } + + // save all log files in temp dir + loggingErr := ctf_docker.WriteAllContainersLogs(l, tempLogsDir) + if loggingErr != nil { + l.Debug().Err(loggingErr).Msg("Error writing all containers logs. Trying again...") + + // try again + return + } + + var fileNameIncludeFilter = func(name string) bool { + for _, n := range nodesToInclude { + if strings.EqualFold(name, n) { + return true + } + } + return false + } + + // find log files for CL nodes + fileWalkErr := filepath.Walk(tempLogsDir, func(path string, info os.FileInfo, err error) error { + if err != nil { + if os.IsPermission(err) { + return nil + } + return err + } + if !info.IsDir() && fileNameIncludeFilter(info.Name()) { + absPath, err := filepath.Abs(path) + if err != nil { + return err + } + logFilePaths[strings.TrimSuffix(info.Name(), ".log")] = absPath + } + return nil + }) + + if fileWalkErr != nil { + l.Debug().Err(fileWalkErr).Msg("Error walking through log files. Trying again...") + + return + } + + if len(logFilePaths) != expectedNodeCount { + l.Debug().Msgf("Expected number of log files to match number of nodes (excluding bootstrap node). Expected: %d, Found: %d. Trying again...", expectedNodeCount, len(logFilePaths)) + + return + } + + // search for expected pattern in log file + var searchForLineInFile = func(filePath string, pattern string) bool { + file, fileErr := os.Open(filePath) + if fileErr != nil { + return false + } + + defer func(file *os.File) { + _ = file.Close() + }(file) + + scanner := bufio.NewScanner(file) + scanner.Split(bufio.ScanLines) + pc := regexp.MustCompile(pattern) + + for scanner.Scan() { + jsonLogLine := scanner.Text() + if pc.MatchString(jsonLogLine) { + return true + } + + } + return false + } + + wg := sync.WaitGroup{} + resultsCh := make(chan map[string][]string, len(logFilePaths)) + + // process all logs in parallel + for nodeName, logFilePath := range logFilePaths { + wg.Add(1) + filePath := logFilePath + go func() { + defer wg.Done() + var patternsFound []string + for _, pattern := range expectedPatterns { + found := searchForLineInFile(filePath, pattern) + if found { + patternsFound = append(patternsFound, pattern) + } + } + resultsCh <- map[string][]string{nodeName: patternsFound} + }() + } + + wg.Wait() + close(resultsCh) - // make sure that nodes are correctly configured by scanning the logs - for _, pattern := range expectedPatterns { - l.Info().Msgf("Checking for pattern: '%s' in CL node logs", pattern) var correctlyConfiguredNodes []string - for i := 1; i < len(testEnv.ClCluster.Nodes); i++ { - logProcessor, processFn, err := logstream.GetRegexMatchingProcessor(testEnv.LogStream, pattern) - require.NoError(t, err, "Error getting regex matching processor") - - count, err := logProcessor.ProcessContainerLogs(testEnv.ClCluster.Nodes[i].ContainerName, processFn) - require.NoError(t, err, "Error processing container logs") - if *count >= 1 { - correctlyConfiguredNodes = append(correctlyConfiguredNodes, testEnv.ClCluster.Nodes[i].ContainerName) + var incorrectlyConfiguredNodes []string + + // check results + for result := range resultsCh { + for nodeName, patternsFound := range result { + if len(patternsFound) == len(expectedPatterns) { + correctlyConfiguredNodes = append(correctlyConfiguredNodes, nodeName) + } else { + incorrectlyConfiguredNodes = append(incorrectlyConfiguredNodes, nodeName) + } } } - require.Equal(t, expectedNodesWithConfiguration, len(correctlyConfiguredNodes), "expected correct plugin config to be applied to %d cl-nodes, but only following ones had it: %s; regexp used: %s", expectedNodesWithConfiguration, strings.Join(correctlyConfiguredNodes, ", "), string(pattern)) - } + + allNodesHaveCorrectConfig = len(correctlyConfiguredNodes) == expectedNodeCount + + g.Expect(allNodesHaveCorrectConfig).To(gomega.BeTrue(), "%d nodes' logs were missing expected plugin configuration entries. Correctly configured nodes: %s. Nodes with missing configuration: %s. Expected log patterns: %s", expectedNodeCount-len(correctlyConfiguredNodes), strings.Join(correctlyConfiguredNodes, ", "), strings.Join(incorrectlyConfiguredNodes, ", "), strings.Join(expectedPatterns, ", ")) + }, "1m", "10s").Should(gomega.Succeed()) + + l.Info().Msg("All nodes have correct plugin configuration applied") } diff --git a/integration-tests/testconfig/automation/example.toml b/integration-tests/testconfig/automation/example.toml index 3bbe78d693d..c239e5a3966 100644 --- a/integration-tests/testconfig/automation/example.toml +++ b/integration-tests/testconfig/automation/example.toml @@ -7,14 +7,6 @@ version="2.7.0" # if set to true will save logs even if test did not fail test_log_collect=false -[Logging.LogStream] -# supported targets: file, loki, in-memory. if empty no logs will be persistet -log_targets=["file"] -# context timeout for starting log producer and also time-frame for requesting logs -log_producer_timeout="10s" -# number of retries before log producer gives up and stops listening to logs -log_producer_retry_limit=10 - # if you want to use polygon_mumbial [Network] selected_networks=["polygon_mumbai"] diff --git a/integration-tests/testconfig/ccip/overrides/sepolia_avax_binance.toml b/integration-tests/testconfig/ccip/overrides/sepolia_avax_binance.toml index 06af64d5d91..72c43b12da5 100644 --- a/integration-tests/testconfig/ccip/overrides/sepolia_avax_binance.toml +++ b/integration-tests/testconfig/ccip/overrides/sepolia_avax_binance.toml @@ -5,10 +5,6 @@ chainlink_node_funding = 2 [Logging] test_log_collect = true -[Logging.LogStream] -# supported targets: file, loki, in-memory. if empty no logs will be persisted -log_targets = ["loki"] - [Network] selected_networks = ['SEPOLIA', 'AVALANCHE_FUJI', 'BSC_TESTNET'] diff --git a/integration-tests/testconfig/default.toml b/integration-tests/testconfig/default.toml index b9987d4571d..8180b40ae21 100644 --- a/integration-tests/testconfig/default.toml +++ b/integration-tests/testconfig/default.toml @@ -2,19 +2,6 @@ # set to true to flush logs to selected target regardless of test result; otherwise logs are only flushed if test failed test_log_collect = false -[Logging.Grafana] -base_url = "https://grafana.ops.prod.cldev.sh" -base_url_github_ci = "http://localhost:8080/primary" -dashboard_url = "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - -[Logging.LogStream] -# supported targets: file, loki, in-memory. if empty no logs will be persisted -log_targets = ["file"] -# context timeout for starting log producer and also time-frame for requesting logs -log_producer_timeout = "10s" -# number of retries before log producer gives up and stops listening to logs -log_producer_retry_limit = 10 - [ChainlinkImage] # postgres version to use postgres_version = "12.0" diff --git a/integration-tests/testconfig/forwarder_ocr/example.toml b/integration-tests/testconfig/forwarder_ocr/example.toml index 517a341f803..6ca4b8bbcc3 100644 --- a/integration-tests/testconfig/forwarder_ocr/example.toml +++ b/integration-tests/testconfig/forwarder_ocr/example.toml @@ -7,33 +7,6 @@ version="2.7.0" # if set to true will save logs even if test did not fail test_log_collect=false -[Logging.LogStream] -# supported targets: file, loki, in-memory. if empty no logs will be persistet -log_targets=["file"] -# context timeout for starting log producer and also time-frame for requesting logs -log_producer_timeout="10s" -# number of retries before log producer gives up and stops listening to logs -log_producer_retry_limit=10 - -[Logging.Loki] -tenant_id="tenant_id" -# full URL of Loki ingest endpoint -endpoint="https://loki.url/api/v3/push" -# currently only needed when using public instance -basic_auth_secret="loki-basic-auth" -# only needed for cloud grafana -bearer_token_secret="bearer_token" - -# LogStream will try to shorten Grafana URLs by default (if all 3 variables are set) -[Logging.Grafana] -# grafana url (trailing "/" will be stripped) -base_url="http://grafana.url" -# url of your grafana dashboard (prefix and suffix "/" are stirpped), example: /d/ad61652-2712-1722/my-dashboard -dashboard_url="/d/your-dashboard" -# Grafana dashboard uid to annotate. Find it in Dashboard Settings -> JSON Model -dashboard_uid="dashboard-uid-to-annotate" -bearer_token_secret="my-awesome-token" - # if you want to use polygon_mumbial [Network] selected_networks=["polygon_mumbai"] diff --git a/integration-tests/testconfig/forwarder_ocr2/example.toml b/integration-tests/testconfig/forwarder_ocr2/example.toml index 3ec3e4c690a..e3fb66a0f3a 100644 --- a/integration-tests/testconfig/forwarder_ocr2/example.toml +++ b/integration-tests/testconfig/forwarder_ocr2/example.toml @@ -8,33 +8,6 @@ version="2.7.0" # if set to true will save logs even if test did not fail test_log_collect=false -[Logging.LogStream] -# supported targets: file, loki, in-memory. if empty no logs will be persistet -log_targets=["file"] -# context timeout for starting log producer and also time-frame for requesting logs -log_producer_timeout="10s" -# number of retries before log producer gives up and stops listening to logs -log_producer_retry_limit=10 - -[Logging.Loki] -tenant_id="tenant_id" -# full URL of Loki ingest endpoint -endpoint="https://loki.url/api/v3/push" -# currently only needed when using public instance -basic_auth_secret="loki-basic-auth" -# only needed for cloud grafana -bearer_token_secret="bearer_token" - -# LogStream will try to shorten Grafana URLs by default (if all 3 variables are set) -[Logging.Grafana] -# grafana url (trailing "/" will be stripped) -base_url="http://grafana.url" -# url of your grafana dashboard (prefix and suffix "/" are stirpped), example: /d/ad61652-2712-1722/my-dashboard -dashboard_url="/d/your-dashboard" -# Grafana dashboard uid to annotate. Find it in Dashboard Settings -> JSON Model -dashboard_uid="dashboard-uid-to-annotate" -bearer_token_secret="my-awesome-token" - # if you want to use polygon_mumbial [Network] selected_networks=["polygon_mumbai"] diff --git a/integration-tests/testconfig/functions/example.toml b/integration-tests/testconfig/functions/example.toml index 74d931632a8..ec7076fa9f9 100644 --- a/integration-tests/testconfig/functions/example.toml +++ b/integration-tests/testconfig/functions/example.toml @@ -7,14 +7,6 @@ version="2.7.0" # if set to true will save logs even if test did not fail test_log_collect=false -[Logging.LogStream] -# supported targets: file, loki, in-memory. if empty no logs will be persistet -log_targets=["file"] -# context timeout for starting log producer and also time-frame for requesting logs -log_producer_timeout="10s" -# number of retries before log producer gives up and stops listening to logs -log_producer_retry_limit=10 - # if you want to use simulated network [Network] selected_networks=["polygon_mumbai"] diff --git a/integration-tests/testconfig/keeper/example.toml b/integration-tests/testconfig/keeper/example.toml index 4efbf974827..7fe3bf26d0a 100644 --- a/integration-tests/testconfig/keeper/example.toml +++ b/integration-tests/testconfig/keeper/example.toml @@ -7,14 +7,6 @@ version="2.7.0" # if set to true will save logs even if test did not fail test_log_collect=false -[Logging.LogStream] -# supported targets: file, loki, in-memory. if empty no logs will be persistet -log_targets=["file"] -# context timeout for starting log producer and also time-frame for requesting logs -log_producer_timeout="10s" -# number of retries before log producer gives up and stops listening to logs -log_producer_retry_limit=10 - # if you want to use polygon_mumbial [Network] selected_networks=["polygon_mumbai"] diff --git a/integration-tests/testconfig/log_poller/example.toml b/integration-tests/testconfig/log_poller/example.toml index 78f3b5482d9..b94b6e0e202 100644 --- a/integration-tests/testconfig/log_poller/example.toml +++ b/integration-tests/testconfig/log_poller/example.toml @@ -7,14 +7,6 @@ version="2.7.0" # if set to true will save logs even if test did not fail test_log_collect=false -[Logging.LogStream] -# supported targets: file, loki, in-memory. if empty no logs will be persistet -log_targets=["file"] -# context timeout for starting log producer and also time-frame for requesting logs -log_producer_timeout="10s" -# number of retries before log producer gives up and stops listening to logs -log_producer_retry_limit=10 - # if you want to use polygon_mumbial [Network] selected_networks=["polygon_mumbai"] diff --git a/integration-tests/testconfig/node/example.toml b/integration-tests/testconfig/node/example.toml index bc5628e46b3..4635e40c037 100644 --- a/integration-tests/testconfig/node/example.toml +++ b/integration-tests/testconfig/node/example.toml @@ -7,14 +7,6 @@ version="2.7.0" # if set to true will save logs even if test did not fail test_log_collect=false -[Logging.LogStream] -# supported targets: file, loki, in-memory. if empty no logs will be persistet -log_targets=["file"] -# context timeout for starting log producer and also time-frame for requesting logs -log_producer_timeout="10s" -# number of retries before log producer gives up and stops listening to logs -log_producer_retry_limit=10 - # if you want to use polygon_mumbial [Network] selected_networks=["polygon_mumbai"] diff --git a/integration-tests/testconfig/ocr/example.toml b/integration-tests/testconfig/ocr/example.toml index 7c1c755567f..d1edd3a67fd 100644 --- a/integration-tests/testconfig/ocr/example.toml +++ b/integration-tests/testconfig/ocr/example.toml @@ -7,33 +7,6 @@ version="2.7.0" # if set to true will save logs even if test did not fail test_log_collect=false -[Logging.LogStream] -# supported targets: file, loki, in-memory. if empty no logs will be persistet -log_targets=["file"] -# context timeout for starting log producer and also time-frame for requesting logs -log_producer_timeout="10s" -# number of retries before log producer gives up and stops listening to logs -log_producer_retry_limit=10 - -[Logging.Loki] -tenant_id="tenant_id" -# full URL of Loki ingest endpoint -endpoint="https://loki.url/api/v3/push" -# currently only needed when using public instance -basic_auth_secret="loki-basic-auth" -# only needed for cloud grafana -bearer_token_secret="bearer_token" - -# LogStream will try to shorten Grafana URLs by default (if all 3 variables are set) -[Logging.Grafana] -# grafana url (trailing "/" will be stripped) -base_url="http://grafana.url" -# url of your grafana dashboard (prefix and suffix "/" are stirpped), example: /d/ad61652-2712-1722/my-dashboard -dashboard_url="/d/your-dashboard" -# Grafana dashboard uid to annotate. Find it in Dashboard Settings -> JSON Model -dashboard_uid="dashboard-uid-to-annotate" -bearer_token_secret="my-awesome-token" - # if you want to use polygon_mumbial [Network] selected_networks=["polygon_mumbai"] diff --git a/integration-tests/testconfig/ocr2/example.toml b/integration-tests/testconfig/ocr2/example.toml index 319f64d2580..679e4527a31 100644 --- a/integration-tests/testconfig/ocr2/example.toml +++ b/integration-tests/testconfig/ocr2/example.toml @@ -7,33 +7,6 @@ version="2.7.0" # if set to true will save logs even if test did not fail test_log_collect=false -[Logging.LogStream] -# supported targets: file, loki, in-memory. if empty no logs will be persistet -log_targets=["file"] -# context timeout for starting log producer and also time-frame for requesting logs -log_producer_timeout="10s" -# number of retries before log producer gives up and stops listening to logs -log_producer_retry_limit=10 - -[Logging.Loki] -tenant_id="tenant_id" -# full URL of Loki ingest endpoint -endpoint="https://loki.url/api/v3/push" -# currently only needed when using public instance -basic_auth_secret="loki-basic-auth" -# only needed for cloud grafana -bearer_token_secret="bearer_token" - -# LogStream will try to shorten Grafana URLs by default (if all 3 variables are set) -[Logging.Grafana] -# grafana url (trailing "/" will be stripped) -base_url="http://grafana.url" -# url of your grafana dashboard (prefix and suffix "/" are stirpped), example: /d/ad61652-2712-1722/my-dashboard -dashboard_url="/d/your-dashboard" -# Grafana dashboard uid to annotate. Find it in Dashboard Settings -> JSON Model -dashboard_uid="dashboard-uid-to-annotate" -bearer_token_secret="my-awesome-token" - # if you want to use polygon_mumbial [Network] selected_networks=["polygon_mumbai"] diff --git a/integration-tests/testconfig/testconfig.go b/integration-tests/testconfig/testconfig.go index 545818e3348..19e3f0b7ada 100644 --- a/integration-tests/testconfig/testconfig.go +++ b/integration-tests/testconfig/testconfig.go @@ -6,7 +6,6 @@ import ( "fmt" "math/big" "os" - "slices" "strings" "github.com/barkimedes/go-deepcopy" @@ -631,26 +630,6 @@ func (c *TestConfig) Validate() error { return fmt.Errorf("logging config must be set") } - if err := c.Logging.Validate(); err != nil { - return errors.Wrapf(err, "logging config validation failed") - } - - if c.Logging.Loki != nil { - if err := c.Logging.Loki.Validate(); err != nil { - return errors.Wrapf(err, "loki config validation failed") - } - } - - if c.Logging.LogStream != nil && slices.Contains(c.Logging.LogStream.LogTargets, "loki") { - if c.Logging.Loki == nil { - return fmt.Errorf("in order to use Loki as logging target you must set Loki config in logging config") - } - - if err := c.Logging.Loki.Validate(); err != nil { - return errors.Wrapf(err, "loki config validation failed") - } - } - if c.Pyroscope != nil { if err := c.Pyroscope.Validate(); err != nil { return errors.Wrapf(err, "pyroscope config validation failed") diff --git a/integration-tests/testconfig/vrfv2/example.toml b/integration-tests/testconfig/vrfv2/example.toml index 13af6dee620..3665c2f43cf 100644 --- a/integration-tests/testconfig/vrfv2/example.toml +++ b/integration-tests/testconfig/vrfv2/example.toml @@ -7,14 +7,6 @@ version="2.7.0" # if set to true will save logs even if test did not fail test_log_collect=false -[Logging.LogStream] -# supported targets: file, loki, in-memory. if empty no logs will be persistet -log_targets=["file"] -# context timeout for starting log producer and also time-frame for requesting logs -log_producer_timeout="10s" -# number of retries before log producer gives up and stops listening to logs -log_producer_retry_limit=10 - # if you want to use polygon_mumbial [Network] selected_networks=["polygon_mumbai"] diff --git a/integration-tests/testconfig/vrfv2plus/example.toml b/integration-tests/testconfig/vrfv2plus/example.toml index 160e9ba03a9..a45d53f67b8 100644 --- a/integration-tests/testconfig/vrfv2plus/example.toml +++ b/integration-tests/testconfig/vrfv2plus/example.toml @@ -7,14 +7,6 @@ version="2.7.0" # if set to true will save logs even if test did not fail test_log_collect=false -[Logging.LogStream] -# supported targets: file, loki, in-memory. if empty no logs will be persistet -log_targets=["file"] -# context timeout for starting log producer and also time-frame for requesting logs -log_producer_timeout="10s" -# number of retries before log producer gives up and stops listening to logs -log_producer_retry_limit=10 - # if you want to use polygon_mumbial [Network] selected_networks=["polygon_mumbai"] diff --git a/integration-tests/testsetups/ccip/test_helpers.go b/integration-tests/testsetups/ccip/test_helpers.go index 3112d738869..514a232bb80 100644 --- a/integration-tests/testsetups/ccip/test_helpers.go +++ b/integration-tests/testsetups/ccip/test_helpers.go @@ -8,20 +8,18 @@ import ( "os" "strconv" "testing" - "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" chainsel "github.com/smartcontractkit/chain-selectors" + "go.uber.org/zap/zapcore" - cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" - "github.com/smartcontractkit/chainlink-ccip/pluginconfig" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" ctfconfig "github.com/smartcontractkit/chainlink-testing-framework/lib/config" ctftestenv "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" "github.com/smartcontractkit/chainlink-testing-framework/lib/networks" + "github.com/smartcontractkit/chainlink-testing-framework/lib/testreporters" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/conversions" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" @@ -29,8 +27,6 @@ import ( "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" - commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" - commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" integrationnodes "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" evmcfg "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" corechainlink "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" @@ -57,235 +53,145 @@ import ( // DeployedLocalDevEnvironment is a helper struct for setting up a local dev environment with docker type DeployedLocalDevEnvironment struct { changeset.DeployedEnv - testEnv *test_env.CLClusterTestEnv - DON *devenv.DON + testEnv *test_env.CLClusterTestEnv + DON *devenv.DON + devEnvTestCfg tc.TestConfig + devEnvCfg *devenv.EnvironmentConfig } -func (d DeployedLocalDevEnvironment) RestartChainlinkNodes(t *testing.T) error { - errGrp := errgroup.Group{} - for _, n := range d.testEnv.ClCluster.Nodes { - n := n - errGrp.Go(func() error { - if err := n.Container.Terminate(testcontext.Get(t)); err != nil { - return err - } - err := n.RestartContainer() - if err != nil { - return err - } - return nil - }) - - } - return errGrp.Wait() +func (l *DeployedLocalDevEnvironment) DeployedEnvironment() changeset.DeployedEnv { + return l.DeployedEnv } -func NewLocalDevEnvironmentWithDefaultPrice(t *testing.T, lggr logger.Logger, tCfg *changeset.TestConfigs) (changeset.DeployedEnv, *test_env.CLClusterTestEnv, tc.TestConfig) { - return NewLocalDevEnvironment(t, lggr, changeset.MockLinkPrice, changeset.MockWethPrice, tCfg) -} - -func NewLocalDevEnvironment( - t *testing.T, - lggr logger.Logger, - linkPrice, wethPrice *big.Int, - tCfg *changeset.TestConfigs, -) (changeset.DeployedEnv, *test_env.CLClusterTestEnv, tc.TestConfig) { - if tCfg == nil { - // set to the default constructed value - tCfg = &changeset.TestConfigs{} - } - +func (l *DeployedLocalDevEnvironment) StartChains(t *testing.T, _ *changeset.TestConfigs) { + lggr := logger.TestLogger(t) ctx := testcontext.Get(t) - // create a local docker environment with simulated chains and job-distributor - // we cannot create the chainlink nodes yet as we need to deploy the capability registry first envConfig, testEnv, cfg := CreateDockerEnv(t) - require.NotNil(t, envConfig) - require.NotEmpty(t, envConfig.Chains, "chainConfigs should not be empty") - require.NotEmpty(t, envConfig.JDConfig, "jdUrl should not be empty") + l.devEnvTestCfg = cfg + l.testEnv = testEnv + l.devEnvCfg = envConfig users := make(map[uint64][]*bind.TransactOpts) for _, chain := range envConfig.Chains { - sel, err := chainsel.SelectorFromChainId(chain.ChainID) - require.NoError(t, err) - users[sel] = chain.Users + details, found := chainsel.ChainByEvmChainID(chain.ChainID) + require.Truef(t, found, "chain not found") + users[details.Selector] = chain.Users } - chains, err := devenv.NewChains(lggr, envConfig.Chains) - require.NoError(t, err) - // locate the home chain - homeChainSel := cfg.CCIP.GetHomeChainSelector() + homeChainSel := l.devEnvTestCfg.CCIP.GetHomeChainSelector() require.NotEmpty(t, homeChainSel, "homeChainSel should not be empty") - feedSel := cfg.CCIP.GetFeedChainSelector() + feedSel := l.devEnvTestCfg.CCIP.GetFeedChainSelector() require.NotEmpty(t, feedSel, "feedSel should not be empty") + chains, err := devenv.NewChains(lggr, envConfig.Chains) + require.NoError(t, err) replayBlocks, err := changeset.LatestBlocksByChain(ctx, chains) require.NoError(t, err) + l.DeployedEnv.Users = users + l.DeployedEnv.Env.Chains = chains + l.DeployedEnv.FeedChainSel = feedSel + l.DeployedEnv.HomeChainSel = homeChainSel + l.DeployedEnv.ReplayBlocks = replayBlocks +} - ab := deployment.NewMemoryAddressBook() - crConfig := changeset.DeployTestContracts(t, lggr, ab, homeChainSel, feedSel, chains, linkPrice, wethPrice) - - // start the chainlink nodes with the CR address - err = StartChainlinkNodes(t, envConfig, +func (l *DeployedLocalDevEnvironment) StartNodes(t *testing.T, _ *changeset.TestConfigs, crConfig deployment.CapabilityRegistryConfig) { + require.NotNil(t, l.testEnv, "docker env is empty, start chains first") + require.NotEmpty(t, l.devEnvTestCfg, "integration test config is empty, start chains first") + require.NotNil(t, l.devEnvCfg, "dev environment config is empty, start chains first") + err := StartChainlinkNodes(t, l.devEnvCfg, crConfig, - testEnv, cfg) + l.testEnv, l.devEnvTestCfg) require.NoError(t, err) - - e, don, err := devenv.NewEnvironment(func() context.Context { return ctx }, lggr, *envConfig) + ctx := testcontext.Get(t) + lggr := logger.TestLogger(t) + e, don, err := devenv.NewEnvironment(func() context.Context { return ctx }, lggr, *l.devEnvCfg) require.NoError(t, err) require.NotNil(t, e) - e.ExistingAddresses = ab + l.DON = don + l.DeployedEnv.Env = *e // fund the nodes zeroLogLggr := logging.GetTestLogger(t) - FundNodes(t, zeroLogLggr, testEnv, cfg, don.PluginNodes()) + FundNodes(t, zeroLogLggr, l.testEnv, l.devEnvTestCfg, don.PluginNodes()) +} - env := *e - envNodes, err := deployment.NodeInfo(env.NodeIDs, env.Offchain) - require.NoError(t, err) - allChains := env.AllChainSelectors() - var usdcChains []uint64 - if tCfg.IsUSDC { - usdcChains = allChains - } - mcmsCfg := make(map[uint64]commontypes.MCMSWithTimelockConfig) - for _, c := range env.AllChainSelectors() { - mcmsCfg[c] = commontypes.MCMSWithTimelockConfig{ - Canceller: commonchangeset.SingleGroupMCMS(t), - Bypasser: commonchangeset.SingleGroupMCMS(t), - Proposer: commonchangeset.SingleGroupMCMS(t), - TimelockExecutors: env.AllDeployerKeys(), - TimelockMinDelay: big.NewInt(0), - } - } - // Need to deploy prerequisites first so that we can form the USDC config - // no proposals to be made, timelock can be passed as nil here - env, err = commonchangeset.ApplyChangesets(t, env, nil, []commonchangeset.ChangesetApplication{ - { - Changeset: commonchangeset.WrapChangeSet(changeset.DeployHomeChain), - Config: changeset.DeployHomeChainConfig{ - HomeChainSel: homeChainSel, - RMNStaticConfig: changeset.NewTestRMNStaticConfig(), - RMNDynamicConfig: changeset.NewTestRMNDynamicConfig(), - NodeOperators: changeset.NewTestNodeOperator(chains[homeChainSel].DeployerKey.From), - NodeP2PIDsPerNodeOpAdmin: map[string][][32]byte{ - "NodeOperator": envNodes.NonBootstraps().PeerIDs(), - }, - }, - }, - { - Changeset: commonchangeset.WrapChangeSet(commonchangeset.DeployLinkToken), - Config: allChains, - }, - { - Changeset: commonchangeset.WrapChangeSet(changeset.DeployPrerequisites), - Config: changeset.DeployPrerequisiteConfig{ - ChainSelectors: allChains, - Opts: []changeset.PrerequisiteOpt{ - changeset.WithUSDCChains(usdcChains), - changeset.WithMulticall3(tCfg.IsMultiCall3), - }, - }, - }, - { - Changeset: commonchangeset.WrapChangeSet(commonchangeset.DeployMCMSWithTimelock), - Config: mcmsCfg, - }, - { - Changeset: commonchangeset.WrapChangeSet(changeset.DeployChainContracts), - Config: changeset.DeployChainContractsConfig{ - ChainSelectors: allChains, - HomeChainSelector: homeChainSel, - }, - }, - }) - require.NoError(t, err) - state, err := changeset.LoadOnchainState(env) +func (l *DeployedLocalDevEnvironment) MockUSDCAttestationServer(t *testing.T, isUSDCAttestationMissing bool) string { + err := ccipactions.SetMockServerWithUSDCAttestation(l.testEnv.MockAdapter, nil, isUSDCAttestationMissing) require.NoError(t, err) + return l.testEnv.MockAdapter.InternalEndpoint +} - var tokenDataProviders []pluginconfig.TokenDataObserverConfig - if len(usdcChains) > 0 { - var endpoint string - err = ccipactions.SetMockServerWithUSDCAttestation(testEnv.MockAdapter, nil, tCfg.IsUSDCAttestationMissing) - require.NoError(t, err) - endpoint = testEnv.MockAdapter.InternalEndpoint - cctpContracts := make(map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig) - for _, usdcChain := range usdcChains { - cctpContracts[cciptypes.ChainSelector(usdcChain)] = pluginconfig.USDCCCTPTokenConfig{ - SourcePoolAddress: state.Chains[usdcChain].USDCTokenPool.Address().String(), - SourceMessageTransmitterAddr: state.Chains[usdcChain].MockUSDCTransmitter.Address().String(), +func (l *DeployedLocalDevEnvironment) RestartChainlinkNodes(t *testing.T) error { + errGrp := errgroup.Group{} + for _, n := range l.testEnv.ClCluster.Nodes { + n := n + errGrp.Go(func() error { + if err := n.Container.Terminate(testcontext.Get(t)); err != nil { + return err } - } - tokenDataProviders = append(tokenDataProviders, pluginconfig.TokenDataObserverConfig{ - Type: pluginconfig.USDCCCTPHandlerType, - Version: "1.0", - USDCCCTPObserverConfig: &pluginconfig.USDCCCTPObserverConfig{ - Tokens: cctpContracts, - AttestationAPI: endpoint, - AttestationAPITimeout: commonconfig.MustNewDuration(time.Second), - AttestationAPIInterval: commonconfig.MustNewDuration(500 * time.Millisecond), - }}) - } + err := n.RestartContainer() + if err != nil { + return err + } + return nil + }) - // Build the per chain config. - tokenConfig := changeset.NewTestTokenConfig(state.Chains[feedSel].USDFeeds) - chainConfigs := make(map[uint64]changeset.CCIPOCRParams) - timelocksPerChain := make(map[uint64]*gethwrappers.RBACTimelock) - for _, chain := range allChains { - timelocksPerChain[chain] = state.Chains[chain].Timelock - tokenInfo := tokenConfig.GetTokenInfo(e.Logger, state.Chains[chain].LinkToken, state.Chains[chain].Weth9) - ocrParams := changeset.DefaultOCRParams(feedSel, tokenInfo, tokenDataProviders) - if tCfg.OCRConfigOverride != nil { - ocrParams = tCfg.OCRConfigOverride(ocrParams) - } - chainConfigs[chain] = ocrParams } - - // Deploy second set of changesets to deploy and configure the CCIP contracts. - env, err = commonchangeset.ApplyChangesets(t, env, timelocksPerChain, []commonchangeset.ChangesetApplication{ - { - Changeset: commonchangeset.WrapChangeSet(changeset.ConfigureNewChains), - Config: changeset.NewChainsConfig{ - HomeChainSel: homeChainSel, - FeedChainSel: feedSel, - ChainConfigByChain: chainConfigs, - }, - }, - { - Changeset: commonchangeset.WrapChangeSet(changeset.CCIPCapabilityJobspec), - }, - }) - require.NoError(t, err) - - // Ensure capreg logs are up to date. - changeset.ReplayLogs(t, e.Offchain, replayBlocks) - - return changeset.DeployedEnv{ - Env: env, - HomeChainSel: homeChainSel, - FeedChainSel: feedSel, - ReplayBlocks: replayBlocks, - Users: users, - }, testEnv, cfg + return errGrp.Wait() } -func NewLocalDevEnvironmentWithRMN( - t *testing.T, - lggr logger.Logger, - numRmnNodes int, -) (changeset.DeployedEnv, devenv.RMNCluster) { - tenv, dockerenv, testCfg := NewLocalDevEnvironmentWithDefaultPrice(t, lggr, nil) - l := logging.GetTestLogger(t) - config := GenerateTestRMNConfig(t, numRmnNodes, tenv, MustNetworksToRPCMap(dockerenv.EVMNetworks)) - require.NotNil(t, testCfg.CCIP) - rmnCluster, err := devenv.NewRMNCluster( - t, l, - []string{dockerenv.DockerNetwork.ID}, - config, - testCfg.CCIP.RMNConfig.GetProxyImage(), - testCfg.CCIP.RMNConfig.GetProxyVersion(), - testCfg.CCIP.RMNConfig.GetAFN2ProxyImage(), - testCfg.CCIP.RMNConfig.GetAFN2ProxyVersion(), - dockerenv.LogStream, - ) - require.NoError(t, err) - return tenv, *rmnCluster +// NewIntegrationEnvironment creates a new integration test environment based on the provided test config +// It can create a memory environment or a docker environment based on env var CCIP_V16_TEST_ENV +// By default, it creates a memory environment if env var CCIP_V16_TEST_ENV is not set +// if CCIP_V16_TEST_ENV is set to 'docker', it creates a docker environment with test config provided under testconfig/ccip/ccip.toml +// It also creates a RMN cluster if the test config has RMN enabled +// It returns the deployed environment and RMN cluster ( in case of RMN enabled) +func NewIntegrationEnvironment(t *testing.T, opts ...changeset.TestOps) (changeset.DeployedEnv, devenv.RMNCluster) { + testCfg := changeset.DefaultTestConfigs() + for _, opt := range opts { + opt(testCfg) + } + // check for EnvType env var + testCfg.MustSetEnvTypeOrDefault(t) + require.NoError(t, testCfg.Validate(), "invalid test config") + switch testCfg.Type { + case changeset.Memory: + memEnv := changeset.NewMemoryEnvironment(t, opts...) + return memEnv, devenv.RMNCluster{} + case changeset.Docker: + dockerEnv := &DeployedLocalDevEnvironment{} + if testCfg.RMNEnabled { + deployedEnv := changeset.NewEnvironmentWithJobsAndContracts(t, testCfg, dockerEnv) + l := logging.GetTestLogger(t) + require.NotNil(t, dockerEnv.testEnv, "empty docker environment") + config := GenerateTestRMNConfig(t, testCfg.NumOfRMNNodes, deployedEnv, MustNetworksToRPCMap(dockerEnv.testEnv.EVMNetworks)) + require.NotNil(t, dockerEnv.devEnvTestCfg.CCIP) + rmnCluster, err := devenv.NewRMNCluster( + t, l, + []string{dockerEnv.testEnv.DockerNetwork.ID}, + config, + dockerEnv.devEnvTestCfg.CCIP.RMNConfig.GetProxyImage(), + dockerEnv.devEnvTestCfg.CCIP.RMNConfig.GetProxyVersion(), + dockerEnv.devEnvTestCfg.CCIP.RMNConfig.GetAFN2ProxyImage(), + dockerEnv.devEnvTestCfg.CCIP.RMNConfig.GetAFN2ProxyVersion(), + ) + require.NoError(t, err) + return deployedEnv, *rmnCluster + } + if testCfg.CreateJobAndContracts { + deployedEnv := changeset.NewEnvironmentWithJobsAndContracts(t, testCfg, dockerEnv) + require.NotNil(t, dockerEnv.testEnv, "empty docker environment") + return deployedEnv, devenv.RMNCluster{} + } + if testCfg.CreateJob { + deployedEnv := changeset.NewEnvironmentWithJobs(t, testCfg, dockerEnv) + require.NotNil(t, dockerEnv.testEnv, "empty docker environment") + return deployedEnv, devenv.RMNCluster{} + } + deployedEnv := changeset.NewEnvironment(t, testCfg, dockerEnv) + require.NotNil(t, dockerEnv.testEnv, "empty docker environment") + return deployedEnv, devenv.RMNCluster{} + default: + require.Failf(t, "Type %s not supported in integration tests choose between %s and %s", string(testCfg.Type), changeset.Memory, changeset.Docker) + } + return changeset.DeployedEnv{}, devenv.RMNCluster{} } func MustNetworksToRPCMap(evmNetworks []*blockchain.EVMNetwork) map[uint64]string { @@ -418,11 +324,30 @@ func CreateDockerEnv(t *testing.T) ( } } + // ignore critical CL node logs until they are fixed, as otherwise tests will fail + var logScannerSettings = test_env.GetDefaultChainlinkNodeLogScannerSettingsWithExtraAllowedMessages(testreporters.NewAllowedLogMessage( + "No live RPC nodes available", + "CL nodes are started before simulated chains, so this is expected", + zapcore.DPanicLevel, + testreporters.WarnAboutAllowedMsgs_No), + testreporters.NewAllowedLogMessage( + "Error stopping job service", + "Possible lifecycle bug in chainlink: failed to close RMN home reader: has already been stopped: already stopped", + zapcore.DPanicLevel, + testreporters.WarnAboutAllowedMsgs_No), + testreporters.NewAllowedLogMessage( + "Shutdown grace period of 5s exceeded, closing DB and exiting...", + "Possible lifecycle bug in chainlink.", + zapcore.DPanicLevel, + testreporters.WarnAboutAllowedMsgs_No), + ) + builder := test_env.NewCLTestEnvBuilder(). WithTestConfig(&cfg). WithTestInstance(t). WithMockAdapter(). WithJobDistributor(cfg.CCIP.JobDistributorConfig). + WithChainlinkNodeLogScanner(logScannerSettings). WithStandardCleanup() // if private ethereum networks are provided, we will use them to create the test environment @@ -528,7 +453,6 @@ func StartChainlinkNodes( pointer.GetString(cfg.GetChainlinkImageConfig().Image), pointer.GetString(cfg.GetChainlinkImageConfig().Version), toml, - env.LogStream, test_env.WithPgDBOptions( ctftestenv.WithPostgresImageVersion(pointer.GetString(cfg.GetChainlinkImageConfig().PostgresVersion)), ), diff --git a/operator_ui/TAG b/operator_ui/TAG index 9f7a519e73b..b0d5ea37b87 100644 --- a/operator_ui/TAG +++ b/operator_ui/TAG @@ -1 +1 @@ -v0.8.0-da96bcb +v0.8.0-445b190 diff --git a/plugins/registrar.go b/plugins/registrar.go index 2a82f2a6204..8523d3980cc 100644 --- a/plugins/registrar.go +++ b/plugins/registrar.go @@ -6,7 +6,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/loop" ) -// RegistrarConfig generates contains static configuration inher +// RegistrarConfig generates contains static configuration type RegistrarConfig interface { RegisterLOOP(config CmdConfig) (func() *exec.Cmd, loop.GRPCOpts, error) UnregisterLOOP(ID string) diff --git a/tools/bin/goreleaser_utils b/tools/bin/goreleaser_utils index 52e37cefd51..0bf745d5a58 100755 --- a/tools/bin/goreleaser_utils +++ b/tools/bin/goreleaser_utils @@ -27,8 +27,10 @@ before_hook() { # linux_arm64, rather than being suffixless on native platforms if [ "$GOARCH" = "arm64" ]; then if [ -d "$BIN_DIR/linux_arm64" ]; then + cp "$BIN_DIR/linux_arm64"/chainlink* "$PLUGIN_DIR" + elif [ -d "$BIN_DIR/linux_arm64_v8.0" ]; then cp "$BIN_DIR/linux_arm64_v8.0"/chainlink* "$PLUGIN_DIR" - else + else cp "$BIN_DIR"/chainlink* "$PLUGIN_DIR" fi # Call patchelf --set-interpreter on all plugins diff --git a/tools/gomod-local-update/README.md b/tools/gomod-local-update/README.md new file mode 100644 index 00000000000..a49a663ecaa --- /dev/null +++ b/tools/gomod-local-update/README.md @@ -0,0 +1,41 @@ +# gomod-local-update + +Updates any module that is `replace`'d with a local path to have its required module version in `go.mod` to match the latest git SHA from a remote branch. + +Is meant to run within each directory where a `go.mod` file is present. + +## Configuration + +Command Line Flags: + +```shell +Optional: + -org-name Organization name (default: smartcontractkit) + -repo-name Repository name (default: chainlink) + -repo-remote Git remote to use (default: origin) + -branch-trunk Branch to get SHA from (default: develop) + -dry-run Preview changes without applying them (default: false) +``` + +## Installation + +The installed binary will be placed in your `$GOPATH/bin` directory. Make sure this directory is in your system's PATH to run the command from anywhere. From the root of this repository, run: + +```shell +go install ./tools/gomod-local-update/cmd/gomod-local-update +``` + +## Usage Examples + +Run from the root of a go module directory. + +```shell +gomod-local-update +``` + +Was designed to be used with [gomods](https://github.com/jmank88/gomods) like: + +```shell +gomods -w gomod-local-update +gomods tidy +``` diff --git a/tools/gomod-local-update/cmd/gomod-local-update/main.go b/tools/gomod-local-update/cmd/gomod-local-update/main.go new file mode 100644 index 00000000000..c471e8db776 --- /dev/null +++ b/tools/gomod-local-update/cmd/gomod-local-update/main.go @@ -0,0 +1,48 @@ +package main + +import ( + "fmt" + "log" + "os" + + "github.com/smartcontractkit/chainlink/v2/tools/gomod-local-update/internal/updater" +) + +const ( + goBinaryName = "gomod-local-update" +) + +var version = "dev" +var usage = fmt.Sprintf(`%s version %%s + +Usage: + cd /path/to/go/module + %s [flags] +`, goBinaryName, goBinaryName) + +func main() { + cfg, err := updater.ParseFlags(os.Args[1:], version) + if err != nil { + fmt.Fprintf(os.Stderr, usage, version) + log.Fatal(err) + } + + if cfg.ShowVersion { + fmt.Printf("%s version %s\n", goBinaryName, version) + os.Exit(0) + } + + if err := cfg.Validate(); err != nil { + fmt.Fprintf(os.Stderr, usage, version) + log.Fatal(err) + } + + u := updater.New( + cfg, + updater.NewSystemOperator(), + ) + + if err := u.Run(); err != nil { + log.Fatal(err) + } +} diff --git a/tools/gomod-local-update/internal/updater/config.go b/tools/gomod-local-update/internal/updater/config.go new file mode 100644 index 00000000000..444193b8086 --- /dev/null +++ b/tools/gomod-local-update/internal/updater/config.go @@ -0,0 +1,69 @@ +package updater + +import ( + "flag" + "fmt" +) + +const ( + DefaultRepoRemote = "origin" + DefaultBranchTrunk = "develop" + DefaultOrgName = "smartcontractkit" + DefaultRepoName = "chainlink" +) + +type Config struct { + RepoRemote string + BranchTrunk string + DryRun bool + ShowVersion bool + OrgName string + RepoName string +} + +func ParseFlags(args []string, version string) (*Config, error) { + flags := flag.NewFlagSet("default", flag.ContinueOnError) + + cfg := &Config{} + + flags.StringVar(&cfg.RepoRemote, "repo-remote", DefaultRepoRemote, "Git remote to use") + flags.StringVar(&cfg.BranchTrunk, "branch-trunk", DefaultBranchTrunk, "Branch to get SHA from") + flags.BoolVar(&cfg.DryRun, "dry-run", false, "Preview changes without applying them") + flags.BoolVar(&cfg.ShowVersion, "version", false, "Show version information") + flags.StringVar(&cfg.OrgName, "org-name", DefaultOrgName, "GitHub organization name") + flags.StringVar(&cfg.RepoName, "repo-name", DefaultRepoName, "GitHub repository name") + + if err := flags.Parse(args); err != nil { + return nil, err + } + + return cfg, nil +} + +func (c *Config) Validate() error { + if c.ShowVersion { + return nil + } + + if c.OrgName == "" { + return fmt.Errorf("%w: org name must be provided", ErrInvalidConfig) + } + if c.RepoName == "" { + return fmt.Errorf("%w: repo name must be provided", ErrInvalidConfig) + } + if c.RepoRemote == "" { + return fmt.Errorf("%w: repo remote must be provided", ErrInvalidConfig) + } + if c.BranchTrunk == "" { + return fmt.Errorf("%w: trunk branch must be provided", ErrInvalidConfig) + } + + if !gitRemoteRE.MatchString(c.RepoRemote) { + return fmt.Errorf("%w: git remote '%s' contains invalid characters", ErrInvalidConfig, c.RepoRemote) + } + if !gitBranchRE.MatchString(c.BranchTrunk) { + return fmt.Errorf("%w: git branch '%s' contains invalid characters", ErrInvalidConfig, c.BranchTrunk) + } + + return nil +} diff --git a/tools/gomod-local-update/internal/updater/config_test.go b/tools/gomod-local-update/internal/updater/config_test.go new file mode 100644 index 00000000000..21b867aea8d --- /dev/null +++ b/tools/gomod-local-update/internal/updater/config_test.go @@ -0,0 +1,177 @@ +package updater + +import ( + "errors" + "testing" +) + +func TestConfig_Validate(t *testing.T) { + tests := []struct { + name string + config *Config + wantErr bool + }{ + { + name: "valid config", + config: &Config{ + RepoRemote: DefaultRepoRemote, + BranchTrunk: DefaultBranchTrunk, + OrgName: DefaultOrgName, + RepoName: DefaultRepoName, + }, + wantErr: false, + }, + { + name: "version flag bypasses validation", + config: &Config{ + ShowVersion: true, + }, + wantErr: false, + }, + { + name: "missing repo remote", + config: &Config{ + BranchTrunk: DefaultBranchTrunk, + OrgName: DefaultOrgName, + RepoName: DefaultRepoName, + }, + wantErr: true, + }, + { + name: "missing branch trunk", + config: &Config{ + RepoRemote: DefaultRepoRemote, + OrgName: DefaultOrgName, + RepoName: DefaultRepoName, + }, + wantErr: true, + }, + { + name: "missing org name", + config: &Config{ + RepoRemote: DefaultRepoRemote, + BranchTrunk: DefaultBranchTrunk, + RepoName: DefaultRepoName, + }, + wantErr: true, + }, + { + name: "missing repo name", + config: &Config{ + RepoRemote: DefaultRepoRemote, + BranchTrunk: DefaultBranchTrunk, + OrgName: DefaultOrgName, + }, + wantErr: true, + }, + { + name: "invalid remote characters", + config: &Config{ + OrgName: "test", + RepoName: "test", + RepoRemote: "origin!@#", + BranchTrunk: "main", + }, + wantErr: true, + }, + { + name: "invalid branch characters", + config: &Config{ + OrgName: "test", + RepoName: "test", + RepoRemote: "origin", + BranchTrunk: "main!@#", + }, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.config.Validate() + if (err != nil) != tt.wantErr { + t.Errorf("Validate() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestConfig_ValidateErrorType(t *testing.T) { + cfg := &Config{ + RepoRemote: "invalid*remote", + BranchTrunk: "develop", + OrgName: "test", + RepoName: "test", + } + + err := cfg.Validate() + if err == nil { + t.Error("expected error due to invalid repo remote, got nil") + return + } + + if !errors.Is(err, ErrInvalidConfig) { + t.Errorf("expected error to be ErrInvalidConfig, got: %v", err) + } +} + +func TestParseFlags(t *testing.T) { + tests := []struct { + name string + args []string + wantCfg *Config + wantErr bool + }{ + { + name: "default flags", + args: []string{}, + wantCfg: &Config{ + RepoRemote: "origin", + BranchTrunk: "develop", + }, + wantErr: false, + }, + { + name: "show version", + args: []string{"-version"}, + wantCfg: &Config{ + ShowVersion: true, + RepoRemote: "origin", + BranchTrunk: "develop", + }, + wantErr: false, + }, + { + name: "custom remote and branch", + args: []string{"-repo-remote", "upstream", "-branch-trunk", "main"}, + wantCfg: &Config{ + RepoRemote: "upstream", + BranchTrunk: "main", + }, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ParseFlags(tt.args, "test-version") + if (err != nil) != tt.wantErr { + t.Errorf("ParseFlags() error = %v, wantErr %v", err, tt.wantErr) + return + } + if err != nil { + return + } + + if got.RepoRemote != tt.wantCfg.RepoRemote { + t.Errorf("ParseFlags() RepoRemote = %v, want %v", got.RepoRemote, tt.wantCfg.RepoRemote) + } + if got.BranchTrunk != tt.wantCfg.BranchTrunk { + t.Errorf("ParseFlags() BranchTrunk = %v, want %v", got.BranchTrunk, tt.wantCfg.BranchTrunk) + } + if got.ShowVersion != tt.wantCfg.ShowVersion { + t.Errorf("ParseFlags() ShowVersion = %v, want %v", got.ShowVersion, tt.wantCfg.ShowVersion) + } + }) + } +} diff --git a/tools/gomod-local-update/internal/updater/errors.go b/tools/gomod-local-update/internal/updater/errors.go new file mode 100644 index 00000000000..288eb49f66d --- /dev/null +++ b/tools/gomod-local-update/internal/updater/errors.go @@ -0,0 +1,11 @@ +package updater + +import "errors" + +var ( + // ErrModOperation indicates a failure in a module-related operation. + ErrModOperation = errors.New("module operation failed") + + // ErrInvalidConfig indicates invalid configuration parameters. + ErrInvalidConfig = errors.New("invalid configuration") +) diff --git a/tools/gomod-local-update/internal/updater/system_operator.go b/tools/gomod-local-update/internal/updater/system_operator.go new file mode 100644 index 00000000000..59ccfb15ed7 --- /dev/null +++ b/tools/gomod-local-update/internal/updater/system_operator.go @@ -0,0 +1,34 @@ +package updater + +import ( + "os" + "path/filepath" +) + +// SystemOperator provides an interface for file system operations. +type SystemOperator interface { + // ReadFile reads the entire contents of a file + ReadFile(path string) ([]byte, error) + // WriteFile writes data to a file with specific permissions + WriteFile(path string, data []byte, perm os.FileMode) error +} + +type systemOperator struct{} + +func NewSystemOperator() SystemOperator { + return &systemOperator{} +} + +func (s *systemOperator) ReadFile(path string) ([]byte, error) { + path = filepath.Clean(path) + return os.ReadFile(path) +} + +func (s *systemOperator) WriteFile(path string, data []byte, perm os.FileMode) error { + path = filepath.Clean(path) + dir := filepath.Dir(path) + if err := os.MkdirAll(dir, 0755); err != nil { + return err + } + return os.WriteFile(path, data, perm) +} diff --git a/tools/gomod-local-update/internal/updater/updater.go b/tools/gomod-local-update/internal/updater/updater.go new file mode 100644 index 00000000000..cfb873ed3ca --- /dev/null +++ b/tools/gomod-local-update/internal/updater/updater.go @@ -0,0 +1,253 @@ +package updater + +import ( + "context" + "errors" + "fmt" + "log" + "os" + "os/exec" + "regexp" + "strings" + "time" + + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" +) + +// gitExecutor allows mocking git commands in tests +type gitExecutor interface { + Command(ctx context.Context, args ...string) ([]byte, error) +} + +// systemGitExecutor executes git commands on the host system +type systemGitExecutor struct{} + +func (g *systemGitExecutor) Command(ctx context.Context, args ...string) ([]byte, error) { + return exec.CommandContext(ctx, "git", args...).Output() +} + +const ( + // File and mode constants + goModFile = "go.mod" + goModFileMode = 0644 + gitSHALength = 12 + gitTimeout = 30 * time.Second + gitTimeFormat = time.RFC3339 + + // Regex pattern constants + gitRemotePattern = `^[a-zA-Z0-9][-a-zA-Z0-9_.]*$` + gitBranchPattern = `^[a-zA-Z0-9][-a-zA-Z0-9/_]*$` + majorVersionPattern = `/v\d+$` + shaPattern = `^[a-fA-F0-9]{40}$` // SHA-1 hashes are 40 hexadecimal characters +) + +var ( + // Pre-compiled regular expressions + gitRemoteRE = regexp.MustCompile(gitRemotePattern) + gitBranchRE = regexp.MustCompile(gitBranchPattern) + gitShaRE = regexp.MustCompile(shaPattern) + majorVersionRE = regexp.MustCompile(majorVersionPattern) +) + +type Updater struct { + config *Config + system SystemOperator + git gitExecutor +} + +// New creates a new Updater +func New(config *Config, system SystemOperator) *Updater { + return &Updater{ + config: config, + system: system, + git: &systemGitExecutor{}, + } +} + +// validateSHA checks if the SHA consists of exactly 40 hexadecimal digits +func (u *Updater) validateSHA(sha string) error { + if !gitShaRE.MatchString(sha) { + return fmt.Errorf("%w: invalid git SHA '%s'", ErrInvalidConfig, sha) + } + return nil +} + +// getGitInfo retrieves the latest commit SHA and timestamp from a Git repository +func (u *Updater) getGitInfo(remote, branch string) (string, time.Time, error) { + ctx, cancel := context.WithTimeout(context.Background(), gitTimeout) + defer cancel() + + // Use u.git.Command for ls-remote + out, err := u.git.Command(ctx, "ls-remote", remote, "refs/heads/"+branch) + if err != nil { + return "", time.Time{}, fmt.Errorf("%w: failed to fetch commit SHA from %s/%s: %w", + ErrModOperation, remote, branch, err) + } + if len(out) == 0 { + return "", time.Time{}, fmt.Errorf("%w: no output from git ls-remote", ErrModOperation) + } + sha := strings.Split(string(out), "\t")[0] + if len(sha) == 0 { + return "", time.Time{}, fmt.Errorf("%w: empty SHA from git ls-remote", ErrModOperation) + } + + // Validate the SHA + if err := u.validateSHA(sha); err != nil { + return "", time.Time{}, err + } + + // Use u.git.Command for show + showOut, showErr := u.git.Command(ctx, "show", "-s", "--format=%cI", sha) + if showErr != nil { + return "", time.Time{}, fmt.Errorf("failed to get commit time: %w", showErr) + } + + commitTime, parseErr := time.Parse(gitTimeFormat, strings.TrimSpace(string(showOut))) + if parseErr != nil { + return "", time.Time{}, fmt.Errorf("failed to parse commit time: %w", parseErr) + } + + return sha[:gitSHALength], commitTime, nil +} + +// Run starts the module update process +func (u *Updater) Run() error { + logger := log.New(os.Stdout, "", log.LstdFlags) + + logger.Printf("info: auto-detecting modules with local replace directives") + + f, err := u.readModFile() + if err != nil { + return fmt.Errorf("%w: failed to read and parse go.mod file", ErrModOperation) + } + + // Auto-detect modules to update + modulesToUpdate, err := u.findLocalReplaceModules() + if err != nil { + return fmt.Errorf("%w: failed to detect local replace modules", ErrModOperation) + } + if len(modulesToUpdate) == 0 { + logger.Printf("info: no modules found to update in %s", f.Module.Mod.Path) + return nil + } + logger.Printf("info: found %d modules with local replace directives: %v", + len(modulesToUpdate), modulesToUpdate) + + // Get commit info once for all modules + sha, commitTime, err := u.getGitInfo(u.config.RepoRemote, u.config.BranchTrunk) + if err != nil { + if errors.Is(err, ErrInvalidConfig) { + return err + } + return fmt.Errorf("%w: failed to get git commit info from remote", ErrModOperation) + } + + // Update the modules in the same file handle + if err := u.updateGoMod(f, modulesToUpdate, sha, commitTime); err != nil { + return fmt.Errorf("%w: failed to update module versions in go.mod", ErrModOperation) + } + + return u.writeModFile(f) +} + +// updateGoMod updates the go.mod file with new pseudo-versions +func (u *Updater) updateGoMod(modFile *modfile.File, modulesToUpdate []string, sha string, commitTime time.Time) error { + for _, modulePath := range modulesToUpdate { + majorVersion := getMajorVersion(modulePath) + pseudoVersion := module.PseudoVersion(majorVersion, "", commitTime, sha[:gitSHALength]) + + // Find and update version + for _, req := range modFile.Require { + if req.Mod.Path == modulePath { + if u.config.DryRun { + log.Printf("[DRY RUN] Would update %s: %s => %s", modulePath, req.Mod.Version, pseudoVersion) + continue + } + + if err := modFile.AddRequire(modulePath, pseudoVersion); err != nil { + return fmt.Errorf("%w: failed to update version for module %s", + ErrModOperation, modulePath) + } + break + } + } + } + + return nil +} + +// getMajorVersion extracts the major version number from a module path +// Returns "v2" for /v2, "v0" for no version suffix +func getMajorVersion(modulePath string) string { + if match := majorVersionRE.FindString(modulePath); match != "" { + return strings.TrimPrefix(match, "/") + } + return "v0" +} + +// findLocalReplaceModules finds modules with local replace directives +func (u *Updater) findLocalReplaceModules() ([]string, error) { + modFile, err := u.readModFile() + if err != nil { + return nil, err + } + + orgPrefix := fmt.Sprintf("github.com/%s/%s", u.config.OrgName, u.config.RepoName) + localModules := make(map[string]bool) + var modules []string + + // First find all local replaces for our org + for _, rep := range modFile.Replace { + if strings.HasPrefix(rep.Old.Path, orgPrefix) && + rep.New.Version == "" && + isLocalPath(rep.New.Path) { + localModules[rep.Old.Path] = true + } + } + + // Then check requires that match our replaces + for _, req := range modFile.Require { + if localModules[req.Mod.Path] { + modules = append(modules, req.Mod.Path) + } + } + + return modules, nil +} + +// isLocalPath checks if the path is a local path +func isLocalPath(path string) bool { + return path == "." || path == ".." || + strings.HasPrefix(path, "./") || + strings.HasPrefix(path, "../") +} + +// readModFile reads the go.mod file +func (u *Updater) readModFile() (*modfile.File, error) { + content, err := u.system.ReadFile(goModFile) + if err != nil { + return nil, fmt.Errorf("unable to read go.mod: %w", err) + } + + modFile, err := modfile.Parse(goModFile, content, nil) + if err != nil { + return nil, fmt.Errorf("%w: invalid go.mod format: %w", ErrModOperation, err) + } + + return modFile, nil +} + +// writeModFile writes the go.mod file +func (u *Updater) writeModFile(modFile *modfile.File) error { + content, err := modFile.Format() + if err != nil { + return fmt.Errorf("%w: failed to format go.mod content", ErrModOperation) + } + + if err := u.system.WriteFile(goModFile, content, goModFileMode); err != nil { + return fmt.Errorf("%w: failed to write updated go.mod file", ErrModOperation) + } + + return nil +} diff --git a/tools/gomod-local-update/internal/updater/updater_test.go b/tools/gomod-local-update/internal/updater/updater_test.go new file mode 100644 index 00000000000..ba17024dd37 --- /dev/null +++ b/tools/gomod-local-update/internal/updater/updater_test.go @@ -0,0 +1,320 @@ +package updater + +import ( + "context" + "fmt" + "os" + "strings" + "testing" + "time" +) + +// mockGitExecutor simulates git commands for testing as an alternative to systemGitExecutor +type mockGitExecutor struct { + sha string + time time.Time +} + +func (m *mockGitExecutor) Command(ctx context.Context, args ...string) ([]byte, error) { + switch args[0] { + case "ls-remote": + // Validate inputs + if len(args) != 3 { + return nil, fmt.Errorf("expected 3 args for ls-remote, got %d", len(args)) + } + remote := args[1] + if remote == "invalid*remote" { + return nil, fmt.Errorf("%w: git remote '%s' contains invalid characters", ErrInvalidConfig, remote) + } + // Return a full 40-character SHA + fullSHA := fmt.Sprintf("%s%s", m.sha, strings.Repeat("0", 40-len(m.sha))) + return []byte(fullSHA + "\trefs/heads/" + args[2] + "\n"), nil + case "show": + if len(args) != 4 { + return nil, fmt.Errorf("unexpected show args: %v", args) + } + // Use the full SHA for validation + fullSHA := fmt.Sprintf("%s%s", m.sha, strings.Repeat("0", 40-len(m.sha))) + if args[3] != fullSHA { + return nil, fmt.Errorf("unexpected SHA: got %s, want %s", args[3], fullSHA) + } + return []byte(m.time.Format(gitTimeFormat) + "\n"), nil + default: + return nil, fmt.Errorf("unexpected git command: %v", args) + } +} + +type mockSystemOperator struct { + files map[string][]byte + err error +} + +func newMockSystemOperator() *mockSystemOperator { + return &mockSystemOperator{ + files: make(map[string][]byte), + } +} + +func (m *mockSystemOperator) ReadFile(path string) ([]byte, error) { + if m.err != nil { + return nil, m.err + } + content, ok := m.files[path] + if !ok { + return nil, fmt.Errorf("file not found: %s", path) + } + return content, nil +} + +func (m *mockSystemOperator) WriteFile(path string, data []byte, perm os.FileMode) error { + if m.err != nil { + return m.err + } + m.files[path] = data + return nil +} + +func TestUpdater_Run(t *testing.T) { + testTime := time.Date(2024, 11, 22, 18, 21, 10, 0, time.UTC) + // Use a full 40-character SHA + testSHA := "ac7a7395feed" + strings.Repeat("0", 28) + + tests := []struct { + name string + config *Config + sysOp *mockSystemOperator + wantErr bool + wantFile string + }{ + { + name: "successful update", + config: &Config{ + RepoRemote: "origin", + BranchTrunk: "develop", + OrgName: "smartcontractkit", + RepoName: "chainlink", + }, + sysOp: func() *mockSystemOperator { + m := newMockSystemOperator() + m.files["go.mod"] = []byte(`module test +require github.com/smartcontractkit/chainlink/v2 v2.0.0 +replace github.com/smartcontractkit/chainlink/v2 => ../ +`) + return m + }(), + wantErr: false, + wantFile: fmt.Sprintf(`module test + +require github.com/smartcontractkit/chainlink/v2 v2.0.0-20241122182110-%s + +replace github.com/smartcontractkit/chainlink/v2 => ../ +`, testSHA[:12]), + }, + { + name: "handles module with local replace", + config: &Config{ + RepoRemote: "origin", + BranchTrunk: "develop", + OrgName: "smartcontractkit", + RepoName: "chainlink", + }, + sysOp: func() *mockSystemOperator { + m := newMockSystemOperator() + m.files["go.mod"] = []byte(`module test +require github.com/smartcontractkit/chainlink/v2 v2.0.0 +replace github.com/smartcontractkit/chainlink/v2 => ../ +`) + return m + }(), + wantErr: false, + }, + { + name: "v1 module update", + config: &Config{ + RepoRemote: "origin", + BranchTrunk: "develop", + OrgName: "example", + RepoName: "mod", + }, + sysOp: func() *mockSystemOperator { + m := newMockSystemOperator() + m.files["go.mod"] = []byte(`module test +require github.com/example/mod v1.0.0 +`) + return m + }(), + wantErr: false, + }, + { + name: "updates v2 module with timestamp", + config: &Config{ + RepoRemote: "origin", + BranchTrunk: "develop", + OrgName: "smartcontractkit", + RepoName: "chainlink", + }, + sysOp: func() *mockSystemOperator { + m := newMockSystemOperator() + m.files["go.mod"] = []byte(`module test +require github.com/smartcontractkit/chainlink/v2 v2.0.0-20241119120536-03115e80382d +`) + return m + }(), + wantErr: false, + wantFile: fmt.Sprintf(`module test + +require github.com/smartcontractkit/chainlink/v2 v2.0.0-20241122182110-%s + +replace github.com/smartcontractkit/chainlink/v2 => ../ +`, testSHA[:12]), + }, + { + name: "updates v0 module with timestamp", + config: &Config{ + RepoRemote: "origin", + BranchTrunk: "develop", + OrgName: "smartcontractkit", + RepoName: "chainlink", + }, + sysOp: func() *mockSystemOperator { + m := newMockSystemOperator() + m.files["go.mod"] = []byte(`module test +require github.com/smartcontractkit/chainlink/deployment v0.0.0-20241119120536-03115e80382d +`) + return m + }(), + wantErr: false, + wantFile: fmt.Sprintf(`module test + +require github.com/smartcontractkit/chainlink/deployment v0.0.0-20241122182110-%s + +replace github.com/smartcontractkit/chainlink/deployment => ../ +`, testSHA[:12]), + }, + { + name: "handles multiple modules with different versions", + config: &Config{ + RepoRemote: "origin", + BranchTrunk: "develop", + OrgName: "smartcontractkit", + RepoName: "chainlink", + }, + sysOp: func() *mockSystemOperator { + m := newMockSystemOperator() + m.files["go.mod"] = []byte(`module test +require ( + github.com/smartcontractkit/chainlink/v2 v2.0.0-20241119120536-03115e80382d + github.com/smartcontractkit/chainlink/deployment v0.0.0-20241119120536-03115e80382d +) +`) + return m + }(), + wantErr: false, + wantFile: fmt.Sprintf(`module test + +require ( + github.com/smartcontractkit/chainlink/v2 v2.0.0-20241122182110-%s + github.com/smartcontractkit/chainlink/deployment v0.0.0-20241122182110-%s +) + +replace github.com/smartcontractkit/chainlink/v2 => ../ + +replace github.com/smartcontractkit/chainlink/deployment => ../ +`, testSHA[:12], testSHA[:12]), + }, + { + name: "updates v3 module with timestamp", + config: &Config{ + RepoRemote: "origin", + BranchTrunk: "develop", + OrgName: "smartcontractkit", + RepoName: "chainlink", + }, + sysOp: func() *mockSystemOperator { + m := newMockSystemOperator() + m.files["go.mod"] = []byte(`module test +require github.com/smartcontractkit/chainlink/v3 v3.0.0-20241119120536-03115e80382d +`) + return m + }(), + wantErr: false, + wantFile: fmt.Sprintf(`module test + +require github.com/smartcontractkit/chainlink/v3 v3.0.0-20241122182110-%s + +replace github.com/smartcontractkit/chainlink/v3 => ../ +`, testSHA[:12]), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + u := New(tt.config, tt.sysOp) + + // Add local replace directive for modules that should be updated + if !strings.Contains(tt.name, "v1 module update") { + modContent := string(tt.sysOp.files["go.mod"]) + for _, module := range []string{"v2", "v3", "deployment"} { + modulePath := fmt.Sprintf("github.com/%s/%s/%s", + tt.config.OrgName, tt.config.RepoName, module) + if strings.Contains(modContent, modulePath) && + !strings.Contains(modContent, "replace "+modulePath) { + modContent += fmt.Sprintf("\nreplace %s => ../\n", modulePath) + } + } + tt.sysOp.files["go.mod"] = []byte(modContent) + } + + // Override the git executor with our mock + u.git = &mockGitExecutor{ + sha: testSHA, + time: testTime, + } + err := u.Run() + if (err != nil) != tt.wantErr { + t.Errorf("Updater.Run() error = %v, wantErr %v", err, tt.wantErr) + } + + if tt.wantFile != "" { + got := string(tt.sysOp.files["go.mod"]) + if got != tt.wantFile { + t.Errorf("File content mismatch\nGot:\n%s\nWant:\n%s", got, tt.wantFile) + } + } + }) + } +} + +func TestUpdater_FindLocalReplaceModules(t *testing.T) { + sysOp := newMockSystemOperator() + sysOp.files["go.mod"] = []byte(` +module test +require ( + github.com/smartcontractkit/chainlink/v2 v2.0.0 + github.com/other/repo v1.0.0 +) +replace ( + github.com/smartcontractkit/chainlink/v2 => ../ + github.com/other/repo => ../other +)`) + + cfg := &Config{ + OrgName: "smartcontractkit", + RepoName: "chainlink", + } + + u := New(cfg, sysOp) + modules, err := u.findLocalReplaceModules() + if err != nil { + t.Errorf("unexpected error: %v", err) + return + } + + if len(modules) != 1 { + t.Errorf("expected 1 module, got %d", len(modules)) + return + } + if modules[0] != "github.com/smartcontractkit/chainlink/v2" { + t.Errorf("expected chainlink module, got %s", modules[0]) + } +}