diff --git a/.github/actions/install-cairo/action.yml b/.github/actions/install-cairo/action.yml index 9be721285..aec329067 100644 --- a/.github/actions/install-cairo/action.yml +++ b/.github/actions/install-cairo/action.yml @@ -4,11 +4,11 @@ description: A composite action that installs cairo and scarb binaries inputs: cairo_version: description: Cairo release version - default: "v1.0.0" + default: "v2.1.0" required: false scarb_version: description: Scarb release version - default: "v0.2.1" + default: "v0.6.0" required: false runs: diff --git a/.github/workflows/integration-tests-smoke.yml b/.github/workflows/integration-tests-smoke.yml index a6629040f..24e064afe 100644 --- a/.github/workflows/integration-tests-smoke.yml +++ b/.github/workflows/integration-tests-smoke.yml @@ -29,6 +29,15 @@ jobs: permissions: id-token: write contents: read + strategy: + matrix: + image: + - name: "" + dockerfile: core/chainlink.Dockerfile + tag-suffix: "" + - name: (plugins) + dockerfile: plugins/chainlink.Dockerfile + tag-suffix: -plugins steps: - name: Collect Metrics if: always() @@ -44,26 +53,27 @@ jobs: uses: smartcontractkit/chainlink-github-actions/docker/image-exists@2c9f401149f6c25fb632067b7e6626aebeee5d69 # v2.1.6 with: repository: chainlink - tag: starknet.${{ github.sha }} + tag: starknet.${{ github.sha }}${{ matrix.image.tag-suffix }} AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - - name: Build Image + - name: Build Image ${{ matrix.image.name }} if: steps.check-image.outputs.exists == 'false' # note using a temporary commit for build-image that works around the go get issues, replace when go get issues are fixed please uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@2c9f401149f6c25fb632067b7e6626aebeee5d69 with: cl_repo: smartcontractkit/chainlink cl_ref: ${{ github.event.inputs.cl_branch_ref }} + cl_dockerfile: ${{ matrix.image.dockerfile }} # commit of the caller branch dep_starknet_sha: ${{ github.event.pull_request.head.sha || github.sha }} - push_tag: ${{ env.CL_ECR }}:starknet.${{ github.sha }} + push_tag: ${{ env.CL_ECR }}:starknet.${{ github.sha }}${{ matrix.image.tag-suffix }} QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_PRIVATE_GHA_PULL: ${{ secrets.QA_PRIVATE_GHA_PULL }} - name: Print Chainlink Image Built run: | echo "### chainlink image tag used for this test run :link:" >> $GITHUB_STEP_SUMMARY - echo "\`starknet.${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY + echo "\`starknet.${{ github.sha }}${{ matrix.image.tag-suffix }}\`" >> $GITHUB_STEP_SUMMARY build_test_image: environment: integration @@ -97,6 +107,14 @@ jobs: runs-on: ubuntu20.04-16cores-64GB needs: [ build_custom_chainlink_image, build_test_image ] environment: integration + # these values need to match those used to build the chainlink image + strategy: + matrix: + image: + - name: "" + tag-suffix: "" + - name: (plugins) + tag-suffix: -plugins env: TEST_SUITE: smoke TEST_ARGS: -test.timeout 1h @@ -105,6 +123,7 @@ jobs: TTL: 3h TEST_DURATION: 15m NODE_COUNT: 5 + INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com permissions: checks: write pull-requests: write @@ -118,7 +137,7 @@ jobs: with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} - this-job-name: Run Smoke Tests + this-job-name: Run Smoke Tests ${{ matrix.image.name }} continue-on-error: true - name: Checkout the repo uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 @@ -126,13 +145,13 @@ jobs: uses: cachix/install-nix-action@29bd9290ef037a3ecbdafe83cbd2185e9dd0fa0a # v20 with: nix_path: nixpkgs=channel:nixos-unstable - - name: Run Tests + - name: Run Tests ${{ matrix.image.name }} uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@2c9f401149f6c25fb632067b7e6626aebeee5d69 with: test_command_to_run: nix develop -c make test-integration-smoke-ci test_download_vendor_packages_command: cd integration-tests && nix develop -c go mod download cl_repo: ${{ env.CL_ECR }} - cl_image_tag: starknet.${{ github.sha }} + cl_image_tag: starknet.${{ github.sha }}${{ matrix.image.tag-suffix }} token: ${{ secrets.GITHUB_TOKEN }} go_mod_path: ./integration-tests/go.mod QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} diff --git a/.github/workflows/integration-tests-soak.yml b/.github/workflows/integration-tests-soak.yml index dc62929ff..613ff9df0 100644 --- a/.github/workflows/integration-tests-soak.yml +++ b/.github/workflows/integration-tests-soak.yml @@ -99,6 +99,7 @@ jobs: TEST_SUITE: soak TEST_ARGS: -test.timeout ${{ github.event.inputs.ttl }} TEST_LOG_LEVEL: debug + INTERNAL_DOCKER_REPO: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com permissions: checks: write pull-requests: write diff --git a/.github/workflows/monitoring-build-push-ecr.yml b/.github/workflows/monitoring-build-push-ecr.yml index fc10259d5..8229dd684 100644 --- a/.github/workflows/monitoring-build-push-ecr.yml +++ b/.github/workflows/monitoring-build-push-ecr.yml @@ -6,6 +6,7 @@ on: - develop paths: - monitoring/** + - relayer/** jobs: build-and-publish-monitoring: @@ -46,7 +47,7 @@ jobs: uses: docker/build-push-action@c56af957549030174b10d6867f20e78cfd7debc5 # v3.2.0 with: push: true - context: monitoring + context: ./ file: monitoring/ops/Dockerfile tags: ${{ steps.docker_meta.outputs.tags }} labels: ${{ steps.docker_meta.outputs.labels }} diff --git a/Makefile b/Makefile index 624936d10..08b70f0d2 100644 --- a/Makefile +++ b/Makefile @@ -139,17 +139,13 @@ format-go-mod-tidy: .PHONY: format-cairo format-cairo: - find ./contracts/src -name "*.cairo" -type f \ - -exec cairo-format -i {} + - find ./examples -name "*.cairo" -type f \ - -exec cairo-format -i {} + + cairo-format -i ./contracts/src/**/*.cairo + cairo-format -i ./examples/**/*.cairo .PHONY: format-cairo-check format-cairo-check: - find ./contracts/src -name "*.cairo" -type f \ - -exec cairo-format -c {} + - find ./examples -name "*.cairo" -type f \ - -exec cairo-format -c {} + + cairo-format -c ./contracts/src/**/*.cairo + cairo-format -c ./examples/**/*.cairo .PHONY: format-ts format-ts: @@ -267,7 +263,7 @@ build-cairo-contracts: .PHONY: test-cairo-contracts test-cairo-contracts: - cd contracts && scarb run test + cd contracts && scarb test # TODO: this script needs to be replaced with a predefined K8s enviroment .PHONY: env-devnet-hardhat diff --git a/contracts/Scarb.toml b/contracts/Scarb.toml index 1cb06d12c..2d2a6323c 100644 --- a/contracts/Scarb.toml +++ b/contracts/Scarb.toml @@ -6,13 +6,15 @@ homepage = "https://github.com/smartcontractkit/chainlink-starknet" [scripts] sierra = "cairo-compile . -r" -test = "cairo-test --starknet ." # Add your own custom commands and run them with scarb run # Uncomment if you want to use dependencies # Note: currently testing doesn't work with dependencies [dependencies] -# quaireaux = { git = "https://github.com/keep-starknet-strange/quaireaux.git" } +starknet = ">=1.0.0" +openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", rev = "495ed8a" } # latest cairo-2 branch + +[lib] [[target.starknet-contract]] sierra = true @@ -21,7 +23,7 @@ casm = true # Unsupported compiled class format. Cairo 1.0 compiled class must contain the attribute `pythonic_hints`. casm-add-pythonic-hints = true -# Necessary to be used as a library by other scarb projects -[lib] -sierra = true # Enable Sierra codegen. -casm = true # Enable CASM codegen. +# this elevates the severity of disallowed libfuncs to compilation errors +# https://docs.swmansion.com/scarb/docs/starknet/contract-target#allowed-libfuncs-validation +allowed-libfuncs-deny = true +allowed-libfuncs-list.name = "audited" diff --git a/contracts/requirements.txt b/contracts/requirements.txt index 62885726a..08b297bfa 100644 --- a/contracts/requirements.txt +++ b/contracts/requirements.txt @@ -1,5 +1,5 @@ ecdsa fastecdsa sympy -cairo-lang>=0.11.1.1 -starknet-devnet>=0.5.2 +cairo-lang>=0.12.1a0 +starknet-devnet>=0.6.0a0 diff --git a/contracts/src/access_control/access_controller.cairo b/contracts/src/access_control/access_controller.cairo index 308fec845..edb73ada2 100644 --- a/contracts/src/access_control/access_controller.cairo +++ b/contracts/src/access_control/access_controller.cairo @@ -1,85 +1,91 @@ use starknet::ContractAddress; -#[abi] -trait IAccessController { - fn has_access(user: ContractAddress, data: Array) -> bool; - fn add_access(user: ContractAddress); - fn remove_access(user: ContractAddress); - fn enable_access_check(); - fn disable_access_check(); -} - -#[contract] +#[starknet::contract] mod AccessController { use starknet::ContractAddress; use starknet::class_hash::ClassHash; - use chainlink::libraries::access_control::AccessControl; - use chainlink::libraries::ownable::Ownable; + use chainlink::libraries::access_control::{AccessControl, IAccessController}; + use chainlink::libraries::ownable::{Ownable, IOwnable}; use chainlink::libraries::upgradeable::Upgradeable; - #[constructor] - fn constructor(owner_address: ContractAddress) { - Ownable::initializer(owner_address); - AccessControl::initializer(); - } - - #[view] - fn has_access(user: ContractAddress, data: Array) -> bool { - AccessControl::has_access(user, data) - } - - #[external] - fn add_access(user: ContractAddress) { - Ownable::assert_only_owner(); - AccessControl::add_access(user); - } - - #[external] - fn remove_access(user: ContractAddress) { - Ownable::assert_only_owner(); - AccessControl::remove_access(user); - } + #[storage] + struct Storage {} - #[external] - fn enable_access_check() { - Ownable::assert_only_owner(); - AccessControl::enable_access_check(); + #[constructor] + fn constructor(ref self: ContractState, owner_address: ContractAddress) { + let mut ownable = Ownable::unsafe_new_contract_state(); + Ownable::constructor(ref ownable, owner_address); + let mut access_control = AccessControl::unsafe_new_contract_state(); + AccessControl::constructor(ref access_control); } - #[external] - fn disable_access_check() { - Ownable::assert_only_owner(); - AccessControl::disable_access_check(); + #[external(v0)] + impl AccessControllerImpl of IAccessController { + fn has_access(self: @ContractState, user: ContractAddress, data: Array) -> bool { + let state = AccessControl::unsafe_new_contract_state(); + AccessControl::has_access(@state, user, data) + } + + fn add_access(ref self: ContractState, user: ContractAddress) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + let mut state = AccessControl::unsafe_new_contract_state(); + AccessControl::add_access(ref state, user); + } + + fn remove_access(ref self: ContractState, user: ContractAddress) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + let mut state = AccessControl::unsafe_new_contract_state(); + AccessControl::remove_access(ref state, user); + } + + fn enable_access_check(ref self: ContractState) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + let mut state = AccessControl::unsafe_new_contract_state(); + AccessControl::enable_access_check(ref state); + } + + fn disable_access_check(ref self: ContractState) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + let mut state = AccessControl::unsafe_new_contract_state(); + AccessControl::disable_access_check(ref state); + } } /// /// Ownable /// - #[view] - fn owner() -> ContractAddress { - Ownable::owner() - } - - #[view] - fn proposed_owner() -> ContractAddress { - Ownable::proposed_owner() - } - - #[external] - fn transfer_ownership(new_owner: ContractAddress) { - Ownable::transfer_ownership(new_owner); - } - - #[external] - fn accept_ownership() { - Ownable::accept_ownership(); - } - - #[external] - fn renounce_ownership() { - Ownable::renounce_ownership(); + #[external(v0)] + impl OwnableImpl of IOwnable { + fn owner(self: @ContractState) -> ContractAddress { + let state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::owner(@state) + } + + fn proposed_owner(self: @ContractState) -> ContractAddress { + let state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::proposed_owner(@state) + } + + fn transfer_ownership(ref self: ContractState, new_owner: ContractAddress) { + let mut state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::transfer_ownership(ref state, new_owner) + } + + fn accept_ownership(ref self: ContractState) { + let mut state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::accept_ownership(ref state) + } + + fn renounce_ownership(ref self: ContractState) { + let mut state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::renounce_ownership(ref state) + } } /// @@ -87,13 +93,14 @@ mod AccessController { /// #[view] - fn type_and_version() -> felt252 { + fn type_and_version(self: @ContractState) -> felt252 { 'AccessController 1.0.0' } - #[external] - fn upgrade(new_impl: ClassHash) { - Ownable::assert_only_owner(); + #[external(v0)] + fn upgrade(ref self: ContractState, new_impl: ClassHash) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); Upgradeable::upgrade(new_impl); } } diff --git a/contracts/src/account.cairo b/contracts/src/account.cairo deleted file mode 100644 index 68b4e3340..000000000 --- a/contracts/src/account.cairo +++ /dev/null @@ -1,2 +0,0 @@ -mod erc165; -mod account; diff --git a/contracts/src/account/account.cairo b/contracts/src/account/account.cairo deleted file mode 100644 index 71020ac46..000000000 --- a/contracts/src/account/account.cairo +++ /dev/null @@ -1,195 +0,0 @@ -// copied from https://github.com/OpenZeppelin/cairo-contracts/pull/616 - -use serde::Serde; -use array::ArrayTrait; -use starknet::ContractAddress; - -const ERC165_ACCOUNT_ID: u32 = 0xa66bd575_u32; -const ERC1271_VALIDATED: u32 = 0x1626ba7e_u32; - -const TRANSACTION_VERSION: felt252 = 1; -const QUERY_VERSION: felt252 = - 340282366920938463463374607431768211457; // 2**128 + TRANSACTION_VERSION - -#[inline(always)] -fn check_gas() { - match gas::withdraw_gas() { - Option::Some(_) => {}, - Option::None(_) => { - let mut data = ArrayTrait::new(); - data.append('Out of gas'); - panic(data); - }, - } -} - -#[derive(Serde, Drop)] -struct Call { - to: ContractAddress, - selector: felt252, - calldata: Array -} - -#[abi] -trait IAccount { - fn __validate__(calls: Array) -> felt252; - fn __validate_declare__(class_hash: felt252) -> felt252; -} - -#[account_contract] -mod Account { - use array::SpanTrait; - use array::ArrayTrait; - use box::BoxTrait; - use option::OptionTrait; - use zeroable::Zeroable; - use ecdsa::check_ecdsa_signature; - use serde::ArraySerde; - use starknet::get_tx_info; - use starknet::get_caller_address; - use starknet::get_contract_address; - - use super::Call; - use super::ERC165_ACCOUNT_ID; - use super::ERC1271_VALIDATED; - use super::TRANSACTION_VERSION; - use super::QUERY_VERSION; - use super::check_gas; - - use chainlink::account::erc165::ERC165; - - // - // Storage and Constructor - // - - struct Storage { - public_key: felt252, - } - - #[constructor] - fn constructor(_public_key: felt252) { - ERC165::register_interface(ERC165_ACCOUNT_ID); - public_key::write(_public_key); - } - - // - // Externals - // - - // todo: fix Span serde - // #[external] - fn __execute__(mut calls: Array) -> Array> { - // avoid calls from other contracts - // https://github.com/OpenZeppelin/cairo-contracts/issues/344 - let sender = get_caller_address(); - assert(sender.is_zero(), 'Account: invalid caller'); - - // check tx version - let tx_info = get_tx_info().unbox(); - let version = tx_info.version; - if version != TRANSACTION_VERSION { // > operator not defined for felt252 - assert(version == QUERY_VERSION, 'Account: invalid tx version'); - } - - _execute_calls(calls, ArrayTrait::new()) - } - - #[external] - fn __validate__(mut calls: Array) -> felt252 { - _validate_transaction() - } - - #[external] - fn __validate_declare__(class_hash: felt252) -> felt252 { - _validate_transaction() - } - - #[external] - fn __validate_deploy__( - class_hash: felt252, contract_address_salt: felt252, _public_key: felt252 - ) -> felt252 { - _validate_transaction() - } - - #[external] - fn set_public_key(new_public_key: felt252) { - _assert_only_self(); - public_key::write(new_public_key); - } - - // - // View - // - - #[view] - fn get_public_key() -> felt252 { - public_key::read() - } - - // todo: fix Span serde - // #[view] - fn is_valid_signature(message: felt252, signature: Span) -> u32 { - if _is_valid_signature(message, signature) { - ERC1271_VALIDATED - } else { - 0_u32 - } - } - - #[view] - fn supports_interface(interface_id: u32) -> bool { - ERC165::supports_interface(interface_id) - } - - // - // Internals - // - - #[internal] - fn _assert_only_self() { - let caller = get_caller_address(); - let self = get_contract_address(); - assert(self == caller, 'Account: unauthorized'); - } - - #[internal] - fn _validate_transaction() -> felt252 { - let tx_info = get_tx_info().unbox(); - let tx_hash = tx_info.transaction_hash; - let signature = tx_info.signature; - assert(_is_valid_signature(tx_hash, signature), 'Account: invalid signature'); - starknet::VALIDATED - } - - #[internal] - fn _is_valid_signature(message: felt252, signature: Span) -> bool { - let valid_length = signature.len() == 2_u32; - - valid_length & check_ecdsa_signature( - message, public_key::read(), *signature.at(0_u32), *signature.at(1_u32) - ) - } - - #[internal] - fn _execute_calls( - mut calls: Array, mut res: Array> - ) -> Array> { - check_gas(); - match calls.pop_front() { - Option::Some(call) => { - let _res = _execute_single_call(call); - res.append(_res); - return _execute_calls(calls, res); - }, - Option::None(_) => { - return res; - }, - } - } - - #[internal] - fn _execute_single_call(mut call: Call) -> Span { - let Call{to, selector, calldata } = call; - starknet::call_contract_syscall(to, selector, calldata.span()).unwrap_syscall() - } -} diff --git a/contracts/src/account/erc165.cairo b/contracts/src/account/erc165.cairo deleted file mode 100644 index ad764311a..000000000 --- a/contracts/src/account/erc165.cairo +++ /dev/null @@ -1,45 +0,0 @@ -// copied from https://github.com/OpenZeppelin/cairo-contracts/pull/583 - -const IERC165_ID: u32 = 0x01ffc9a7_u32; -const INVALID_ID: u32 = 0xffffffff_u32; - -trait IERC165 { - fn supports_interface(interface_id: u32) -> bool; -} - -#[contract] -mod ERC165 { - use super::IERC165_ID; - use super::INVALID_ID; - use super::IERC165; - - struct Storage { - supported_interfaces: LegacyMap, - } - - impl ERC165 of IERC165 { - fn supports_interface(interface_id: u32) -> bool { - if interface_id == IERC165_ID { - return true; - } - supported_interfaces::read(interface_id) - } - } - - #[view] - fn supports_interface(interface_id: u32) -> bool { - ERC165::supports_interface(interface_id) - } - - #[internal] - fn register_interface(interface_id: u32) { - assert(interface_id != INVALID_ID, 'Invalid id'); - supported_interfaces::write(interface_id, true); - } - - #[internal] - fn deregister_interface(interface_id: u32) { - assert(interface_id != IERC165_ID, 'Invalid id'); - supported_interfaces::write(interface_id, false); - } -} diff --git a/contracts/src/emergency/sequencer_uptime_feed.cairo b/contracts/src/emergency/sequencer_uptime_feed.cairo index ec6185299..df2420ee9 100644 --- a/contracts/src/emergency/sequencer_uptime_feed.cairo +++ b/contracts/src/emergency/sequencer_uptime_feed.cairo @@ -1,4 +1,12 @@ -#[contract] +use starknet::EthAddress; + +#[starknet::interface] +trait ISequencerUptimeFeed { + fn l1_sender(self: @TContractState) -> EthAddress; + fn set_l1_sender(ref self: TContractState, address: EthAddress); +} + +#[starknet::contract] mod SequencerUptimeFeed { use starknet::EthAddress; use starknet::EthAddressSerde; @@ -6,7 +14,6 @@ mod SequencerUptimeFeed { use starknet::Felt252TryIntoEthAddress; use starknet::EthAddressZeroable; use starknet::ContractAddress; - use starknet::StorageAccess; use starknet::StorageBaseAddress; use starknet::SyscallResult; use starknet::storage_read_syscall; @@ -20,14 +27,14 @@ mod SequencerUptimeFeed { use option::OptionTrait; use zeroable::Zeroable; - use chainlink::libraries::ownable::Ownable; - use chainlink::libraries::access_control::AccessControl; + use chainlink::libraries::ownable::{Ownable, IOwnable}; + use chainlink::libraries::access_control::{AccessControl, IAccessController}; use chainlink::ocr2::aggregator::Round; use chainlink::ocr2::aggregator::IAggregator; - use chainlink::ocr2::aggregator::Aggregator::Transmission; - use chainlink::ocr2::aggregator::Aggregator::TransmissionStorageAccess; + use chainlink::ocr2::aggregator::{Transmission}; use chainlink::libraries::upgradeable::Upgradeable; + #[storage] struct Storage { // l1 sender is an starknet validator ethereum address _l1_sender: felt252, @@ -37,27 +44,55 @@ mod SequencerUptimeFeed { } #[event] - fn RoundUpdated(status: u128, updated_at: u64) {} + #[derive(Drop, starknet::Event)] + enum Event { + RoundUpdated: RoundUpdated, + NewRound: NewRound, + AnswerUpdated: AnswerUpdated, + UpdateIgnored: UpdateIgnored, + L1SenderTransferred: L1SenderTransferred, + } - #[event] - fn NewRound(round_id: u128, started_by: ContractAddress, started_at: u64) {} + #[derive(Drop, starknet::Event)] + struct RoundUpdated { + status: u128, + updated_at: u64 + } - #[event] - fn AnswerUpdated(current: u128, round_id: u128, timestamp: u64) {} + #[derive(Drop, starknet::Event)] + struct NewRound { + round_id: u128, + started_by: ContractAddress, + started_at: u64 + } - #[event] - fn UpdateIgnored( - latest_status: u128, latest_timestamp: u64, incoming_status: u128, incoming_timestamp: u64 - ) {} + #[derive(Drop, starknet::Event)] + struct AnswerUpdated { + current: u128, + round_id: u128, + timestamp: u64 + } - #[event] - fn L1SenderTransferred(from_address: EthAddress, to_address: EthAddress) {} + #[derive(Drop, starknet::Event)] + struct UpdateIgnored { + latest_status: u128, + latest_timestamp: u64, + incoming_status: u128, + incoming_timestamp: u64 + } - impl Aggregator of IAggregator { - fn latest_round_data() -> Round { - _require_read_access(); - let latest_round_id = _latest_round_id::read(); - let round_transmission = _round_transmissions::read(latest_round_id); + #[derive(Drop, starknet::Event)] + struct L1SenderTransferred { + from_address: EthAddress, + to_address: EthAddress + } + + #[external(v0)] + impl AggregatorImpl of IAggregator { + fn latest_round_data(self: @ContractState) -> Round { + self._require_read_access(); + let latest_round_id = self._latest_round_id.read(); + let round_transmission = self._round_transmissions.read(latest_round_id); Round { round_id: latest_round_id.into(), answer: round_transmission.answer, @@ -67,10 +102,10 @@ mod SequencerUptimeFeed { } } - fn round_data(round_id: u128) -> Round { - _require_read_access(); - assert(round_id < _latest_round_id::read(), 'invalid round id'); - let round_transmission = _round_transmissions::read(round_id); + fn round_data(self: @ContractState, round_id: u128) -> Round { + self._require_read_access(); + assert(round_id < self._latest_round_id.read(), 'invalid round id'); + let round_transmission = self._round_transmissions.read(round_id); Round { round_id: round_id.into(), answer: round_transmission.answer, @@ -80,165 +115,165 @@ mod SequencerUptimeFeed { } } - fn description() -> felt252 { + fn description(self: @ContractState) -> felt252 { 'L2 Sequencer Uptime Status Feed' } - fn decimals() -> u8 { + fn decimals(self: @ContractState) -> u8 { 0_u8 } - fn type_and_version() -> felt252 { + fn type_and_version(self: @ContractState) -> felt252 { 'SequencerUptimeFeed 1.0.0' } } #[constructor] - fn constructor(initial_status: u128, owner_address: ContractAddress) { - _initializer(initial_status, owner_address); + fn constructor(ref self: ContractState, initial_status: u128, owner_address: ContractAddress) { + self._initializer(initial_status, owner_address); } #[l1_handler] - fn update_status(from_address: felt252, status: u128, timestamp: u64) { - assert(_l1_sender::read() == from_address, 'EXPECTED_FROM_BRIDGE_ONLY'); + fn update_status(ref self: ContractState, from_address: felt252, status: u128, timestamp: u64) { + assert(self._l1_sender.read() == from_address, 'EXPECTED_FROM_BRIDGE_ONLY'); - let latest_round_id = _latest_round_id::read(); - let latest_round = _round_transmissions::read(latest_round_id); + let latest_round_id = self._latest_round_id.read(); + let latest_round = self._round_transmissions.read(latest_round_id); if timestamp <= latest_round.observation_timestamp { - UpdateIgnored( - latest_round.answer, latest_round.transmission_timestamp, status, timestamp - ); + self + .emit( + Event::UpdateIgnored( + UpdateIgnored { + latest_status: latest_round.answer, + latest_timestamp: latest_round.transmission_timestamp, + incoming_status: status, + incoming_timestamp: timestamp + } + ) + ); return (); } if latest_round.answer == status { - _update_round(latest_round_id, latest_round); + self._update_round(latest_round_id, latest_round); } else { // only increment round when status flips let round_id = latest_round_id + 1_u128; - _record_round(round_id, status, timestamp); + self._record_round(round_id, status, timestamp); } } - #[external] - fn set_l1_sender(address: EthAddress) { - Ownable::assert_only_owner(); - - assert(!address.is_zero(), '0 address not allowed'); - - let old_address = _l1_sender::read(); - - if old_address != address.into() { - _l1_sender::write(address.into()); - L1SenderTransferred(old_address.try_into().unwrap(), address); + #[external(v0)] + impl SequencerUptimeFeedImpl of super::ISequencerUptimeFeed { + fn set_l1_sender(ref self: ContractState, address: EthAddress) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + + assert(!address.is_zero(), '0 address not allowed'); + + let old_address = self._l1_sender.read(); + + if old_address != address.into() { + self._l1_sender.write(address.into()); + self + .emit( + Event::L1SenderTransferred( + L1SenderTransferred { + from_address: old_address.try_into().unwrap(), to_address: address + } + ) + ); + } } - } - #[view] - fn l1_sender() -> EthAddress { - _l1_sender::read().try_into().unwrap() + fn l1_sender(self: @ContractState) -> EthAddress { + self._l1_sender.read().try_into().unwrap() + } } /// /// Upgradeable /// - #[external] - fn upgrade(new_impl: ClassHash) { - Ownable::assert_only_owner(); + #[external(v0)] + fn upgrade(ref self: ContractState, new_impl: ClassHash) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); Upgradeable::upgrade(new_impl) } - /// - /// Aggregator - /// - - #[view] - fn latest_round_data() -> Round { - Aggregator::latest_round_data() - } - - #[view] - fn round_data(round_id: u128) -> Round { - Aggregator::round_data(round_id) - } - - #[view] - fn description() -> felt252 { - Aggregator::description() - } - - #[view] - fn decimals() -> u8 { - Aggregator::decimals() - } - - #[view] - fn type_and_version() -> felt252 { - Aggregator::type_and_version() - } - /// /// Ownership /// - #[view] - fn owner() -> ContractAddress { - Ownable::owner() - } + #[external(v0)] + impl OwnableImpl of IOwnable { + fn owner(self: @ContractState) -> ContractAddress { + let state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::owner(@state) + } - #[view] - fn proposed_owner() -> ContractAddress { - Ownable::proposed_owner() - } + fn proposed_owner(self: @ContractState) -> ContractAddress { + let state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::proposed_owner(@state) + } - #[external] - fn transfer_ownership(new_owner: ContractAddress) { - Ownable::transfer_ownership(new_owner) - } + fn transfer_ownership(ref self: ContractState, new_owner: ContractAddress) { + let mut state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::transfer_ownership(ref state, new_owner) + } - #[external] - fn accept_ownership() { - Ownable::accept_ownership() - } + fn accept_ownership(ref self: ContractState) { + let mut state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::accept_ownership(ref state) + } - #[external] - fn renounce_ownership() { - Ownable::renounce_ownership() + fn renounce_ownership(ref self: ContractState) { + let mut state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::renounce_ownership(ref state) + } } + /// /// Access Control /// - #[view] - fn has_access(user: ContractAddress, data: Array) -> bool { - AccessControl::has_access(user, data) - } + #[external(v0)] + impl AccessControllerImpl of IAccessController { + fn has_access(self: @ContractState, user: ContractAddress, data: Array) -> bool { + let state = AccessControl::unsafe_new_contract_state(); + AccessControl::has_access(@state, user, data) + } - #[external] - fn add_access(user: ContractAddress) { - Ownable::assert_only_owner(); - AccessControl::add_access(user); - } + fn add_access(ref self: ContractState, user: ContractAddress) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + let mut state = AccessControl::unsafe_new_contract_state(); + AccessControl::add_access(ref state, user) + } - #[external] - fn remove_access(user: ContractAddress) { - Ownable::assert_only_owner(); - AccessControl::remove_access(user); - } + fn remove_access(ref self: ContractState, user: ContractAddress) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + let mut state = AccessControl::unsafe_new_contract_state(); + AccessControl::remove_access(ref state, user) + } - #[external] - fn enable_access_check() { - Ownable::assert_only_owner(); - AccessControl::enable_access_check(); - } + fn enable_access_check(ref self: ContractState) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + let mut state = AccessControl::unsafe_new_contract_state(); + AccessControl::enable_access_check(ref state) + } - #[external] - fn disable_access_check() { - Ownable::assert_only_owner(); - AccessControl::disable_access_check(); + fn disable_access_check(ref self: ContractState) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + let mut state = AccessControl::unsafe_new_contract_state(); + AccessControl::disable_access_check(ref state) + } } @@ -246,43 +281,68 @@ mod SequencerUptimeFeed { /// Internals /// - fn _require_read_access() { - let sender = starknet::info::get_caller_address(); - AccessControl::check_read_access(sender); - } - - fn _initializer(initial_status: u128, owner_address: ContractAddress) { - Ownable::initializer(owner_address); - AccessControl::initializer(); - let round_id = 1_u128; - let timestamp = starknet::info::get_block_timestamp(); - _record_round(round_id, initial_status, timestamp); - } - - fn _record_round(round_id: u128, status: u128, timestamp: u64) { - _latest_round_id::write(round_id); - let block_info = starknet::info::get_block_info().unbox(); - let block_number = block_info.block_number; - let block_timestamp = block_info.block_timestamp; - - let round = Transmission { - answer: status, - block_num: block_number, - observation_timestamp: timestamp, - transmission_timestamp: block_timestamp, - }; - _round_transmissions::write(round_id, round); - - let sender = starknet::info::get_caller_address(); + #[generate_trait] + impl Internals of InternalTrait { + fn _require_read_access(self: @ContractState) { + let sender = starknet::info::get_caller_address(); + let access_control = AccessControl::unsafe_new_contract_state(); + AccessControl::check_read_access(@access_control, sender); + } - NewRound(round_id, sender, timestamp); - AnswerUpdated(status, round_id, timestamp); - } + fn _initializer( + ref self: ContractState, initial_status: u128, owner_address: ContractAddress + ) { + let mut ownable = Ownable::unsafe_new_contract_state(); + Ownable::constructor(ref ownable, owner_address); + let mut access_control = AccessControl::unsafe_new_contract_state(); + AccessControl::constructor(ref access_control); + let round_id = 1_u128; + let timestamp = starknet::info::get_block_timestamp(); + self._record_round(round_id, initial_status, timestamp); + } - fn _update_round(round_id: u128, mut round: Transmission) { - round.transmission_timestamp = starknet::info::get_block_timestamp(); - _round_transmissions::write(round_id, round); + fn _record_round(ref self: ContractState, round_id: u128, status: u128, timestamp: u64) { + self._latest_round_id.write(round_id); + let block_info = starknet::info::get_block_info().unbox(); + let block_number = block_info.block_number; + let block_timestamp = block_info.block_timestamp; + + let round = Transmission { + answer: status, + block_num: block_number, + observation_timestamp: timestamp, + transmission_timestamp: block_timestamp, + }; + self._round_transmissions.write(round_id, round); + + let sender = starknet::info::get_caller_address(); + + self + .emit( + Event::NewRound( + NewRound { round_id: round_id, started_by: sender, started_at: timestamp } + ) + ); + self + .emit( + Event::AnswerUpdated( + AnswerUpdated { current: status, round_id: round_id, timestamp: timestamp } + ) + ); + } - RoundUpdated(round.answer, round.transmission_timestamp); + fn _update_round(ref self: ContractState, round_id: u128, mut round: Transmission) { + round.transmission_timestamp = starknet::info::get_block_timestamp(); + self._round_transmissions.write(round_id, round); + + self + .emit( + Event::RoundUpdated( + RoundUpdated { + status: round.answer, updated_at: round.transmission_timestamp + } + ) + ); + } } } diff --git a/contracts/src/lib.cairo b/contracts/src/lib.cairo index 35b37fdf7..b1661658f 100644 --- a/contracts/src/lib.cairo +++ b/contracts/src/lib.cairo @@ -6,7 +6,6 @@ mod utils; mod emergency; mod multisig; mod token; -mod account; mod access_control; #[cfg(test)] diff --git a/contracts/src/libraries/access_control.cairo b/contracts/src/libraries/access_control.cairo index 92e87e858..d3454d011 100644 --- a/contracts/src/libraries/access_control.cairo +++ b/contracts/src/libraries/access_control.cairo @@ -1,33 +1,57 @@ -#[contract] +use starknet::ContractAddress; +#[starknet::interface] +trait IAccessController { + fn has_access(self: @TContractState, user: ContractAddress, data: Array) -> bool; + fn add_access(ref self: TContractState, user: ContractAddress); + fn remove_access(ref self: TContractState, user: ContractAddress); + fn enable_access_check(ref self: TContractState); + fn disable_access_check(ref self: TContractState); +} + +#[starknet::contract] mod AccessControl { use starknet::ContractAddress; use starknet::class_hash::ClassHash; use zeroable::Zeroable; + #[storage] struct Storage { _check_enabled: bool, _access_list: LegacyMap, } #[event] - fn AddedAccess(user: ContractAddress) {} + #[derive(Drop, starknet::Event)] + enum Event { + AddedAccess: AddedAccess, + RemovedAccess: RemovedAccess, + AccessControlEnabled: AccessControlEnabled, + AccessControlDisabled: AccessControlDisabled, + } - #[event] - fn RemovedAccess(user: ContractAddress) {} + #[derive(Drop, starknet::Event)] + struct AddedAccess { + user: ContractAddress + } - #[event] - fn AccessControlEnabled() {} + #[derive(Drop, starknet::Event)] + struct RemovedAccess { + user: ContractAddress + } - #[event] - fn AccessControlDisabled() {} + #[derive(Drop, starknet::Event)] + struct AccessControlEnabled {} + + #[derive(Drop, starknet::Event)] + struct AccessControlDisabled {} - fn has_access(user: ContractAddress, data: Array) -> bool { - let has_access = _access_list::read(user); + fn has_access(self: @ContractState, user: ContractAddress, data: Array) -> bool { + let has_access = self._access_list.read(user); if has_access { return true; } - let check_enabled = _check_enabled::read(); + let check_enabled = self._check_enabled.read(); if !check_enabled { return true; } @@ -35,8 +59,8 @@ mod AccessControl { false } - fn has_read_access(user: ContractAddress, data: Array) -> bool { - let _has_access = has_access(user, data); + fn has_read_access(self: @ContractState, user: ContractAddress, data: Array) -> bool { + let _has_access = has_access(self, user, data); if _has_access { return true; } @@ -49,13 +73,13 @@ mod AccessControl { false } - fn check_access(user: ContractAddress) { - let allowed = has_access(user, ArrayTrait::new()); + fn check_access(self: @ContractState, user: ContractAddress) { + let allowed = has_access(self, user, ArrayTrait::new()); assert(allowed, 'user does not have access'); } - fn check_read_access(user: ContractAddress) { - let allowed = has_read_access(user, ArrayTrait::new()); + fn check_read_access(self: @ContractState, user: ContractAddress) { + let allowed = has_read_access(self, user, ArrayTrait::new()); assert(allowed, 'user does not have read access'); } @@ -63,40 +87,41 @@ mod AccessControl { // Unprotected // - fn initializer() { - _check_enabled::write(true); - AccessControlEnabled(); + #[constructor] + fn constructor(ref self: ContractState) { + self._check_enabled.write(true); + self.emit(Event::AccessControlEnabled(AccessControlEnabled {})); } - fn add_access(user: ContractAddress) { - let has_access = _access_list::read(user); + fn add_access(ref self: ContractState, user: ContractAddress) { + let has_access = self._access_list.read(user); if !has_access { - _access_list::write(user, true); - AddedAccess(user); + self._access_list.write(user, true); + self.emit(Event::AddedAccess(AddedAccess { user: user })); } } - fn remove_access(user: ContractAddress) { - let has_access = _access_list::read(user); + fn remove_access(ref self: ContractState, user: ContractAddress) { + let has_access = self._access_list.read(user); if has_access { - _access_list::write(user, false); - RemovedAccess(user); + self._access_list.write(user, false); + self.emit(Event::RemovedAccess(RemovedAccess { user: user })); } } - fn enable_access_check() { - let check_enabled = _check_enabled::read(); + fn enable_access_check(ref self: ContractState) { + let check_enabled = self._check_enabled.read(); if !check_enabled { - _check_enabled::write(true); - AccessControlEnabled(); + self._check_enabled.write(true); + self.emit(Event::AccessControlEnabled(AccessControlEnabled {})); } } - fn disable_access_check() { - let check_enabled = _check_enabled::read(); + fn disable_access_check(ref self: ContractState) { + let check_enabled = self._check_enabled.read(); if check_enabled { - _check_enabled::write(false); - AccessControlDisabled(); + self._check_enabled.write(false); + self.emit(Event::AccessControlDisabled(AccessControlDisabled {})); } } } diff --git a/contracts/src/libraries/ownable.cairo b/contracts/src/libraries/ownable.cairo index f40048b43..6646d5cf9 100644 --- a/contracts/src/libraries/ownable.cairo +++ b/contracts/src/libraries/ownable.cairo @@ -1,20 +1,21 @@ use starknet::ContractAddress; -#[abi] -trait IOwnable { - fn owner() -> ContractAddress; - fn proposed_owner() -> ContractAddress; - fn transfer_ownership(new_owner: ContractAddress); - fn accept_ownership(); - fn renounce_ownership(); +#[starknet::interface] +trait IOwnable { + fn owner(self: @TContractState) -> ContractAddress; + fn proposed_owner(self: @TContractState) -> ContractAddress; + fn transfer_ownership(ref self: TContractState, new_owner: ContractAddress); + fn accept_ownership(ref self: TContractState); + fn renounce_ownership(ref self: TContractState); } -#[contract] +#[starknet::contract] mod Ownable { use starknet::ContractAddress; use starknet::contract_address_const; use zeroable::Zeroable; + #[storage] struct Storage { _owner: ContractAddress, _proposed_owner: ContractAddress, @@ -35,75 +36,75 @@ mod Ownable { // #[constructor] - fn constructor(owner: ContractAddress) { - initializer(owner); - } - - fn initializer(owner: ContractAddress) { + fn constructor(ref self: ContractState, owner: ContractAddress) { assert(!owner.is_zero(), 'Ownable: transfer to 0'); - _accept_ownership_transfer(owner); + self._accept_ownership_transfer(owner); } // // Modifiers // - fn assert_only_owner() { - let owner = _owner::read(); + fn assert_only_owner(self: @ContractState) { + let owner = self._owner.read(); let caller = starknet::get_caller_address(); assert(caller == owner, 'Ownable: caller is not owner'); } - // - // Getters - // - #[view] - fn owner() -> ContractAddress { - _owner::read() - } - - #[view] - fn proposed_owner() -> ContractAddress { - _proposed_owner::read() - } - - // - // Setters - // - - #[external] - fn transfer_ownership(new_owner: ContractAddress) { - assert(!new_owner.is_zero(), 'Ownable: transfer to 0'); - assert_only_owner(); - - _proposed_owner::write(new_owner); - let previous_owner = _owner::read(); - OwnershipTransferRequested(previous_owner, new_owner); - } - - #[external] - fn accept_ownership() { - let proposed_owner = _proposed_owner::read(); - let caller = starknet::get_caller_address(); - - assert(caller == proposed_owner, 'Ownable: not proposed_owner'); - - _accept_ownership_transfer(proposed_owner); - } - - #[external] - fn renounce_ownership() { - assert_only_owner(); - _accept_ownership_transfer(starknet::contract_address_const::<0>()); + #[external(v0)] + impl OwnableImpl of super::IOwnable { + // + // Getters + // + fn owner(self: @ContractState) -> ContractAddress { + self._owner.read() + } + + fn proposed_owner(self: @ContractState) -> ContractAddress { + self._proposed_owner.read() + } + + // + // Setters + // + + fn transfer_ownership(ref self: ContractState, new_owner: ContractAddress) { + assert(!new_owner.is_zero(), 'Ownable: transfer to 0'); + assert_only_owner(@self); + + self._proposed_owner.write(new_owner); + let previous_owner = self._owner.read(); + OwnershipTransferRequested(previous_owner, new_owner); + } + + fn accept_ownership(ref self: ContractState) { + let proposed_owner = self._proposed_owner.read(); + let caller = starknet::get_caller_address(); + + assert(caller == proposed_owner, 'Ownable: not proposed_owner'); + + self._accept_ownership_transfer(proposed_owner); + } + + fn renounce_ownership(ref self: ContractState) { + assert_only_owner(@self); + self._accept_ownership_transfer(starknet::contract_address_const::<0>()); + } } // // Internal // - fn _accept_ownership_transfer(new_owner: starknet::ContractAddress) { - let previous_owner = _owner::read(); - _owner::write(new_owner); - _proposed_owner::write(starknet::contract_address_const::<0>()); - OwnershipTransferred(previous_owner, new_owner); + + #[generate_trait] + impl InternalImpl of InternalTrait { + fn _accept_ownership_transfer( + ref self: ContractState, new_owner: starknet::ContractAddress + ) { + let previous_owner = self._owner.read(); + self._owner.write(new_owner); + self._proposed_owner.write(starknet::contract_address_const::<0>()); + OwnershipTransferred(previous_owner, new_owner); + } } } diff --git a/contracts/src/libraries/token.cairo b/contracts/src/libraries/token.cairo index dc21a2d74..b6b4d8df3 100644 --- a/contracts/src/libraries/token.cairo +++ b/contracts/src/libraries/token.cairo @@ -1,2 +1 @@ -mod erc20; mod erc677; diff --git a/contracts/src/libraries/token/erc20.cairo b/contracts/src/libraries/token/erc20.cairo deleted file mode 100644 index 5c4512856..000000000 --- a/contracts/src/libraries/token/erc20.cairo +++ /dev/null @@ -1,207 +0,0 @@ -// taken from OpenZeppelin: https://github.com/OpenZeppelin/cairo-contracts/blob/42a160f1f011414e5044b5174e56dcaa73876aae/src/openzeppelin/token/erc20.cairo - -use starknet::ContractAddress; - -trait IERC20 { - fn name() -> felt252; - fn symbol() -> felt252; - fn decimals() -> u8; - fn total_supply() -> u256; - fn balance_of(account: ContractAddress) -> u256; - fn allowance(owner: ContractAddress, spender: ContractAddress) -> u256; - fn transfer(recipient: ContractAddress, amount: u256) -> bool; - fn transfer_from(sender: ContractAddress, recipient: ContractAddress, amount: u256) -> bool; - fn approve(spender: ContractAddress, amount: u256) -> bool; -} - -#[contract] -mod ERC20 { - use super::IERC20; - use starknet::get_caller_address; - use starknet::ContractAddress; - use zeroable::Zeroable; - - struct Storage { - _name: felt252, - _symbol: felt252, - _total_supply: u256, - _balances: LegacyMap, - _allowances: LegacyMap<(ContractAddress, ContractAddress), u256>, - } - - #[event] - fn Transfer(from: ContractAddress, to: ContractAddress, value: u256) {} - - #[event] - fn Approval(owner: ContractAddress, spender: ContractAddress, value: u256) {} - - impl ERC20 of IERC20 { - fn name() -> felt252 { - _name::read() - } - - fn symbol() -> felt252 { - _symbol::read() - } - - fn decimals() -> u8 { - 18_u8 - } - - fn total_supply() -> u256 { - _total_supply::read() - } - - fn balance_of(account: ContractAddress) -> u256 { - _balances::read(account) - } - - fn allowance(owner: ContractAddress, spender: ContractAddress) -> u256 { - _allowances::read((owner, spender)) - } - - fn transfer(recipient: ContractAddress, amount: u256) -> bool { - let sender = get_caller_address(); - _transfer(sender, recipient, amount); - true - } - - fn transfer_from( - sender: ContractAddress, recipient: ContractAddress, amount: u256 - ) -> bool { - let caller = get_caller_address(); - _spend_allowance(sender, caller, amount); - _transfer(sender, recipient, amount); - true - } - - fn approve(spender: ContractAddress, amount: u256) -> bool { - let caller = get_caller_address(); - _approve(caller, spender, amount); - true - } - } - - #[constructor] - fn constructor( - name: felt252, symbol: felt252, initial_supply: u256, recipient: ContractAddress - ) { - initializer(name, symbol); - _mint(recipient, initial_supply); - } - - #[view] - fn name() -> felt252 { - ERC20::name() - } - - #[view] - fn symbol() -> felt252 { - ERC20::symbol() - } - - #[view] - fn decimals() -> u8 { - ERC20::decimals() - } - - #[view] - fn total_supply() -> u256 { - ERC20::total_supply() - } - - #[view] - fn balance_of(account: ContractAddress) -> u256 { - ERC20::balance_of(account) - } - - #[view] - fn allowance(owner: ContractAddress, spender: ContractAddress) -> u256 { - ERC20::allowance(owner, spender) - } - - #[external] - fn transfer(recipient: ContractAddress, amount: u256) -> bool { - ERC20::transfer(recipient, amount) - } - - #[external] - fn transfer_from(sender: ContractAddress, recipient: ContractAddress, amount: u256) -> bool { - ERC20::transfer_from(sender, recipient, amount) - } - - #[external] - fn approve(spender: ContractAddress, amount: u256) -> bool { - ERC20::approve(spender, amount) - } - - #[external] - fn increase_allowance(spender: ContractAddress, added_value: u256) -> bool { - _increase_allowance(spender, added_value) - } - - #[external] - fn decrease_allowance(spender: ContractAddress, subtracted_value: u256) -> bool { - _decrease_allowance(spender, subtracted_value) - } - - /// - /// Internals - /// - - fn initializer(name_: felt252, symbol_: felt252) { - _name::write(name_); - _symbol::write(symbol_); - } - - fn _increase_allowance(spender: ContractAddress, added_value: u256) -> bool { - let caller = get_caller_address(); - _approve(caller, spender, _allowances::read((caller, spender)) + added_value); - true - } - - fn _decrease_allowance(spender: ContractAddress, subtracted_value: u256) -> bool { - let caller = get_caller_address(); - _approve(caller, spender, _allowances::read((caller, spender)) - subtracted_value); - true - } - - fn _mint(recipient: ContractAddress, amount: u256) { - assert(!recipient.is_zero(), 'ERC20: mint to 0'); - _total_supply::write(_total_supply::read() + amount); - _balances::write(recipient, _balances::read(recipient) + amount); - Transfer(Zeroable::zero(), recipient, amount); - } - - fn _burn(account: ContractAddress, amount: u256) { - assert(!account.is_zero(), 'ERC20: burn from 0'); - _total_supply::write(_total_supply::read() - amount); - _balances::write(account, _balances::read(account) - amount); - Transfer(account, Zeroable::zero(), amount); - } - - fn _approve(owner: ContractAddress, spender: ContractAddress, amount: u256) { - assert(!owner.is_zero(), 'ERC20: approve from 0'); - assert(!spender.is_zero(), 'ERC20: approve to 0'); - _allowances::write((owner, spender), amount); - Approval(owner, spender, amount); - } - - fn _transfer(sender: ContractAddress, recipient: ContractAddress, amount: u256) { - assert(!sender.is_zero(), 'ERC20: transfer from 0'); - assert(!recipient.is_zero(), 'ERC20: transfer to 0'); - _balances::write(sender, _balances::read(sender) - amount); - _balances::write(recipient, _balances::read(recipient) + amount); - Transfer(sender, recipient, amount); - } - - fn _spend_allowance(owner: ContractAddress, spender: ContractAddress, amount: u256) { - let current_allowance = _allowances::read((owner, spender)); - let ONES_MASK = 0xffffffffffffffffffffffffffffffff_u128; - let is_unlimited_allowance = - current_allowance.low == ONES_MASK & current_allowance.high == ONES_MASK; - if !is_unlimited_allowance { - _approve(owner, spender, current_allowance - amount); - } - } -} diff --git a/contracts/src/libraries/token/erc677.cairo b/contracts/src/libraries/token/erc677.cairo index e9e1dd080..c0f390218 100644 --- a/contracts/src/libraries/token/erc677.cairo +++ b/contracts/src/libraries/token/erc677.cairo @@ -1,16 +1,18 @@ use starknet::ContractAddress; -#[abi] -trait IERC677Receiver { - fn on_token_transfer(sender: ContractAddress, value: u256, data: Array); +#[starknet::interface] +trait IERC677Receiver { + fn on_token_transfer( + ref self: TContractState, sender: ContractAddress, value: u256, data: Array + ); // implements EIP-165, where function selectors are defined by Ethereum ABI using the ethereum function signatures - fn supports_interface(interface_id: u32) -> bool; + fn supports_interface(ref self: TContractState, interface_id: u32) -> bool; } - +#[starknet::contract] mod ERC677 { use starknet::ContractAddress; - use chainlink::libraries::token::erc20::ERC20; + use openzeppelin::token::erc20::ERC20; use array::ArrayTrait; use array::SpanTrait; use clone::Clone; @@ -22,14 +24,36 @@ mod ERC677 { // ethereum function selector of "onTokenTransfer(address,uint256,bytes)" const IERC677_RECEIVER_ID: u32 = 0xa4c0ed36_u32; + #[storage] + struct Storage {} + #[event] - fn Transfer(from: ContractAddress, to: ContractAddress, value: u256, data: Array) {} + #[derive(Drop, starknet::Event)] + enum Event { + Transfer: Transfer, + } + + #[derive(Drop, starknet::Event)] + struct Transfer { + from: ContractAddress, + to: ContractAddress, + value: u256, + data: Array + } - fn transfer_and_call(to: ContractAddress, value: u256, data: Array) -> bool { + fn transfer_and_call( + ref self: ContractState, to: ContractAddress, value: u256, data: Array + ) -> bool { let sender = starknet::info::get_caller_address(); - ERC20::transfer(to, value); - Transfer(sender, to, value, data.clone()); + let mut state = ERC20::unsafe_new_contract_state(); + ERC20::ERC20Impl::transfer(ref state, to, value); + self + .emit( + Event::Transfer( + Transfer { from: sender, to: to, value: value, data: data.clone(), } + ) + ); let receiver = IERC677ReceiverDispatcher { contract_address: to }; diff --git a/contracts/src/libraries/upgradeable.cairo b/contracts/src/libraries/upgradeable.cairo index e316b5205..22bfdb880 100644 --- a/contracts/src/libraries/upgradeable.cairo +++ b/contracts/src/libraries/upgradeable.cairo @@ -1,3 +1,15 @@ +use starknet::class_hash::ClassHash; + +#[starknet::interface] +trait IUpgradeable { + fn upgrade(ref self: TContractState, new_impl: ClassHash); +} + +#[derive(Drop, starknet::Event)] +struct Upgraded { + new_impl: ClassHash +} + mod Upgradeable { use zeroable::Zeroable; @@ -7,9 +19,6 @@ mod Upgradeable { use starknet::class_hash::ClassHash; use starknet::class_hash::ClassHashZeroable; - #[event] - fn Upgraded(new_impl: ClassHash) {} - // this method assumes replace_class_syscall has a very low possibility of being deprecated // but if it does, we will either have upgraded the contract to be non-upgradeable by then // because the starknet ecosystem has stabilized or we will be able to upgrade the contract to the proxy pattern @@ -17,6 +26,6 @@ mod Upgradeable { fn upgrade(new_impl: ClassHash) { assert(!new_impl.is_zero(), 'Class hash cannot be zero'); replace_class_syscall(new_impl).unwrap_syscall(); - Upgraded(new_impl); + // TODO: Upgraded(new_impl); } } diff --git a/contracts/src/multisig.cairo b/contracts/src/multisig.cairo index c569b75b1..01c32a942 100644 --- a/contracts/src/multisig.cairo +++ b/contracts/src/multisig.cairo @@ -1,10 +1,10 @@ use array::ArrayTrait; use option::OptionTrait; +use starknet::ContractAddress; +use starknet::class_hash::ClassHash; -fn assert_unique_values, -impl TDrop: Drop, -impl TPartialEq: PartialEq, +fn assert_unique_values< + T, impl TCopy: Copy, impl TDrop: Drop, impl TPartialEq: PartialEq, >( a: @Array:: ) { @@ -12,10 +12,8 @@ impl TPartialEq: PartialEq, _assert_unique_values_loop(a, len, 0_usize, 1_usize); } -fn _assert_unique_values_loop, -impl TDrop: Drop, -impl TPartialEq: PartialEq, +fn _assert_unique_values_loop< + T, impl TCopy: Copy, impl TDrop: Drop, impl TPartialEq: PartialEq, >( a: @Array::, len: usize, j: usize, k: usize ) { @@ -23,21 +21,56 @@ impl TPartialEq: PartialEq, return (); } if k >= len { - gas::withdraw_gas_all(get_builtin_costs()).expect('Out of gas'); _assert_unique_values_loop(a, len, j + 1_usize, j + 2_usize); return (); } let j_val = *a.at(j); let k_val = *a.at(k); assert(j_val != k_val, 'duplicate values'); - gas::withdraw_gas_all(get_builtin_costs()).expect('Out of gas'); _assert_unique_values_loop(a, len, j, k + 1_usize); } +#[derive(Copy, Drop, Serde, starknet::Store)] +struct Transaction { + to: ContractAddress, + function_selector: felt252, + calldata_len: usize, + executed: bool, + confirmations: usize, +} -#[contract] +#[starknet::interface] +trait IMultisig { + fn is_signer(self: @TContractState, address: ContractAddress) -> bool; + fn get_signers_len(self: @TContractState) -> usize; + fn get_signers(self: @TContractState) -> Array; + fn get_threshold(self: @TContractState) -> usize; + fn get_transactions_len(self: @TContractState) -> u128; + fn is_confirmed(self: @TContractState, nonce: u128, signer: ContractAddress) -> bool; + fn is_executed(self: @TContractState, nonce: u128) -> bool; + fn get_transaction(self: @TContractState, nonce: u128) -> (Transaction, Array::); + fn type_and_version(self: @TContractState) -> felt252; + fn upgrade(ref self: TContractState, new_impl: ClassHash); + fn submit_transaction( + ref self: TContractState, + to: ContractAddress, + function_selector: felt252, + calldata: Array + ); + fn confirm_transaction(ref self: TContractState, nonce: u128); + fn revoke_confirmation(ref self: TContractState, nonce: u128); + fn execute_transaction(ref self: TContractState, nonce: u128) -> Array; + fn set_threshold(ref self: TContractState, threshold: usize); + fn set_signers(ref self: TContractState, signers: Array); + fn set_signers_and_threshold( + ref self: TContractState, signers: Array, threshold: usize + ); +} + +#[starknet::contract] mod Multisig { use super::assert_unique_values; + use super::{Transaction}; use traits::Into; use traits::TryInto; @@ -49,7 +82,6 @@ mod Multisig { use starknet::ContractAddress; use starknet::ContractAddressIntoFelt252; use starknet::Felt252TryIntoContractAddress; - use starknet::StorageAccess; use starknet::StorageBaseAddress; use starknet::SyscallResult; use starknet::call_contract_syscall; @@ -63,92 +95,52 @@ mod Multisig { use chainlink::libraries::upgradeable::Upgradeable; #[event] - fn TransactionSubmitted(signer: ContractAddress, nonce: u128, to: ContractAddress) {} - - #[event] - fn TransactionConfirmed(signer: ContractAddress, nonce: u128) {} - - #[event] - fn ConfirmationRevoked(signer: ContractAddress, nonce: u128) {} + #[derive(Drop, starknet::Event)] + enum Event { + TransactionSubmitted: TransactionSubmitted, + TransactionConfirmed: TransactionConfirmed, + ConfirmationRevoked: ConfirmationRevoked, + TransactionExecuted: TransactionExecuted, + SignersSet: SignersSet, + ThresholdSet: ThresholdSet, + } - #[event] - fn TransactionExecuted(executor: ContractAddress, nonce: u128) {} + #[derive(Drop, starknet::Event)] + struct TransactionSubmitted { + signer: ContractAddress, + nonce: u128, + to: ContractAddress + } - #[event] - fn SignersSet(signers: Array) {} + #[derive(Drop, starknet::Event)] + struct TransactionConfirmed { + signer: ContractAddress, + nonce: u128 + } - #[event] - fn ThresholdSet(threshold: usize) {} + #[derive(Drop, starknet::Event)] + struct ConfirmationRevoked { + signer: ContractAddress, + nonce: u128 + } - #[derive(Copy, Drop, Serde)] - struct Transaction { - to: ContractAddress, - function_selector: felt252, - calldata_len: usize, - executed: bool, - confirmations: usize, + #[derive(Drop, starknet::Event)] + struct TransactionExecuted { + executor: ContractAddress, + nonce: u128 } - impl TransactionStorageAccess of StorageAccess { - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult:: { - Result::Ok( - Transaction { - to: storage_read_syscall( - address_domain, storage_address_from_base_and_offset(base, 0_u8) - )?.try_into().unwrap(), - function_selector: storage_read_syscall( - address_domain, storage_address_from_base_and_offset(base, 1_u8) - )?, - calldata_len: storage_read_syscall( - address_domain, storage_address_from_base_and_offset(base, 2_u8) - )?.try_into().unwrap(), - executed: if storage_read_syscall( - address_domain, storage_address_from_base_and_offset(base, 3_u8) - )? == 1 { - true - } else { - false - }, - confirmations: storage_read_syscall( - address_domain, storage_address_from_base_and_offset(base, 4_u8) - )?.try_into().unwrap(), - } - ) - } + #[derive(Drop, starknet::Event)] + struct SignersSet { + signers: Array + } - fn write( - address_domain: u32, base: StorageBaseAddress, value: Transaction - ) -> SyscallResult::<()> { - storage_write_syscall( - address_domain, storage_address_from_base_and_offset(base, 0_u8), value.to.into(), - )?; - storage_write_syscall( - address_domain, - storage_address_from_base_and_offset(base, 1_u8), - value.function_selector, - )?; - storage_write_syscall( - address_domain, - storage_address_from_base_and_offset(base, 2_u8), - value.calldata_len.into(), - )?; - storage_write_syscall( - address_domain, - storage_address_from_base_and_offset(base, 3_u8), - if value.executed { - 1 - } else { - 0 - }, - )?; - storage_write_syscall( - address_domain, - storage_address_from_base_and_offset(base, 4_u8), - value.confirmations.into() - ) - } + #[derive(Drop, starknet::Event)] + struct ThresholdSet { + threshold: usize } + #[storage] struct Storage { _threshold: usize, _signers: LegacyMap, @@ -162,359 +154,381 @@ mod Multisig { } #[constructor] - fn constructor(signers: Array, threshold: usize) { + fn constructor(ref self: ContractState, signers: Array, threshold: usize) { let signers_len = signers.len(); - _require_valid_threshold(threshold, signers_len); - _set_signers(signers, signers_len); - _set_threshold(threshold); - } - - /// Views - - #[view] - fn is_signer(address: ContractAddress) -> bool { - _is_signer::read(address) + self._require_valid_threshold(threshold, signers_len); + self._set_signers(signers, signers_len); + self._set_threshold(threshold); } - #[view] - fn get_signers_len() -> usize { - _signers_len::read() - } - - #[view] - fn get_signers() -> Array { - let signers_len = _signers_len::read(); - let mut signers = ArrayTrait::new(); - _get_signers_range(0_usize, signers_len, ref signers); - signers - } - - #[view] - fn get_threshold() -> usize { - _threshold::read() - } - - #[view] - fn get_transactions_len() -> u128 { - _next_nonce::read() - } + #[external(v0)] + impl MultisigImpl of super::IMultisig { + /// Views - #[view] - fn is_confirmed(nonce: u128, signer: ContractAddress) -> bool { - _is_confirmed::read((nonce, signer)) - } - - #[view] - fn is_executed(nonce: u128) -> bool { - let transaction = _transactions::read(nonce); - transaction.executed - } - - #[view] - fn get_transaction(nonce: u128) -> (Transaction, Array::) { - let transaction = _transactions::read(nonce); + fn is_signer(self: @ContractState, address: ContractAddress) -> bool { + self._is_signer.read(address) + } - let mut calldata = ArrayTrait::new(); - let calldata_len = transaction.calldata_len; - _get_transaction_calldata_range(nonce, 0_usize, calldata_len, ref calldata); + fn get_signers_len(self: @ContractState, ) -> usize { + self._signers_len.read() + } - (transaction, calldata) - } + fn get_signers(self: @ContractState) -> Array { + let signers_len = self._signers_len.read(); + let mut signers = ArrayTrait::new(); + self._get_signers_range(0_usize, signers_len, ref signers); + signers + } - #[view] - fn type_and_version() -> felt252 { - 'Multisig 1.0.0' - } + fn get_threshold(self: @ContractState, ) -> usize { + self._threshold.read() + } - /// Externals + fn get_transactions_len(self: @ContractState, ) -> u128 { + self._next_nonce.read() + } - #[external] - fn upgrade(new_impl: ClassHash) { - _require_multisig(); - Upgradeable::upgrade(new_impl) - } + fn is_confirmed(self: @ContractState, nonce: u128, signer: ContractAddress) -> bool { + self._is_confirmed.read((nonce, signer)) + } - #[external] - fn submit_transaction( - to: ContractAddress, function_selector: felt252, calldata: Array, - ) { - _require_signer(); - - let nonce = _next_nonce::read(); - let calldata_len = calldata.len(); - - let transaction = Transaction { - to: to, - function_selector: function_selector, - calldata_len: calldata_len, - executed: false, - confirmations: 0_usize - }; - _transactions::write(nonce, transaction); - - _set_transaction_calldata_range(nonce, 0_usize, calldata_len, @calldata); - - let caller = get_caller_address(); - TransactionSubmitted(caller, nonce, to); - _next_nonce::write(nonce + 1_u128); - } + fn is_executed(self: @ContractState, nonce: u128) -> bool { + let transaction = self._transactions.read(nonce); + transaction.executed + } - #[external] - fn confirm_transaction(nonce: u128) { - _require_signer(); - _require_tx_exists(nonce); - _require_tx_valid(nonce); - _require_not_executed(nonce); - _require_not_confirmed(nonce); + fn get_transaction(self: @ContractState, nonce: u128) -> (Transaction, Array::) { + let transaction = self._transactions.read(nonce); - // TODO: write a single field instead of the whole transaction? - let mut transaction = _transactions::read(nonce); - transaction.confirmations += 1_usize; - _transactions::write(nonce, transaction); + let mut calldata = ArrayTrait::new(); + let calldata_len = transaction.calldata_len; + self._get_transaction_calldata_range(nonce, 0_usize, calldata_len, ref calldata); - let caller = get_caller_address(); - _is_confirmed::write((nonce, caller), true); + (transaction, calldata) + } - TransactionConfirmed(caller, nonce); - } + fn type_and_version(self: @ContractState, ) -> felt252 { + 'Multisig 1.0.0' + } - #[external] - fn revoke_confirmation(nonce: u128) { - _require_signer(); - _require_tx_exists(nonce); - _require_tx_valid(nonce); - _require_not_executed(nonce); - _require_confirmed(nonce); + /// Externals - // TODO: write a single field instead of the whole transaction? - let mut transaction = _transactions::read(nonce); - transaction.confirmations -= 1_usize; - _transactions::write(nonce, transaction); + fn upgrade(ref self: ContractState, new_impl: ClassHash) { + self._require_multisig(); + Upgradeable::upgrade(new_impl) + } - let caller = get_caller_address(); - _is_confirmed::write((nonce, caller), false); + fn submit_transaction( + ref self: ContractState, + to: ContractAddress, + function_selector: felt252, + calldata: Array, + ) { + self._require_signer(); + + let nonce = self._next_nonce.read(); + let calldata_len = calldata.len(); + + let transaction = Transaction { + to: to, + function_selector: function_selector, + calldata_len: calldata_len, + executed: false, + confirmations: 0_usize + }; + self._transactions.write(nonce, transaction); + + self._set_transaction_calldata_range(nonce, 0_usize, calldata_len, @calldata); + + let caller = get_caller_address(); + self + .emit( + Event::TransactionSubmitted( + TransactionSubmitted { signer: caller, nonce: nonce, to: to } + ) + ); + self._next_nonce.write(nonce + 1_u128); + } - ConfirmationRevoked(caller, nonce); - } + fn confirm_transaction(ref self: ContractState, nonce: u128) { + self._require_signer(); + self._require_tx_exists(nonce); + self._require_tx_valid(nonce); + self._require_not_executed(nonce); + self._require_not_confirmed(nonce); + + // TODO: write a single field instead of the whole transaction? + let mut transaction = self._transactions.read(nonce); + transaction.confirmations += 1_usize; + self._transactions.write(nonce, transaction); + + let caller = get_caller_address(); + self._is_confirmed.write((nonce, caller), true); + + self + .emit( + Event::TransactionConfirmed( + TransactionConfirmed { signer: caller, nonce: nonce } + ) + ); + } - #[external] - fn execute_transaction(nonce: u128) -> Array { - _require_signer(); - _require_tx_exists(nonce); - _require_tx_valid(nonce); - _require_not_executed(nonce); + fn revoke_confirmation(ref self: ContractState, nonce: u128) { + self._require_signer(); + self._require_tx_exists(nonce); + self._require_tx_valid(nonce); + self._require_not_executed(nonce); + self._require_confirmed(nonce); + + // TODO: write a single field instead of the whole transaction? + let mut transaction = self._transactions.read(nonce); + transaction.confirmations -= 1_usize; + self._transactions.write(nonce, transaction); + + let caller = get_caller_address(); + self._is_confirmed.write((nonce, caller), false); + + self + .emit( + Event::ConfirmationRevoked(ConfirmationRevoked { signer: caller, nonce: nonce }) + ); + } - let mut transaction = _transactions::read(nonce); + fn execute_transaction(ref self: ContractState, nonce: u128) -> Array { + self._require_signer(); + self._require_tx_exists(nonce); + self._require_tx_valid(nonce); + self._require_not_executed(nonce); - let threshold = _threshold::read(); - assert(threshold <= transaction.confirmations, 'more confirmations required'); + let mut transaction = self._transactions.read(nonce); - let mut calldata = ArrayTrait::new(); - let calldata_len = transaction.calldata_len; - _get_transaction_calldata_range(nonce, 0_usize, calldata_len, ref calldata); + let threshold = self._threshold.read(); + assert(threshold <= transaction.confirmations, 'more confirmations required'); - transaction.executed = true; - _transactions::write(nonce, transaction); + let mut calldata = ArrayTrait::new(); + let calldata_len = transaction.calldata_len; + self._get_transaction_calldata_range(nonce, 0_usize, calldata_len, ref calldata); - let caller = get_caller_address(); - TransactionExecuted(caller, nonce); + transaction.executed = true; + self._transactions.write(nonce, transaction); - let response = call_contract_syscall( - transaction.to, transaction.function_selector, calldata.span() - ).unwrap_syscall(); + let caller = get_caller_address(); + self + .emit( + Event::TransactionExecuted( + TransactionExecuted { executor: caller, nonce: nonce } + ) + ); - // TODO: this shouldn't be necessary. call_contract_syscall returns a Span, which - // is a serialized result, but returning a Span results in an error: - // - // Trait has no implementation in context: core::serde::Serde::> - // - // Cairo docs also have an example that returns a Span: - // https://github.com/starkware-libs/cairo/blob/fe425d0893ff93a936bb3e8bbbac771033074bdb/docs/reference/src/components/cairo/modules/language_constructs/pages/contracts.adoc#L226 - ArrayTCloneImpl::clone(response.snapshot) - } + let response = call_contract_syscall( + transaction.to, transaction.function_selector, calldata.span() + ) + .unwrap_syscall(); + + // TODO: this shouldn't be necessary. call_contract_syscall returns a Span, which + // is a serialized result, but returning a Span results in an error: + // + // Trait has no implementation in context: core::serde::Serde::> + // + // Cairo docs also have an example that returns a Span: + // https://github.com/starkware-libs/cairo/blob/fe425d0893ff93a936bb3e8bbbac771033074bdb/docs/reference/src/components/cairo/modules/language_constructs/pages/contracts.adoc#L226 + ArrayTCloneImpl::clone(response.snapshot) + } - #[external] - fn set_threshold(threshold: usize) { - _require_multisig(); + fn set_threshold(ref self: ContractState, threshold: usize) { + self._require_multisig(); - let signers_len = _signers_len::read(); - _require_valid_threshold(threshold, signers_len); + let signers_len = self._signers_len.read(); + self._require_valid_threshold(threshold, signers_len); - _update_tx_valid_since(); + self._update_tx_valid_since(); - _set_threshold(threshold); - } + self._set_threshold(threshold); + } - #[external] - fn set_signers(signers: Array) { - _require_multisig(); + fn set_signers(ref self: ContractState, signers: Array) { + self._require_multisig(); - _update_tx_valid_since(); + self._update_tx_valid_since(); - let signers_len = signers.len(); - _set_signers(signers, signers_len); + let signers_len = signers.len(); + self._set_signers(signers, signers_len); - let threshold = _threshold::read(); + let threshold = self._threshold.read(); - if signers_len < threshold { - _require_valid_threshold(signers_len, signers_len); - _set_threshold(signers_len); + if signers_len < threshold { + self._require_valid_threshold(signers_len, signers_len); + self._set_threshold(signers_len); + } } - } - #[external] - fn set_signers_and_threshold(signers: Array, threshold: usize) { - _require_multisig(); + fn set_signers_and_threshold( + ref self: ContractState, signers: Array, threshold: usize + ) { + self._require_multisig(); - let signers_len = signers.len(); - _require_valid_threshold(threshold, signers_len); + let signers_len = signers.len(); + self._require_valid_threshold(threshold, signers_len); - _update_tx_valid_since(); + self._update_tx_valid_since(); - _set_signers(signers, signers_len); - _set_threshold(threshold); + self._set_signers(signers, signers_len); + self._set_threshold(threshold); + } } /// Internals - fn _set_signers(signers: Array, signers_len: usize) { - _require_unique_signers(@signers); - - let old_signers_len = _signers_len::read(); - _clean_signers_range(0_usize, old_signers_len); + #[generate_trait] + impl InternalImpl of InternalTrait { + fn _set_signers( + ref self: ContractState, signers: Array, signers_len: usize + ) { + self._require_unique_signers(@signers); - _signers_len::write(signers_len); - _set_signers_range(0_usize, signers_len, @signers); + let old_signers_len = self._signers_len.read(); + self._clean_signers_range(0_usize, old_signers_len); - SignersSet(signers); - } + self._signers_len.write(signers_len); + self._set_signers_range(0_usize, signers_len, @signers); - fn _clean_signers_range(index: usize, len: usize) { - if index >= len { - return (); + self.emit(Event::SignersSet(SignersSet { signers: signers })); } - let signer = _signers::read(index); - _is_signer::write(signer, false); - _signers::write(index, Zeroable::zero()); + fn _clean_signers_range(ref self: ContractState, index: usize, len: usize) { + if index >= len { + return (); + } - gas::withdraw_gas_all(get_builtin_costs()).expect('Out of gas'); - _clean_signers_range(index + 1_usize, len); - } + let signer = self._signers.read(index); + self._is_signer.write(signer, false); + self._signers.write(index, Zeroable::zero()); - fn _set_signers_range(index: usize, len: usize, signers: @Array) { - if index >= len { - return (); + self._clean_signers_range(index + 1_usize, len); } - let signer = *signers.at(index); - _signers::write(index, signer); - _is_signer::write(signer, true); + fn _set_signers_range( + ref self: ContractState, index: usize, len: usize, signers: @Array + ) { + if index >= len { + return (); + } - gas::withdraw_gas_all(get_builtin_costs()).expect('Out of gas'); - _set_signers_range(index + 1_usize, len, signers); - } + let signer = *signers.at(index); + self._signers.write(index, signer); + self._is_signer.write(signer, true); - fn _get_signers_range(index: usize, len: usize, ref signers: Array) { - if index >= len { - return (); + self._set_signers_range(index + 1_usize, len, signers); } - let signer = _signers::read(index); - signers.append(signer); + fn _get_signers_range( + self: @ContractState, index: usize, len: usize, ref signers: Array + ) { + if index >= len { + return (); + } - gas::withdraw_gas_all(get_builtin_costs()).expect('Out of gas'); - _get_signers_range(index + 1_usize, len, ref signers); - } + let signer = self._signers.read(index); + signers.append(signer); - fn _set_transaction_calldata_range( - nonce: u128, index: usize, len: usize, calldata: @Array - ) { - if index >= len { - return (); + self._get_signers_range(index + 1_usize, len, ref signers); } - let calldata_arg = *calldata.at(index); - _transaction_calldata::write((nonce, index), calldata_arg); + fn _set_transaction_calldata_range( + ref self: ContractState, + nonce: u128, + index: usize, + len: usize, + calldata: @Array + ) { + if index >= len { + return (); + } - gas::withdraw_gas_all(get_builtin_costs()).expect('Out of gas'); - _set_transaction_calldata_range(nonce, index + 1_usize, len, calldata); - } + let calldata_arg = *calldata.at(index); + self._transaction_calldata.write((nonce, index), calldata_arg); - fn _get_transaction_calldata_range( - nonce: u128, index: usize, len: usize, ref calldata: Array - ) { - if index >= len { - return (); + self._set_transaction_calldata_range(nonce, index + 1_usize, len, calldata); } - let calldata_arg = _transaction_calldata::read((nonce, index)); - calldata.append(calldata_arg); + fn _get_transaction_calldata_range( + self: @ContractState, + nonce: u128, + index: usize, + len: usize, + ref calldata: Array + ) { + if index >= len { + return (); + } + + let calldata_arg = self._transaction_calldata.read((nonce, index)); + calldata.append(calldata_arg); - gas::withdraw_gas_all(get_builtin_costs()).expect('Out of gas'); - _get_transaction_calldata_range(nonce, index + 1_usize, len, ref calldata); - } + self._get_transaction_calldata_range(nonce, index + 1_usize, len, ref calldata); + } - fn _set_threshold(threshold: usize) { - _threshold::write(threshold); - ThresholdSet(threshold); - } + fn _set_threshold(ref self: ContractState, threshold: usize) { + self._threshold.write(threshold); + self.emit(Event::ThresholdSet(ThresholdSet { threshold: threshold })); + } - fn _update_tx_valid_since() { - let tx_valid_since = _next_nonce::read(); - _tx_valid_since::write(tx_valid_since); - } + fn _update_tx_valid_since(ref self: ContractState) { + let tx_valid_since = self._next_nonce.read(); + self._tx_valid_since.write(tx_valid_since); + } - fn _require_signer() { - let caller = get_caller_address(); - let is_signer = _is_signer::read(caller); - assert(is_signer, 'invalid signer'); - } + fn _require_signer(self: @ContractState) { + let caller = get_caller_address(); + let is_signer = self._is_signer.read(caller); + assert(is_signer, 'invalid signer'); + } - fn _require_tx_exists(nonce: u128) { - let next_nonce = _next_nonce::read(); - assert(nonce < next_nonce, 'transaction does not exist'); - } + fn _require_tx_exists(self: @ContractState, nonce: u128) { + let next_nonce = self._next_nonce.read(); + assert(nonce < next_nonce, 'transaction does not exist'); + } - fn _require_not_executed(nonce: u128) { - let transaction = _transactions::read(nonce); - assert(!transaction.executed, 'transaction already executed'); - } + fn _require_not_executed(self: @ContractState, nonce: u128) { + let transaction = self._transactions.read(nonce); + assert(!transaction.executed, 'transaction already executed'); + } - fn _require_not_confirmed(nonce: u128) { - let caller = get_caller_address(); - let is_confirmed = _is_confirmed::read((nonce, caller)); - assert(!is_confirmed, 'transaction already confirmed'); - } + fn _require_not_confirmed(self: @ContractState, nonce: u128) { + let caller = get_caller_address(); + let is_confirmed = self._is_confirmed.read((nonce, caller)); + assert(!is_confirmed, 'transaction already confirmed'); + } - fn _require_confirmed(nonce: u128) { - let caller = get_caller_address(); - let is_confirmed = _is_confirmed::read((nonce, caller)); - assert(is_confirmed, 'transaction not confirmed'); - } + fn _require_confirmed(self: @ContractState, nonce: u128) { + let caller = get_caller_address(); + let is_confirmed = self._is_confirmed.read((nonce, caller)); + assert(is_confirmed, 'transaction not confirmed'); + } - fn _require_unique_signers(signers: @Array) { - assert_unique_values(signers); - } + fn _require_unique_signers(self: @ContractState, signers: @Array) { + assert_unique_values(signers); + } - fn _require_tx_valid(nonce: u128) { - let tx_valid_since = _tx_valid_since::read(); - assert(tx_valid_since <= nonce, 'transaction invalid'); - } + fn _require_tx_valid(self: @ContractState, nonce: u128) { + let tx_valid_since = self._tx_valid_since.read(); + assert(tx_valid_since <= nonce, 'transaction invalid'); + } - fn _require_multisig() { - let caller = get_caller_address(); - let contract = get_contract_address(); - assert(caller == contract, 'only multisig allowed'); - } + fn _require_multisig(self: @ContractState) { + let caller = get_caller_address(); + let contract = get_contract_address(); + assert(caller == contract, 'only multisig allowed'); + } - fn _require_valid_threshold(threshold: usize, signers_len: usize) { - if threshold == 0_usize { - if signers_len == 0_usize { - return (); + fn _require_valid_threshold(self: @ContractState, threshold: usize, signers_len: usize) { + if threshold == 0_usize { + if signers_len == 0_usize { + return (); + } } - } - assert(threshold >= 1_usize, 'invalid threshold, too small'); - assert(threshold <= signers_len, 'invalid threshold, too large'); + assert(threshold >= 1_usize, 'invalid threshold, too small'); + assert(threshold <= signers_len, 'invalid threshold, too large'); + } } } diff --git a/contracts/src/ocr2/aggregator.cairo b/contracts/src/ocr2/aggregator.cairo index 655a078ff..650805abf 100644 --- a/contracts/src/ocr2/aggregator.cairo +++ b/contracts/src/ocr2/aggregator.cairo @@ -1,3 +1,5 @@ +use starknet::ContractAddress; + #[derive(Copy, Drop, Serde, PartialEq)] struct Round { // used as u128 internally, but necessary for phase-prefixed round ids as returned by proxy @@ -8,12 +10,119 @@ struct Round { updated_at: u64, } -trait IAggregator { - fn latest_round_data() -> Round; - fn round_data(round_id: u128) -> Round; - fn description() -> felt252; - fn decimals() -> u8; - fn type_and_version() -> felt252; +#[derive(Copy, Drop, Serde, starknet::Store)] +struct Transmission { + answer: u128, + block_num: u64, + observation_timestamp: u64, + transmission_timestamp: u64, +} + +// TODO: reintroduce custom storage to save on space +// impl TransmissionStorageAccess of StorageAccess { +// fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult:: { +// let block_num_and_answer = storage_read_syscall( +// address_domain, storage_address_from_base_and_offset(base, 0_u8) +// )?; +// let (block_num, answer) = split_felt(block_num_and_answer); +// let timestamps = storage_read_syscall( +// address_domain, storage_address_from_base_and_offset(base, 1_u8) +// )?; +// let (observation_timestamp, transmission_timestamp) = split_felt(timestamps); + +// Result::Ok( +// Transmission { +// answer, +// block_num: block_num.try_into().unwrap(), +// observation_timestamp: observation_timestamp.try_into().unwrap(), +// transmission_timestamp: transmission_timestamp.try_into().unwrap(), +// } +// ) +// } +// +// fn write( +// address_domain: u32, base: StorageBaseAddress, value: Transmission +// ) -> SyscallResult::<()> { +// let block_num_and_answer = value.block_num.into() * SHIFT_128 + value.answer.into(); +// let timestamps = value.observation_timestamp.into() * SHIFT_128 +// + value.transmission_timestamp.into(); +// storage_write_syscall( +// address_domain, +// storage_address_from_base_and_offset(base, 0_u8), +// block_num_and_answer +// )?; +// storage_write_syscall( +// address_domain, storage_address_from_base_and_offset(base, 1_u8), timestamps +// ) +// } +// } + +#[starknet::interface] +trait IAggregator { + fn latest_round_data(self: @TContractState) -> Round; + fn round_data(self: @TContractState, round_id: u128) -> Round; + fn description(self: @TContractState) -> felt252; + fn decimals(self: @TContractState) -> u8; + fn type_and_version(self: @TContractState) -> felt252; +} + +#[derive(Copy, Drop, Serde)] +struct OracleConfig { + signer: felt252, + transmitter: ContractAddress, +} + +impl OracleConfigLegacyHash of LegacyHash { + fn hash(mut state: felt252, value: OracleConfig) -> felt252 { + state = LegacyHash::hash(state, value.signer); + state = LegacyHash::hash(state, value.transmitter); + state + } +} + +#[starknet::interface] +trait Configuration { + fn set_config( + ref self: TContractState, + oracles: Array, + f: u8, + onchain_config: Array, + offchain_config_version: u64, + offchain_config: Array, + ) -> felt252; // digest + fn latest_config_details(self: @TContractState) -> (u64, u64, felt252); + fn transmitters(self: @TContractState) -> Array; +} + +use Aggregator::{BillingConfig, BillingConfigSerde}; + +#[starknet::interface] +trait Billing { + fn set_billing_access_controller(ref self: TContractState, access_controller: ContractAddress); + fn set_billing(ref self: TContractState, config: Aggregator::BillingConfig); + fn billing(self: @TContractState) -> Aggregator::BillingConfig; + // + fn withdraw_payment(ref self: TContractState, transmitter: ContractAddress); + fn owed_payment(self: @TContractState, transmitter: ContractAddress) -> u128; + fn withdraw_funds(ref self: TContractState, recipient: ContractAddress, amount: u256); + fn link_available_for_payment( + self: @TContractState + ) -> (bool, u128); // (is negative, absolute difference) +} + +#[derive(Copy, Drop, Serde)] +struct PayeeConfig { + transmitter: ContractAddress, + payee: ContractAddress, +} + +#[starknet::interface] +trait PayeeManagement { + fn set_payees(ref self: TContractState, payees: Array); + fn transfer_payeeship( + ref self: TContractState, transmitter: ContractAddress, proposed: ContractAddress + ); + fn accept_payeeship(ref self: TContractState, transmitter: ContractAddress); } use array::ArrayTrait; @@ -28,7 +137,6 @@ fn hash_span, impl TCopy: Copy>( match item { Option::Some(x) => { let s = LegacyHash::hash(state, *x); - gas::withdraw_gas_all(get_builtin_costs()).expect('Out of gas'); hash_span(s, value) }, Option::None(_) => state, @@ -40,7 +148,6 @@ fn pow(n: u128, m: u128) -> u128 { if m == 0_u128 { return 1_u128; } - gas::withdraw_gas_all(get_builtin_costs()).expect('Out of gas'); let half = pow(n, m / 2_u128); let total = half * half; // TODO: check if (& 1) is cheaper @@ -58,10 +165,10 @@ impl SpanLegacyHash, impl TCopy: Copy> of Legacy } } -#[contract] +#[starknet::contract] mod Aggregator { - use super::IAggregator; use super::Round; + use super::{Transmission}; use super::SpanLegacyHash; use super::pow; @@ -80,7 +187,6 @@ mod Aggregator { use starknet::ContractAddress; use starknet::get_caller_address; use starknet::contract_address_const; - use starknet::StorageAccess; use starknet::StorageBaseAddress; use starknet::SyscallResult; use starknet::storage_read_syscall; @@ -89,34 +195,35 @@ mod Aggregator { use starknet::class_hash::ClassHash; use chainlink::utils::split_felt; - use chainlink::libraries::ownable::Ownable; + use chainlink::libraries::ownable::{Ownable, IOwnable}; use chainlink::libraries::access_control::AccessControl; use chainlink::libraries::upgradeable::Upgradeable; - // NOTE: remove duplication once we can directly use the trait - #[abi] - trait IERC20 { - fn balance_of(account: ContractAddress) -> u256; - fn transfer(recipient: ContractAddress, amount: u256) -> bool; - // fn transfer_from(sender: ContractAddress, recipient: ContractAddress, amount: u256) -> bool; - } + use openzeppelin::token::erc20::interface::{IERC20, IERC20Dispatcher, IERC20DispatcherTrait}; - // NOTE: remove duplication once we can directly use the trait - #[abi] - trait IAccessController { - fn has_access(user: ContractAddress, data: Array) -> bool; - fn add_access(user: ContractAddress); - fn remove_access(user: ContractAddress); - fn enable_access_check(); - fn disable_access_check(); - } + use chainlink::libraries::access_control::{ + IAccessController, IAccessControllerDispatcher, IAccessControllerDispatcherTrait + }; const GIGA: u128 = 1000000000_u128; const MAX_ORACLES: u32 = 31_u32; #[event] - fn NewTransmission( + #[derive(Drop, starknet::Event)] + enum Event { + NewTransmission: NewTransmission, + ConfigSet: ConfigSet, + LinkTokenSet: LinkTokenSet, + BillingAccessControllerSet: BillingAccessControllerSet, + BillingSet: BillingSet, + OraclePaid: OraclePaid, + PayeeshipTransferRequested: PayeeshipTransferRequested, + PayeeshipTransferred: PayeeshipTransferred, + } + + #[derive(Drop, starknet::Event)] + struct NewTransmission { round_id: u128, answer: u128, transmitter: ContractAddress, @@ -128,80 +235,36 @@ mod Aggregator { config_digest: felt252, epoch_and_round: u64, reimbursement: u128 - ) {} + } - #[derive(Copy, Drop, Serde)] + #[derive(Copy, Drop, Serde, starknet::Store)] struct Oracle { index: usize, // entire supply of LINK always fits into u96, so u128 is safe to use payment_juels: u128, } - impl OracleStorageAccess of StorageAccess { - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult:: { - let value = storage_read_syscall( - address_domain, storage_address_from_base_and_offset(base, 0_u8) - )?; - let (index, payment_juels) = split_felt(value); - Result::Ok(Oracle { index: index.into().try_into().unwrap(), payment_juels, }) - } - - fn write( - address_domain: u32, base: StorageBaseAddress, value: Oracle - ) -> SyscallResult::<()> { - let value = value.index.into() * SHIFT_128 + value.payment_juels.into(); - storage_write_syscall( - address_domain, storage_address_from_base_and_offset(base, 0_u8), value - ) - } - } - - #[derive(Copy, Drop, Serde)] - struct Transmission { - answer: u128, - block_num: u64, - observation_timestamp: u64, - transmission_timestamp: u64, - } - - impl TransmissionStorageAccess of StorageAccess { - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult:: { - let block_num_and_answer = storage_read_syscall( - address_domain, storage_address_from_base_and_offset(base, 0_u8) - )?; - let (block_num, answer) = split_felt(block_num_and_answer); - let timestamps = storage_read_syscall( - address_domain, storage_address_from_base_and_offset(base, 1_u8) - )?; - let (observation_timestamp, transmission_timestamp) = split_felt(timestamps); - - Result::Ok( - Transmission { - answer, - block_num: block_num.into().try_into().unwrap(), - observation_timestamp: observation_timestamp.into().try_into().unwrap(), - transmission_timestamp: transmission_timestamp.into().try_into().unwrap(), - } - ) - } - - fn write( - address_domain: u32, base: StorageBaseAddress, value: Transmission - ) -> SyscallResult::<()> { - let block_num_and_answer = value.block_num.into() * SHIFT_128 + value.answer.into(); - let timestamps = value.observation_timestamp.into() * SHIFT_128 - + value.transmission_timestamp.into(); - storage_write_syscall( - address_domain, - storage_address_from_base_and_offset(base, 0_u8), - block_num_and_answer - )?; - storage_write_syscall( - address_domain, storage_address_from_base_and_offset(base, 1_u8), timestamps - ) - } - } - + // TODO: reintroduce custom storage to save on space + // impl OracleStorageAccess of StorageAccess { + // fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult:: { + // let value = storage_read_syscall( + // address_domain, storage_address_from_base_and_offset(base, 0_u8) + // )?; + // let (index, payment_juels) = split_felt(value); + // Result::Ok(Oracle { index: index.try_into().unwrap(), payment_juels, }) + // } + // + // fn write( + // address_domain: u32, base: StorageBaseAddress, value: Oracle + // ) -> SyscallResult::<()> { + // let value = value.index.into() * SHIFT_128 + value.payment_juels.into(); + // storage_write_syscall( + // address_domain, storage_address_from_base_and_offset(base, 0_u8), value + // ) + // } + // } + + #[storage] struct Storage { /// Maximum number of faulty oracles _f: u8, @@ -226,7 +289,7 @@ mod Aggregator { _link_token: ContractAddress, // billing _billing_access_controller: ContractAddress, - _billing: Billing, + _billing: BillingConfig, // payee management _payees: LegacyMap, // _proposed_payees: LegacyMap Round { + #[external(v0)] + impl AggregatorImpl of super::IAggregator { + fn latest_round_data(self: @ContractState) -> Round { _require_read_access(); - let latest_round_id = _latest_aggregator_round_id::read(); - let transmission = _transmissions::read(latest_round_id); + let latest_round_id = self._latest_aggregator_round_id.read(); + let transmission = self._transmissions.read(latest_round_id); Round { round_id: latest_round_id.into(), answer: transmission.answer, @@ -252,9 +317,9 @@ mod Aggregator { } } - fn round_data(round_id: u128) -> Round { + fn round_data(self: @ContractState, round_id: u128) -> Round { _require_read_access(); - let transmission = _transmissions::read(round_id); + let transmission = self._transmissions.read(round_id); Round { round_id: round_id.into(), answer: transmission.answer, @@ -264,17 +329,17 @@ mod Aggregator { } } - fn description() -> felt252 { + fn description(self: @ContractState) -> felt252 { _require_read_access(); - _description::read() + self._description.read() } - fn decimals() -> u8 { + fn decimals(self: @ContractState) -> u8 { _require_read_access(); - _decimals::read() + self._decimals.read() } - fn type_and_version() -> felt252 { + fn type_and_version(self: @ContractState) -> felt252 { 'ocr2/aggregator.cairo 1.0.0' } } @@ -283,6 +348,7 @@ mod Aggregator { #[constructor] fn constructor( + ref self: ContractState, owner: ContractAddress, link: ContractAddress, min_answer: u128, @@ -291,83 +357,96 @@ mod Aggregator { decimals: u8, description: felt252 ) { - Ownable::initializer(owner); - AccessControl::initializer(); - _link_token::write(link); - _billing_access_controller::write(billing_access_controller); + let mut ownable = Ownable::unsafe_new_contract_state(); + Ownable::constructor(ref ownable, owner); // Ownable::initializer(owner); + let mut access_control = AccessControl::unsafe_new_contract_state(); + AccessControl::constructor(ref access_control); + self._link_token.write(link); + self._billing_access_controller.write(billing_access_controller); assert(min_answer < max_answer, 'min >= max'); - _min_answer::write(min_answer); - _max_answer::write(max_answer); + self._min_answer.write(min_answer); + self._max_answer.write(max_answer); - _decimals::write(decimals); - _description::write(description); + self._decimals.write(decimals); + self._description.write(description); } // --- Upgradeable --- - #[external] - fn upgrade(new_impl: ClassHash) { - Ownable::assert_only_owner(); + #[external(v0)] + fn upgrade(ref self: ContractState, new_impl: ClassHash) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); Upgradeable::upgrade(new_impl) } // --- Ownership --- - #[view] - fn owner() -> ContractAddress { - Ownable::owner() - } + #[external(v0)] + impl OwnableImpl of IOwnable { + fn owner(self: @ContractState) -> ContractAddress { + let state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::owner(@state) + } - #[view] - fn proposed_owner() -> ContractAddress { - Ownable::proposed_owner() - } + fn proposed_owner(self: @ContractState) -> ContractAddress { + let state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::proposed_owner(@state) + } - #[external] - fn transfer_ownership(new_owner: ContractAddress) { - Ownable::transfer_ownership(new_owner) - } + fn transfer_ownership(ref self: ContractState, new_owner: ContractAddress) { + let mut state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::transfer_ownership(ref state, new_owner) + } - #[external] - fn accept_ownership() { - Ownable::accept_ownership() - } + fn accept_ownership(ref self: ContractState) { + let mut state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::accept_ownership(ref state) + } - #[external] - fn renounce_ownership() { - Ownable::renounce_ownership() + fn renounce_ownership(ref self: ContractState) { + let mut state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::renounce_ownership(ref state) + } } // -- Access Control -- - #[view] - fn has_access(user: ContractAddress, data: Array) -> bool { - AccessControl::has_access(user, data) - } + #[external(v0)] + impl AccessControllerImpl of IAccessController { + fn has_access(self: @ContractState, user: ContractAddress, data: Array) -> bool { + let state = AccessControl::unsafe_new_contract_state(); + AccessControl::has_access(@state, user, data) + } - #[external] - fn add_access(user: ContractAddress) { - Ownable::assert_only_owner(); - AccessControl::add_access(user); - } + fn add_access(ref self: ContractState, user: ContractAddress) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + let mut state = AccessControl::unsafe_new_contract_state(); + AccessControl::add_access(ref state, user) + } - #[external] - fn remove_access(user: ContractAddress) { - Ownable::assert_only_owner(); - AccessControl::remove_access(user); - } + fn remove_access(ref self: ContractState, user: ContractAddress) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + let mut state = AccessControl::unsafe_new_contract_state(); + AccessControl::remove_access(ref state, user) + } - #[external] - fn enable_access_check() { - Ownable::assert_only_owner(); - AccessControl::enable_access_check(); - } + fn enable_access_check(ref self: ContractState) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + let mut state = AccessControl::unsafe_new_contract_state(); + AccessControl::enable_access_check(ref state) + } - #[external] - fn disable_access_check() { - Ownable::assert_only_owner(); - AccessControl::disable_access_check(); + fn disable_access_check(ref self: ContractState) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + let mut state = AccessControl::unsafe_new_contract_state(); + AccessControl::disable_access_check(ref state) + } } // --- Validation --- @@ -376,8 +455,8 @@ mod Aggregator { // --- Configuration - #[event] - fn ConfigSet( + #[derive(Drop, starknet::Event)] + struct ConfigSet { previous_config_block_number: u64, latest_config_digest: felt252, config_count: u64, @@ -386,144 +465,9 @@ mod Aggregator { onchain_config: Array, offchain_config_version: u64, offchain_config: Array, - ) {} - - #[derive(Copy, Drop, Serde)] - struct OracleConfig { - signer: felt252, - transmitter: ContractAddress, - } - - impl OracleConfigLegacyHash of LegacyHash { - fn hash(mut state: felt252, value: OracleConfig) -> felt252 { - state = LegacyHash::hash(state, value.signer); - state = LegacyHash::hash(state, value.transmitter); - state - } - } - - #[external] - fn set_config( - oracles: Array, - f: u8, - onchain_config: Array, - offchain_config_version: u64, - offchain_config: Array, - ) -> felt252 { // digest - Ownable::assert_only_owner(); - assert(oracles.len() <= MAX_ORACLES, 'too many oracles'); - assert((3_u8 * f).into() < oracles.len(), 'faulty-oracle f too high'); - assert(f > 0_u8, 'f must be positive'); - - assert(onchain_config.len() == 0_u32, 'onchain_config must be empty'); - - let min_answer = _min_answer::read(); - let max_answer = _max_answer::read(); - - let mut computed_onchain_config = ArrayTrait::new(); - computed_onchain_config.append(1); // version - computed_onchain_config.append(min_answer.into()); - computed_onchain_config.append(max_answer.into()); - - pay_oracles(); - - // remove old signers & transmitters - let len = _oracles_len::read(); - remove_oracles(len); - - let latest_round_id = _latest_aggregator_round_id::read(); - - let oracles_len = oracles.len(); // work around variable move issue - add_oracles(@oracles, 0_usize, oracles_len, latest_round_id); - - _f::write(f); - let block_num = starknet::info::get_block_info().unbox().block_number; - let prev_block_num = _latest_config_block_number::read(); - _latest_config_block_number::write(block_num); - // update config count - let mut config_count = _config_count::read(); - config_count += 1_u64; - _config_count::write(config_count); - let contract_address = starknet::info::get_contract_address(); - let chain_id = starknet::info::get_tx_info().unbox().chain_id; - - let digest = config_digest_from_data( - chain_id, - contract_address, - config_count, - @oracles, - f, - @computed_onchain_config, - offchain_config_version, - @offchain_config, - ); - - _latest_config_digest::write(digest); - - // reset epoch & round - _latest_epoch_and_round::write(0_u64); - - ConfigSet( - prev_block_num, - digest, - config_count, - oracles, - f, - computed_onchain_config, - offchain_config_version, - offchain_config - ); - - digest } - fn remove_oracles(n: usize) { - if n == 0_usize { - _oracles_len::write(0_usize); - return (); - } - - let signer = _signers_list::read(n); - _signers::write(signer, 0_usize); - - let transmitter = _transmitters_list::read(n); - _transmitters::write(transmitter, Oracle { index: 0_usize, payment_juels: 0_u128 }); - - gas::withdraw_gas_all(get_builtin_costs()).expect('Out of gas'); - remove_oracles(n - 1_usize) - } - - // TODO: measure gas, then rewrite (add_oracles and remove_oracles) using pop_front to see gas costs - fn add_oracles(oracles: @Array, index: usize, len: usize, latest_round_id: u128) { - if len == 0_usize { - _oracles_len::write(index); - return (); - } - - let oracle = oracles.at(index); - - // NOTE: index should start with 1 here because storage is 0-initialized. - // That way signers(pkey) => 0 indicates "not present" - let index = index + 1_usize; - - // check for duplicates - let existing_signer = _signers::read(*oracle.signer); - assert(existing_signer == 0_usize, 'repeated signer'); - - let existing_transmitter = _transmitters::read(*oracle.transmitter); - assert(existing_transmitter.index == 0_usize, 'repeated transmitter'); - - _signers::write(*oracle.signer, index); - _signers_list::write(index, *oracle.signer); - - _transmitters::write(*oracle.transmitter, Oracle { index, payment_juels: 0_u128 }); - _transmitters_list::write(index, *oracle.transmitter); - - _reward_from_aggregator_round_id::write(index, latest_round_id); - - gas::withdraw_gas_all(get_builtin_costs()).expect('Out of gas'); - add_oracles(oracles, index, len - 1_usize, latest_round_id) - } + use super::OracleConfig; const SHIFT_128: felt252 = 0x100000000000000000000000000000000; // 4 * 2 ** (124 - 12) @@ -573,33 +517,171 @@ mod Aggregator { masked } - #[view] - fn latest_config_details() -> (u64, u64, felt252) { - let config_count = _config_count::read(); - let block_number = _latest_config_block_number::read(); - let config_digest = _latest_config_digest::read(); + #[external(v0)] + impl ConfigurationImpl of super::Configuration { + fn set_config( + ref self: ContractState, + oracles: Array, + f: u8, + onchain_config: Array, + offchain_config_version: u64, + offchain_config: Array, + ) -> felt252 { // digest + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + assert(oracles.len() <= MAX_ORACLES, 'too many oracles'); + assert((3_u8 * f).into() < oracles.len(), 'faulty-oracle f too high'); + assert(f > 0_u8, 'f must be positive'); + + assert(onchain_config.len() == 0_u32, 'onchain_config must be empty'); + + let min_answer = self._min_answer.read(); + let max_answer = self._max_answer.read(); + + let mut computed_onchain_config = ArrayTrait::new(); + computed_onchain_config.append(1); // version + computed_onchain_config.append(min_answer.into()); + computed_onchain_config.append(max_answer.into()); + + self.pay_oracles(); + + // remove old signers & transmitters + self.remove_oracles(); + + let latest_round_id = self._latest_aggregator_round_id.read(); + + self.add_oracles(@oracles, latest_round_id); + + self._f.write(f); + let block_num = starknet::info::get_block_info().unbox().block_number; + let prev_block_num = self._latest_config_block_number.read(); + self._latest_config_block_number.write(block_num); + // update config count + let mut config_count = self._config_count.read(); + config_count += 1_u64; + self._config_count.write(config_count); + let contract_address = starknet::info::get_contract_address(); + let chain_id = starknet::info::get_tx_info().unbox().chain_id; + + let digest = config_digest_from_data( + chain_id, + contract_address, + config_count, + @oracles, + f, + @computed_onchain_config, + offchain_config_version, + @offchain_config, + ); + + self._latest_config_digest.write(digest); + + // reset epoch & round + self._latest_epoch_and_round.write(0_u64); + + self + .emit( + Event::ConfigSet( + ConfigSet { + previous_config_block_number: prev_block_num, + latest_config_digest: digest, + config_count: config_count, + oracles: oracles, + f: f, + onchain_config: computed_onchain_config, + offchain_config_version: offchain_config_version, + offchain_config: offchain_config + } + ) + ); + + digest + } - (config_count, block_number, config_digest) - } + fn latest_config_details(self: @ContractState) -> (u64, u64, felt252) { + let config_count = self._config_count.read(); + let block_number = self._latest_config_block_number.read(); + let config_digest = self._latest_config_digest.read(); - #[view] - fn transmitters() -> Array { - let len = _oracles_len::read(); - let result = ArrayTrait::new(); - transmitters_(len, 0_usize, result) - } + (config_count, block_number, config_digest) + } - fn transmitters_( - len: usize, index: usize, mut result: Array - ) -> Array { - if len == 0_usize { + fn transmitters(self: @ContractState) -> Array { + let mut index = 1; + let mut len = self._oracles_len.read(); + let mut result = ArrayTrait::new(); + loop { + if len == 0_usize { + break (); + } + let transmitter = self._transmitters_list.read(index); + result.append(transmitter); + len -= 1; + index += 1; + }; return result; } - let index = index + 1_usize; - let transmitter = _transmitters_list::read(index); - result.append(transmitter); - gas::withdraw_gas_all(get_builtin_costs()).expect('Out of gas'); - transmitters_(len - 1_usize, index, result) + } + + #[generate_trait] + impl ConfigurationHelperImpl of ConfigurationHelperTrait { + fn remove_oracles(ref self: ContractState) { + let mut index = self._oracles_len.read(); + loop { + if index == 0_usize { + self._oracles_len.write(0_usize); + break (); + } + + let signer = self._signers_list.read(index); + self._signers.write(signer, 0_usize); + + let transmitter = self._transmitters_list.read(index); + self + ._transmitters + .write(transmitter, Oracle { index: 0_usize, payment_juels: 0_u128 }); + + index -= 1; + } + } + + fn add_oracles( + ref self: ContractState, oracles: @Array, latest_round_id: u128 + ) { + let mut index = 0; + let mut span = oracles.span(); + loop { + match span.pop_front() { + Option::Some(oracle) => { + // NOTE: index should start with 1 here because storage is 0-initialized. + // That way signers(pkey) => 0 indicates "not present" + // This is why we increment first, before using the index + index += 1; + + // check for duplicates + let existing_signer = self._signers.read(*oracle.signer); + assert(existing_signer == 0_usize, 'repeated signer'); + + let existing_transmitter = self._transmitters.read(*oracle.transmitter); + assert(existing_transmitter.index == 0_usize, 'repeated transmitter'); + + self._signers.write(*oracle.signer, index); + self._signers_list.write(index, *oracle.signer); + + self + ._transmitters + .write(*oracle.transmitter, Oracle { index, payment_juels: 0_u128 }); + self._transmitters_list.write(index, *oracle.transmitter); + + self._reward_from_aggregator_round_id.write(index, latest_round_id); + }, + Option::None(_) => { + self._oracles_len.write(index); + break (); + } + }; + } + } } // --- Transmission --- @@ -618,8 +700,9 @@ mod Aggregator { extra_hash: felt252, } - #[external] + #[external(v0)] fn transmit( + ref self: ContractState, report_context: ReportContext, observation_timestamp: u64, observers: felt252, @@ -630,19 +713,19 @@ mod Aggregator { ) { let signatures_len = signatures.len(); - let epoch_and_round = _latest_epoch_and_round::read(); + let epoch_and_round = self._latest_epoch_and_round.read(); assert(epoch_and_round < report_context.epoch_and_round, 'stale report'); // validate transmitter let caller = starknet::info::get_caller_address(); - let mut oracle = _transmitters::read(caller); + let mut oracle = self._transmitters.read(caller); assert(oracle.index != 0_usize, 'unknown sender'); // 0 index = uninitialized // Validate config digest matches latest_config_digest - let config_digest = _latest_config_digest::read(); + let config_digest = self._latest_config_digest.read(); assert(report_context.config_digest == config_digest, 'config digest mismatch'); - let f = _f::read(); + let f = self._f.read(); assert(signatures_len == (f + 1_u8).into(), 'wrong number of signatures'); let msg = hash_report( @@ -662,7 +745,7 @@ mod Aggregator { // Although 31 bits is enough, we use a u128 here for simplicity because BitAnd and BitOr // operators are defined only for u128 and u256. assert(MAX_ORACLES == 31_u32, ''); - verify_signatures(msg, ref signatures, 0_u128); + self.verify_signatures(msg, ref signatures, 0_u128); // report(): @@ -670,61 +753,77 @@ mod Aggregator { assert(observations_len <= MAX_ORACLES, ''); assert(f.into() < observations_len, ''); - _latest_epoch_and_round::write(report_context.epoch_and_round); + self._latest_epoch_and_round.write(report_context.epoch_and_round); let median_idx = observations_len / 2_usize; let median = *observations[median_idx]; // Validate median in min-max range - let min_answer = _min_answer::read(); - let max_answer = _max_answer::read(); - assert(min_answer <= median & median <= max_answer, 'median is out of min-max range'); + let min_answer = self._min_answer.read(); + let max_answer = self._max_answer.read(); + assert((min_answer <= median) & (median <= max_answer), 'median is out of min-max range'); - let prev_round_id = _latest_aggregator_round_id::read(); + let prev_round_id = self._latest_aggregator_round_id.read(); let round_id = prev_round_id + 1_u128; - _latest_aggregator_round_id::write(round_id); + self._latest_aggregator_round_id.write(round_id); let block_info = starknet::info::get_block_info().unbox(); - _transmissions::write( - round_id, - Transmission { - answer: median, - block_num: block_info.block_number, - observation_timestamp, - transmission_timestamp: block_info.block_timestamp, - } - ); + self + ._transmissions + .write( + round_id, + Transmission { + answer: median, + block_num: block_info.block_number, + observation_timestamp, + transmission_timestamp: block_info.block_timestamp, + } + ); // NOTE: Usually validating via validator would happen here, currently disabled - let billing = _billing::read(); + let billing = self._billing.read(); let reimbursement_juels = calculate_reimbursement( juels_per_fee_coin, signatures_len, gas_price, billing ); // end report() - NewTransmission( - round_id, - median, - caller, - observation_timestamp, - observers, - observations, - juels_per_fee_coin, - gas_price, - report_context.config_digest, - report_context.epoch_and_round, - reimbursement_juels, - ); + self + .emit( + Event::NewTransmission( + NewTransmission { + round_id: round_id, + answer: median, + transmitter: caller, + observation_timestamp: observation_timestamp, + observers: observers, + observations: observations, + juels_per_fee_coin: juels_per_fee_coin, + gas_price: gas_price, + config_digest: report_context.config_digest, + epoch_and_round: report_context.epoch_and_round, + reimbursement: reimbursement_juels, + } + ) + ); // pay transmitter let payment = reimbursement_juels + (billing.transmission_payment_gjuels.into() * GIGA); // TODO: check overflow oracle.payment_juels += payment; - _transmitters::write(caller, oracle); + self._transmitters.write(caller, oracle); + } + + #[external(v0)] + fn latest_transmission_details(self: @ContractState) -> (felt252, u64, u128, u64) { + let config_digest = self._latest_config_digest.read(); + let latest_round_id = self._latest_aggregator_round_id.read(); + let epoch_and_round = self._latest_epoch_and_round.read(); + let transmission = self._transmissions.read(latest_round_id); + (config_digest, epoch_and_round, transmission.answer, transmission.transmission_timestamp) } fn hash_report( @@ -750,81 +849,59 @@ mod Aggregator { state } - fn verify_signatures(msg: felt252, ref signatures: Array, mut signed_count: u128) { - let signature = match signatures.pop_front() { - Option::Some(signature) => signature, - Option::None(_) => { - // No more signatures left! - return (); - } - }; - - let index = _signers::read(signature.public_key); - assert(index != 0_usize, 'invalid signer'); // 0 index == uninitialized - - let indexed_bit = pow(2_u128, index.into() - 1_u128); - let prev_signed_count = signed_count; - signed_count = signed_count | indexed_bit; - assert(prev_signed_count != signed_count, 'duplicate signer'); - - let is_valid = ecdsa::check_ecdsa_signature( - msg, signature.public_key, signature.r, signature.s - ); - - assert(is_valid, ''); - - gas::withdraw_gas_all(get_builtin_costs()).expect('Out of gas'); - verify_signatures(msg, ref signatures, signed_count) - } - - #[view] - fn latest_transmission_details() -> (felt252, u64, u128, u64) { - let config_digest = _latest_config_digest::read(); - let latest_round_id = _latest_aggregator_round_id::read(); - let epoch_and_round = _latest_epoch_and_round::read(); - let transmission = _transmissions::read(latest_round_id); - (config_digest, epoch_and_round, transmission.answer, transmission.transmission_timestamp) + #[generate_trait] + impl TransmissionHelperImpl of TransmissionHelperTrait { + fn verify_signatures( + self: @ContractState, + msg: felt252, + ref signatures: Array, + mut signed_count: u128 + ) { + let mut span = signatures.span(); + loop { + match span.pop_front() { + Option::Some(signature) => { + let index = self._signers.read(*signature.public_key); + assert(index != 0_usize, 'invalid signer'); // 0 index == uninitialized + + let indexed_bit = pow(2_u128, index.into() - 1_u128); + let prev_signed_count = signed_count; + signed_count = signed_count | indexed_bit; + assert(prev_signed_count != signed_count, 'duplicate signer'); + + let is_valid = ecdsa::check_ecdsa_signature( + msg, *signature.public_key, *signature.r, *signature.s + ); + + assert(is_valid, ''); + }, + Option::None(_) => { + // No more signatures left! + break (); + } + }; + }; + } } // --- RequestNewRound - // --- Queries - - #[view] - fn description() -> felt252 { - Aggregator::description() - } - - #[view] - fn decimals() -> u8 { - Aggregator::decimals() - } - - #[view] - fn latest_round_data() -> Round { - Aggregator::latest_round_data() - } - - #[view] - fn round_data(round_id: u128) -> Round { - Aggregator::round_data(round_id) - } - - #[view] - fn type_and_version() -> felt252 { - Aggregator::type_and_version() - } - // --- Set LINK Token - #[event] - fn LinkTokenSet(old_link_token: ContractAddress, new_link_token: ContractAddress, ) {} + #[derive(Drop, starknet::Event)] + struct LinkTokenSet { + old_link_token: ContractAddress, + new_link_token: ContractAddress + } - #[external] - fn set_link_token(link_token: ContractAddress, recipient: ContractAddress) { - Ownable::assert_only_owner(); + #[external(v0)] + fn set_link_token( + ref self: ContractState, link_token: ContractAddress, recipient: ContractAddress + ) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); - let old_token = _link_token::read(); + let old_token = self._link_token.read(); if link_token == old_token { return (); @@ -836,291 +913,275 @@ mod Aggregator { let token = IERC20Dispatcher { contract_address: link_token }; token.balance_of(account: contract_address); - pay_oracles(); + self.pay_oracles(); // transfer remaining balance of old token to recipient let old_token_dispatcher = IERC20Dispatcher { contract_address: old_token }; let amount = old_token_dispatcher.balance_of(account: contract_address); old_token_dispatcher.transfer(recipient, amount); - _link_token::write(link_token); + self._link_token.write(link_token); - LinkTokenSet(old_token, link_token); - } - - // --- Billing Access Controller - - #[event] - fn BillingAccessControllerSet( - old_controller: ContractAddress, new_controller: ContractAddress, - ) {} - - #[external] - fn set_billing_access_controller(access_controller: ContractAddress) { - Ownable::assert_only_owner(); - - let old_controller = _billing_access_controller::read(); - if access_controller == old_controller { - return (); - } - - _billing_access_controller::write(access_controller); - BillingAccessControllerSet(old_controller, access_controller); + self + .emit( + Event::LinkTokenSet( + LinkTokenSet { old_link_token: old_token, new_link_token: link_token } + ) + ); } // --- Billing Config - #[derive(Copy, Drop, Serde)] - struct Billing { + #[derive(Copy, Drop, Serde, starknet::Store)] + struct BillingConfig { observation_payment_gjuels: u32, transmission_payment_gjuels: u32, gas_base: u32, gas_per_signature: u32, } - impl BillingStorageAccess of StorageAccess { - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult:: { - Result::Ok( - Billing { - observation_payment_gjuels: storage_read_syscall( - address_domain, storage_address_from_base_and_offset(base, 0_u8) - )?.try_into().unwrap(), - transmission_payment_gjuels: storage_read_syscall( - address_domain, storage_address_from_base_and_offset(base, 1_u8) - )?.try_into().unwrap(), - gas_base: storage_read_syscall( - address_domain, storage_address_from_base_and_offset(base, 2_u8) - )?.try_into().unwrap(), - gas_per_signature: storage_read_syscall( - address_domain, storage_address_from_base_and_offset(base, 3_u8) - )?.try_into().unwrap(), - } - ) - } - - fn write( - address_domain: u32, base: StorageBaseAddress, value: Billing - ) -> SyscallResult::<()> { - storage_write_syscall( - address_domain, - storage_address_from_base_and_offset(base, 0_u8), - value.observation_payment_gjuels.into() - )?; - storage_write_syscall( - address_domain, - storage_address_from_base_and_offset(base, 1_u8), - value.transmission_payment_gjuels.into() - )?; - storage_write_syscall( - address_domain, - storage_address_from_base_and_offset(base, 2_u8), - value.gas_base.into() - )?; - storage_write_syscall( - address_domain, - storage_address_from_base_and_offset(base, 3_u8), - value.gas_per_signature.into() - ) - } - } - - #[event] - fn BillingSet(config: Billing) {} - - #[external] - fn set_billing(config: Billing) { - has_billing_access(); - - pay_oracles(); - - _billing::write(config); - - BillingSet(config); - } + // --- Billing Access Controller - #[view] - fn billing() -> Billing { - _billing::read() + #[derive(Drop, starknet::Event)] + struct BillingAccessControllerSet { + old_controller: ContractAddress, + new_controller: ContractAddress, } - fn has_billing_access() { - let caller = starknet::info::get_caller_address(); - let owner = Ownable::owner(); - - // owner always has access - if caller == owner { - return (); - } - - let access_controller = _billing_access_controller::read(); - let access_controller = IAccessControllerDispatcher { contract_address: access_controller }; - assert( - access_controller.has_access(caller, ArrayTrait::new()), 'caller does not have access' - ); + #[derive(Drop, starknet::Event)] + struct BillingSet { + config: BillingConfig } - // --- Payments and Withdrawals - - #[event] - fn OraclePaid( + #[derive(Drop, starknet::Event)] + struct OraclePaid { transmitter: ContractAddress, payee: ContractAddress, amount: u256, link_token: ContractAddress, - ) {} + } - #[external] - fn withdraw_payment(transmitter: ContractAddress) { - let caller = starknet::info::get_caller_address(); - let payee = _payees::read(transmitter); - assert(caller == payee, 'only payee can withdraw'); + #[external(v0)] + impl BillingImpl of super::Billing { + fn set_billing_access_controller( + ref self: ContractState, access_controller: ContractAddress + ) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); - let latest_round_id = _latest_aggregator_round_id::read(); - let link_token = _link_token::read(); - pay_oracle(transmitter, latest_round_id, link_token) - } + let old_controller = self._billing_access_controller.read(); + if access_controller == old_controller { + return (); + } - fn _owed_payment(oracle: @Oracle) -> u128 { - if *oracle.index == 0_usize { - return 0_u128; + self._billing_access_controller.write(access_controller); + self + .emit( + Event::BillingAccessControllerSet( + BillingAccessControllerSet { + old_controller: old_controller, new_controller: access_controller + } + ) + ); } - let billing = _billing::read(); + fn set_billing(ref self: ContractState, config: BillingConfig) { + self.has_billing_access(); - let latest_round_id = _latest_aggregator_round_id::read(); - let from_round_id = _reward_from_aggregator_round_id::read(*oracle.index); - let rounds = latest_round_id - from_round_id; + self.pay_oracles(); - (rounds * billing.observation_payment_gjuels.into() * GIGA) + *oracle.payment_juels - } + self._billing.write(config); - #[view] - fn owed_payment(transmitter: ContractAddress) -> u128 { - let oracle = _transmitters::read(transmitter); - _owed_payment(@oracle) - } + self.emit(Event::BillingSet(BillingSet { config: config })); + } - fn pay_oracle( - transmitter: ContractAddress, latest_round_id: u128, link_token: ContractAddress - ) { - let oracle = _transmitters::read(transmitter); - if oracle.index == 0_usize { - return (); + fn billing(self: @ContractState) -> BillingConfig { + self._billing.read() } - let amount = _owed_payment(@oracle); - // if zero, fastpath return to avoid empty transfers - if amount == 0_u128 { - return (); + // Payments and Withdrawals + + fn withdraw_payment(ref self: ContractState, transmitter: ContractAddress) { + let caller = starknet::info::get_caller_address(); + let payee = self._payees.read(transmitter); + assert(caller == payee, 'only payee can withdraw'); + + let latest_round_id = self._latest_aggregator_round_id.read(); + let link_token = self._link_token.read(); + self.pay_oracle(transmitter, latest_round_id, link_token) } - let payee = _payees::read(transmitter); + fn owed_payment(self: @ContractState, transmitter: ContractAddress) -> u128 { + let oracle = self._transmitters.read(transmitter); + self._owed_payment(@oracle) + } - // NOTE: equivalent to converting u128 to u256 - let amount = u256 { high: 0_u128, low: amount }; + fn withdraw_funds(ref self: ContractState, recipient: ContractAddress, amount: u256) { + self.has_billing_access(); - let token = IERC20Dispatcher { contract_address: link_token }; - token.transfer(recipient: payee, amount: amount); + let link_token = self._link_token.read(); + let contract_address = starknet::info::get_contract_address(); - // Reset payment - _reward_from_aggregator_round_id::write(oracle.index, latest_round_id); - _transmitters::write(transmitter, Oracle { index: oracle.index, payment_juels: 0_u128 }); + let due = self.total_link_due(); + // NOTE: equivalent to converting u128 to u256 + let due = u256 { high: 0_u128, low: due }; - OraclePaid(transmitter, payee, amount, link_token); - } + let token = IERC20Dispatcher { contract_address: link_token }; + let balance = token.balance_of(account: contract_address); - fn pay_oracles() { - let len = _oracles_len::read(); - let latest_round_id = _latest_aggregator_round_id::read(); - let link_token = _link_token::read(); - pay_oracles_(len, latest_round_id, link_token) - } + assert(due <= balance, 'amount due exceeds balance'); + let available = balance - due; - fn pay_oracles_(index: usize, latest_round_id: u128, link_token: ContractAddress) { - if index == 0_usize { - return (); + // Transfer as much as there is available + let amount = if available < amount { + available + } else { + amount + }; + token.transfer(recipient, amount); } - let transmitter = _transmitters_list::read(index); - pay_oracle(transmitter, latest_round_id, link_token); - - gas::withdraw_gas_all(get_builtin_costs()).expect('Out of gas'); - pay_oracles_(index - 1_usize, latest_round_id, link_token) + fn link_available_for_payment( + self: @ContractState + ) -> (bool, u128) { // (is negative, absolute difference) + let link_token = self._link_token.read(); + let contract_address = starknet::info::get_contract_address(); + + let token = IERC20Dispatcher { contract_address: link_token }; + let balance = token.balance_of(account: contract_address); + // entire link supply fits into u96 so this should not fail + assert(balance.high == 0_u128, 'balance too high'); + let balance: u128 = balance.low; + + let due = self.total_link_due(); + if balance > due { + (false, balance - due) + } else { + (true, due - balance) + } + } } - #[external] - fn withdraw_funds(recipient: ContractAddress, amount: u256) { - has_billing_access(); + #[generate_trait] + impl BillingHelperImpl of BillingHelperTrait { + fn has_billing_access(self: @ContractState) { + let caller = starknet::info::get_caller_address(); + let ownable = Ownable::unsafe_new_contract_state(); + let owner = Ownable::OwnableImpl::owner(@ownable); - let link_token = _link_token::read(); - let contract_address = starknet::info::get_contract_address(); + // owner always has access + if caller == owner { + return (); + } - let due = total_link_due(); - // NOTE: equivalent to converting u128 to u256 - let due = u256 { high: 0_u128, low: due }; + let access_controller = self._billing_access_controller.read(); + let access_controller = IAccessControllerDispatcher { + contract_address: access_controller + }; + assert( + access_controller.has_access(caller, ArrayTrait::new()), + 'caller does not have access' + ); + } - let token = IERC20Dispatcher { contract_address: link_token }; - let balance = token.balance_of(account: contract_address); - - assert(due <= balance, 'amount due exceeds balance'); - let available = balance - due; - - // Transfer as much as there is available - let amount = if available < amount { - available - } else { - amount - }; - token.transfer(recipient, amount); - } + // --- Payments and Withdrawals - fn total_link_due() -> u128 { - let len = _oracles_len::read(); - let latest_round_id = _latest_aggregator_round_id::read(); + fn _owed_payment(self: @ContractState, oracle: @Oracle) -> u128 { + if *oracle.index == 0_usize { + return 0_u128; + } - total_link_due_(len, latest_round_id, 0_u128, 0_u128) - } - fn total_link_due_( - index: usize, latest_round_id: u128, total_rounds: u128, payments_juels: u128 - ) -> u128 { - if index == 0_usize { - let billing = _billing::read(); - return (total_rounds * billing.observation_payment_gjuels.into() * GIGA) - + payments_juels; + let billing = self._billing.read(); + + let latest_round_id = self._latest_aggregator_round_id.read(); + let from_round_id = self._reward_from_aggregator_round_id.read(*oracle.index); + let rounds = latest_round_id - from_round_id; + + (rounds * billing.observation_payment_gjuels.into() * GIGA) + *oracle.payment_juels } - let transmitter = _transmitters_list::read(index); - let oracle = _transmitters::read(transmitter); - assert(oracle.index != 0_usize, ''); // 0 == undefined + fn pay_oracle( + ref self: ContractState, + transmitter: ContractAddress, + latest_round_id: u128, + link_token: ContractAddress + ) { + let oracle = self._transmitters.read(transmitter); + if oracle.index == 0_usize { + return (); + } - let from_round_id = _reward_from_aggregator_round_id::read(oracle.index); - let rounds = latest_round_id - from_round_id; + let amount = self._owed_payment(@oracle); + // if zero, fastpath return to avoid empty transfers + if amount == 0_u128 { + return (); + } - gas::withdraw_gas_all(get_builtin_costs()).expect('Out of gas'); - total_link_due_( - index - 1_usize, - latest_round_id, - total_rounds + rounds, - payments_juels + oracle.payment_juels - ) - } + let payee = self._payees.read(transmitter); + + // NOTE: equivalent to converting u128 to u256 + let amount = u256 { high: 0_u128, low: amount }; + + let token = IERC20Dispatcher { contract_address: link_token }; + token.transfer(recipient: payee, amount: amount); + + // Reset payment + self._reward_from_aggregator_round_id.write(oracle.index, latest_round_id); + self + ._transmitters + .write(transmitter, Oracle { index: oracle.index, payment_juels: 0_u128 }); + + self + .emit( + Event::OraclePaid( + OraclePaid { + transmitter: transmitter, + payee: payee, + amount: amount, + link_token: link_token + } + ) + ); + } - #[view] - fn link_available_for_payment() -> (bool, u128) { // (is negative, absolute difference) - let link_token = _link_token::read(); - let contract_address = starknet::info::get_contract_address(); + fn pay_oracles(ref self: ContractState) { + let mut index = self._oracles_len.read(); + let latest_round_id = self._latest_aggregator_round_id.read(); + let link_token = self._link_token.read(); + loop { + if index == 0_usize { + break (); + } + let transmitter = self._transmitters_list.read(index); + self.pay_oracle(transmitter, latest_round_id, link_token); + index -= 1; + } + } - let token = IERC20Dispatcher { contract_address: link_token }; - let balance = token.balance_of(account: contract_address); - // entire link supply fits into u96 so this should not fail - assert(balance.high == 0_u128, 'balance too high'); - let balance: u128 = balance.low; - - let due = total_link_due(); - if balance > due { - (false, balance - due) - } else { - (true, due - balance) + fn total_link_due(self: @ContractState) -> u128 { + let mut index = self._oracles_len.read(); + let latest_round_id = self._latest_aggregator_round_id.read(); + let mut total_rounds = 0; + let mut payments_juels = 0; + + loop { + if index == 0_usize { + break (); + } + let transmitter = self._transmitters_list.read(index); + let oracle = self._transmitters.read(transmitter); + assert(oracle.index != 0_usize, index.into()); // 0 == undefined + + let from_round_id = self._reward_from_aggregator_round_id.read(oracle.index); + let rounds = latest_round_id - from_round_id; + total_rounds += rounds; + payments_juels += oracle.payment_juels; + index -= 1; + }; + + let billing = self._billing.read(); + return (total_rounds * billing.observation_payment_gjuels.into() * GIGA) + + payments_juels; } } @@ -1129,7 +1190,7 @@ mod Aggregator { const MARGIN: u128 = 115_u128; fn calculate_reimbursement( - juels_per_fee_coin: u128, signature_count: usize, gas_price: u128, config: Billing + juels_per_fee_coin: u128, signature_count: usize, gas_price: u128, config: BillingConfig ) -> u128 { // TODO: determine new values for these constants // Based on estimateFee (f=1 14977, f=2 14989, f=3 15002 f=4 15014 f=5 15027, count = f+1) @@ -1146,71 +1207,92 @@ mod Aggregator { // --- Payee Management - #[event] - fn PayeeshipTransferRequested( - transmitter: ContractAddress, current: ContractAddress, proposed: ContractAddress, - ) {} - - #[event] - fn PayeeshipTransferred( - transmitter: ContractAddress, previous: ContractAddress, current: ContractAddress, - ) {} + use super::PayeeConfig; - #[derive(Copy, Drop, Serde)] - struct PayeeConfig { + #[derive(Drop, starknet::Event)] + struct PayeeshipTransferRequested { transmitter: ContractAddress, - payee: ContractAddress, + current: ContractAddress, + proposed: ContractAddress, } - #[external] - fn set_payees(payees: Array) { - Ownable::assert_only_owner(); - set_payee(payees) - } - - fn set_payee(mut payees: Array) { - let payee = match payees.pop_front() { - Option::Some(payee) => payee, - Option::None(_) => { - // No more payees left! - return (); + #[derive(Drop, starknet::Event)] + struct PayeeshipTransferred { + transmitter: ContractAddress, + previous: ContractAddress, + current: ContractAddress, + } + + #[external(v0)] + impl PayeeManagementImpl of super::PayeeManagement { + fn set_payees(ref self: ContractState, mut payees: Array) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + loop { + match payees.pop_front() { + Option::Some(payee) => { + let current_payee = self._payees.read(payee.transmitter); + let is_unset = current_payee.is_zero(); + let is_same = current_payee == payee.payee; + assert(is_unset | is_same, 'payee already set'); + + self._payees.write(payee.transmitter, payee.payee); + + self + .emit( + Event::PayeeshipTransferred( + PayeeshipTransferred { + transmitter: payee.transmitter, + previous: current_payee, + current: payee.payee + } + ) + ); + }, + Option::None(_) => { + // No more payees left! + break (); + } + }; } - }; - - let current_payee = _payees::read(payee.transmitter); - let is_unset = current_payee.is_zero(); - let is_same = current_payee == payee.payee; - assert(is_unset | is_same, 'payee already set'); - - _payees::write(payee.transmitter, payee.payee); - - PayeeshipTransferred(payee.transmitter, current_payee, payee.payee); - - gas::withdraw_gas_all(get_builtin_costs()).expect('Out of gas'); - set_payee(payees) - } - - #[external] - fn transfer_payeeship(transmitter: ContractAddress, proposed: ContractAddress) { - assert(!proposed.is_zero(), 'cannot transfer to zero address'); - let caller = starknet::info::get_caller_address(); - let payee = _payees::read(transmitter); - assert(caller == payee, 'only current payee can update'); - assert(caller != proposed, 'cannot transfer to self'); - - _proposed_payees::write(transmitter, proposed); - PayeeshipTransferRequested(transmitter, payee, proposed) - } + } - #[external] - fn accept_payeeship(transmitter: ContractAddress) { - let proposed = _proposed_payees::read(transmitter); - let caller = starknet::info::get_caller_address(); - assert(caller == proposed, 'only proposed payee can accept'); - let previous = _payees::read(transmitter); + fn transfer_payeeship( + ref self: ContractState, transmitter: ContractAddress, proposed: ContractAddress + ) { + assert(!proposed.is_zero(), 'cannot transfer to zero address'); + let caller = starknet::info::get_caller_address(); + let payee = self._payees.read(transmitter); + assert(caller == payee, 'only current payee can update'); + assert(caller != proposed, 'cannot transfer to self'); + + self._proposed_payees.write(transmitter, proposed); + self + .emit( + Event::PayeeshipTransferRequested( + PayeeshipTransferRequested { + transmitter: transmitter, current: payee, proposed: proposed + } + ) + ); + } - _payees::write(transmitter, proposed); - _proposed_payees::write(transmitter, Zeroable::zero()); - PayeeshipTransferred(transmitter, previous, caller) + fn accept_payeeship(ref self: ContractState, transmitter: ContractAddress) { + let proposed = self._proposed_payees.read(transmitter); + let caller = starknet::info::get_caller_address(); + assert(caller == proposed, 'only proposed payee can accept'); + let previous = self._payees.read(transmitter); + + self._payees.write(transmitter, proposed); + self._proposed_payees.write(transmitter, Zeroable::zero()); + self + .emit( + Event::PayeeshipTransferred( + PayeeshipTransferred { + transmitter: transmitter, previous: previous, current: caller + } + ) + ); + } } } diff --git a/contracts/src/ocr2/aggregator_proxy.cairo b/contracts/src/ocr2/aggregator_proxy.cairo index 1e55ce776..02176d0a5 100644 --- a/contracts/src/ocr2/aggregator_proxy.cairo +++ b/contracts/src/ocr2/aggregator_proxy.cairo @@ -1,24 +1,28 @@ use chainlink::ocr2::aggregator::Round; - -trait IAggregatorProxy { - fn latest_round_data() -> Round; - fn round_data(round_id: felt252) -> Round; - fn description() -> felt252; - fn decimals() -> u8; - fn type_and_version() -> felt252; +use chainlink::ocr2::aggregator::{IAggregator, IAggregatorDispatcher, IAggregatorDispatcherTrait}; +use starknet::ContractAddress; + +// TODO: use a generic param for the round_id? +#[starknet::interface] +trait IAggregatorProxy { + fn latest_round_data(self: @TContractState) -> Round; + fn round_data(self: @TContractState, round_id: felt252) -> Round; + fn description(self: @TContractState) -> felt252; + fn decimals(self: @TContractState) -> u8; + fn type_and_version(self: @TContractState) -> felt252; } -// TODO: is it possible not to duplicate this trait when we require the abi attribute? -#[abi] -trait IAggregator { - fn latest_round_data() -> Round; - fn round_data(round_id: u128) -> Round; - fn description() -> felt252; - fn decimals() -> u8; - fn type_and_version() -> felt252; +#[starknet::interface] +trait IAggregatorProxyInternal { + fn propose_aggregator(ref self: TContractState, address: ContractAddress); + fn confirm_aggregator(ref self: TContractState, address: ContractAddress); + fn proposed_latest_round_data(self: @TContractState) -> Round; + fn proposed_round_data(self: @TContractState, round_id: felt252) -> Round; + fn aggregator(self: @TContractState) -> ContractAddress; + fn phase_id(self: @TContractState) -> u128; } -#[contract] +#[starknet::contract] mod AggregatorProxy { use super::IAggregatorProxy; use super::IAggregatorDispatcher; @@ -34,7 +38,6 @@ mod AggregatorProxy { use starknet::ContractAddressIntoFelt252; use starknet::Felt252TryIntoContractAddress; use integer::Felt252TryIntoU128; - use starknet::StorageAccess; use starknet::StorageBaseAddress; use starknet::SyscallResult; use integer::U128IntoFelt252; @@ -46,48 +49,21 @@ mod AggregatorProxy { use chainlink::ocr2::aggregator::IAggregator; use chainlink::ocr2::aggregator::Round; - use chainlink::libraries::ownable::Ownable; - use chainlink::libraries::access_control::AccessControl; + use chainlink::libraries::ownable::{Ownable, IOwnable}; + use chainlink::libraries::access_control::{AccessControl, IAccessController}; use chainlink::utils::split_felt; use chainlink::libraries::upgradeable::Upgradeable; - const SHIFT: felt252 = 0x100000000000000000000000000000000_felt252; - const MAX_ID: felt252 = 0xffffffffffffffffffffffffffffffff_felt252; + const SHIFT: felt252 = 0x100000000000000000000000000000000; + const MAX_ID: felt252 = 0xffffffffffffffffffffffffffffffff; - #[derive(Copy, Drop, Serde)] + #[derive(Copy, Drop, Serde, starknet::Store)] struct Phase { id: u128, aggregator: ContractAddress } - impl PhaseStorageAccess of StorageAccess { - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult:: { - Result::Ok( - Phase { - id: storage_read_syscall( - address_domain, storage_address_from_base_and_offset(base, 0_u8) - )?.try_into().unwrap(), - aggregator: storage_read_syscall( - address_domain, storage_address_from_base_and_offset(base, 1_u8) - )?.try_into().unwrap(), - } - ) - } - - fn write( - address_domain: u32, base: StorageBaseAddress, value: Phase - ) -> SyscallResult::<()> { - storage_write_syscall( - address_domain, storage_address_from_base_and_offset(base, 0_u8), value.id.into() - )?; - storage_write_syscall( - address_domain, - storage_address_from_base_and_offset(base, 1_u8), - value.aggregator.into() - ) - } - } - + #[storage] struct Storage { _current_phase: Phase, _proposed_aggregator: ContractAddress, @@ -100,10 +76,11 @@ mod AggregatorProxy { #[event] fn AggregatorConfirmed(previous: ContractAddress, latest: ContractAddress) {} - impl AggregatorProxy of IAggregatorProxy { - fn latest_round_data() -> Round { - _require_read_access(); - let phase = _current_phase::read(); + #[external(v0)] + impl AggregatorProxyImpl of IAggregatorProxy { + fn latest_round_data(self: @ContractState) -> Round { + self._require_read_access(); + let phase = self._current_phase.read(); let aggregator = IAggregatorDispatcher { contract_address: phase.aggregator }; let round = aggregator.latest_round_data(); Round { @@ -114,10 +91,10 @@ mod AggregatorProxy { updated_at: round.updated_at, } } - fn round_data(round_id: felt252) -> Round { - _require_read_access(); + fn round_data(self: @ContractState, round_id: felt252) -> Round { + self._require_read_access(); let (phase_id, round_id) = split_felt(round_id); - let address = _phases::read(phase_id); + let address = self._phases.read(phase_id); assert(!address.is_zero(), 'aggregator address is 0'); let aggregator = IAggregatorDispatcher { contract_address: address }; @@ -131,194 +108,186 @@ mod AggregatorProxy { updated_at: round.updated_at, } } - fn description() -> felt252 { - _require_read_access(); - let phase = _current_phase::read(); + fn description(self: @ContractState) -> felt252 { + self._require_read_access(); + let phase = self._current_phase.read(); let aggregator = IAggregatorDispatcher { contract_address: phase.aggregator }; aggregator.description() } - fn decimals() -> u8 { - _require_read_access(); - let phase = _current_phase::read(); + fn decimals(self: @ContractState) -> u8 { + self._require_read_access(); + let phase = self._current_phase.read(); let aggregator = IAggregatorDispatcher { contract_address: phase.aggregator }; aggregator.decimals() } - fn type_and_version() -> felt252 { - let phase = _current_phase::read(); + fn type_and_version(self: @ContractState) -> felt252 { + let phase = self._current_phase.read(); let aggregator = IAggregatorDispatcher { contract_address: phase.aggregator }; aggregator.type_and_version() } } #[constructor] - fn constructor(owner: ContractAddress, address: ContractAddress) { - Ownable::initializer(owner); - AccessControl::initializer(); - _set_aggregator(address); + fn constructor(ref self: ContractState, owner: ContractAddress, address: ContractAddress) { + // TODO: ownable and access control need to share owners and update when needed + let mut ownable = Ownable::unsafe_new_contract_state(); + Ownable::constructor(ref ownable, owner); + let mut access_control = AccessControl::unsafe_new_contract_state(); + AccessControl::constructor(ref access_control); + self._set_aggregator(address); } // --- Ownership --- - #[view] - fn owner() -> ContractAddress { - Ownable::owner() - } + #[external(v0)] + impl OwnableImpl of IOwnable { + fn owner(self: @ContractState) -> ContractAddress { + let state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::owner(@state) + } - #[view] - fn proposed_owner() -> ContractAddress { - Ownable::proposed_owner() - } + fn proposed_owner(self: @ContractState) -> ContractAddress { + let state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::proposed_owner(@state) + } - #[external] - fn transfer_ownership(new_owner: ContractAddress) { - Ownable::transfer_ownership(new_owner) - } + fn transfer_ownership(ref self: ContractState, new_owner: ContractAddress) { + let mut state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::transfer_ownership(ref state, new_owner) + } - #[external] - fn accept_ownership() { - Ownable::accept_ownership() - } + fn accept_ownership(ref self: ContractState) { + let mut state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::accept_ownership(ref state) + } - #[external] - fn renounce_ownership() { - Ownable::renounce_ownership() + fn renounce_ownership(ref self: ContractState) { + let mut state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::renounce_ownership(ref state) + } } // -- Upgradeable -- - #[external] - fn upgrade(new_impl: ClassHash) { - Ownable::assert_only_owner(); + #[external(v0)] + fn upgrade(ref self: ContractState, new_impl: ClassHash) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); Upgradeable::upgrade(new_impl) } // -- Access Control -- - #[view] - fn has_access(user: ContractAddress, data: Array) -> bool { - AccessControl::has_access(user, data) - } + #[external(v0)] + impl AccessControllerImpl of IAccessController { + fn has_access(self: @ContractState, user: ContractAddress, data: Array) -> bool { + let state = AccessControl::unsafe_new_contract_state(); + AccessControl::has_access(@state, user, data) + } - #[external] - fn add_access(user: ContractAddress) { - Ownable::assert_only_owner(); - AccessControl::add_access(user) - } + fn add_access(ref self: ContractState, user: ContractAddress) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + let mut state = AccessControl::unsafe_new_contract_state(); + AccessControl::add_access(ref state, user) + } - #[external] - fn remove_access(user: ContractAddress) { - Ownable::assert_only_owner(); - AccessControl::remove_access(user) - } + fn remove_access(ref self: ContractState, user: ContractAddress) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + let mut state = AccessControl::unsafe_new_contract_state(); + AccessControl::remove_access(ref state, user) + } - #[external] - fn enable_access_check() { - Ownable::assert_only_owner(); - AccessControl::enable_access_check() - } + fn enable_access_check(ref self: ContractState) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + let mut state = AccessControl::unsafe_new_contract_state(); + AccessControl::enable_access_check(ref state) + } - #[external] - fn disable_access_check() { - Ownable::assert_only_owner(); - AccessControl::disable_access_check() + fn disable_access_check(ref self: ContractState) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + let mut state = AccessControl::unsafe_new_contract_state(); + AccessControl::disable_access_check(ref state) + } } // - #[external] - fn propose_aggregator(address: ContractAddress) { - Ownable::assert_only_owner(); - assert(!address.is_zero(), 'proposed address is 0'); - _proposed_aggregator::write(address); - - let phase = _current_phase::read(); - AggregatorProposed(phase.aggregator, address); - } - - #[external] - fn confirm_aggregator(address: ContractAddress) { - Ownable::assert_only_owner(); - assert(!address.is_zero(), 'confirm address is 0'); - let phase = _current_phase::read(); - let previous = phase.aggregator; - - let proposed_aggregator = _proposed_aggregator::read(); - assert(address == proposed_aggregator, 'does not match proposed address'); - _proposed_aggregator::write(starknet::contract_address_const::<0>()); - _set_aggregator(proposed_aggregator); - - AggregatorConfirmed(previous, address); - } - - #[view] - fn proposed_latest_round_data() -> Round { - _require_read_access(); - let address = _proposed_aggregator::read(); - let aggregator = IAggregatorDispatcher { contract_address: address }; - aggregator.latest_round_data() - } + #[external(v0)] + impl AggregatorProxyInternal of super::IAggregatorProxyInternal { + fn propose_aggregator(ref self: ContractState, address: ContractAddress) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + assert(!address.is_zero(), 'proposed address is 0'); + self._proposed_aggregator.write(address); - #[view] - fn proposed_round_data(round_id: felt252) -> Round { - _require_read_access(); - let address = _proposed_aggregator::read(); - let round_id128: u128 = round_id.try_into().unwrap(); - let aggregator = IAggregatorDispatcher { contract_address: address }; - aggregator.round_data(round_id128) - } + let phase = self._current_phase.read(); + AggregatorProposed(phase.aggregator, address); + } - #[view] - fn aggregator() -> ContractAddress { - _require_read_access(); - let phase = _current_phase::read(); - phase.aggregator - } + fn confirm_aggregator(ref self: ContractState, address: ContractAddress) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); + assert(!address.is_zero(), 'confirm address is 0'); + let phase = self._current_phase.read(); + let previous = phase.aggregator; - #[view] - fn phase_id() -> u128 { - _require_read_access(); - let phase = _current_phase::read(); - phase.id - } + let proposed_aggregator = self._proposed_aggregator.read(); + assert(address == proposed_aggregator, 'does not match proposed address'); + self._proposed_aggregator.write(starknet::contract_address_const::<0>()); + self._set_aggregator(proposed_aggregator); - #[view] - fn latest_round_data() -> Round { - AggregatorProxy::latest_round_data() - } + AggregatorConfirmed(previous, address); + } - #[view] - fn round_data(round_id: felt252) -> Round { - AggregatorProxy::round_data(round_id) - } + fn proposed_latest_round_data(self: @ContractState) -> Round { + self._require_read_access(); + let address = self._proposed_aggregator.read(); + let aggregator = IAggregatorDispatcher { contract_address: address }; + aggregator.latest_round_data() + } - #[view] - fn description() -> felt252 { - AggregatorProxy::description() - } + fn proposed_round_data(self: @ContractState, round_id: felt252) -> Round { + self._require_read_access(); + let address = self._proposed_aggregator.read(); + let round_id128: u128 = round_id.try_into().unwrap(); + let aggregator = IAggregatorDispatcher { contract_address: address }; + aggregator.round_data(round_id128) + } - #[view] - fn decimals() -> u8 { - AggregatorProxy::decimals() - } + fn aggregator(self: @ContractState) -> ContractAddress { + self._require_read_access(); + let phase = self._current_phase.read(); + phase.aggregator + } - #[view] - fn type_and_version() -> felt252 { - AggregatorProxy::type_and_version() + fn phase_id(self: @ContractState) -> u128 { + self._require_read_access(); + let phase = self._current_phase.read(); + phase.id + } } /// Internals - fn _set_aggregator(address: ContractAddress) { - let phase = _current_phase::read(); - let new_phase_id = phase.id + 1_u128; - _current_phase::write(Phase { id: new_phase_id, aggregator: address }); - _phases::write(new_phase_id, address); - } + #[generate_trait] + impl StorageImpl of StorageTrait { + fn _set_aggregator(ref self: ContractState, address: ContractAddress) { + let phase = self._current_phase.read(); + let new_phase_id = phase.id + 1_u128; + self._current_phase.write(Phase { id: new_phase_id, aggregator: address }); + self._phases.write(new_phase_id, address); + } - fn _require_read_access() { - let caller = starknet::info::get_caller_address(); - AccessControl::check_read_access(caller); + fn _require_read_access(self: @ContractState) { + let caller = starknet::info::get_caller_address(); + let state = AccessControl::unsafe_new_contract_state(); + AccessControl::check_read_access(@state, caller); + } } } diff --git a/contracts/src/ocr2/mocks/mock_aggregator.cairo b/contracts/src/ocr2/mocks/mock_aggregator.cairo index 9d6a5720b..e7e6cd622 100644 --- a/contracts/src/ocr2/mocks/mock_aggregator.cairo +++ b/contracts/src/ocr2/mocks/mock_aggregator.cairo @@ -1,14 +1,25 @@ -#[contract] +#[starknet::interface] +trait IMockAggregator { + fn set_latest_round_data( + ref self: TContractState, + answer: u128, + block_num: u64, + observation_timestamp: u64, + transmission_timestamp: u64 + ); +} + +#[starknet::contract] mod MockAggregator { use array::ArrayTrait; use starknet::contract_address_const; use traits::Into; - use chainlink::ocr2::aggregator::Aggregator::Transmission; - use chainlink::ocr2::aggregator::Aggregator::TransmissionStorageAccess; - use chainlink::ocr2::aggregator::Aggregator::NewTransmission; + use chainlink::ocr2::aggregator::IAggregator; + use chainlink::ocr2::aggregator::Aggregator::{Transmission, NewTransmission, Event}; use chainlink::ocr2::aggregator::Round; + #[storage] struct Storage { _transmissions: LegacyMap, _latest_aggregator_round_id: u128, @@ -16,63 +27,88 @@ mod MockAggregator { } #[constructor] - fn constructor(decimals: u8) { - _decimals::write(decimals); + fn constructor(ref self: ContractState, decimals: u8) { + self._decimals.write(decimals); } - #[external] - fn set_latest_round_data( - answer: u128, block_num: u64, observation_timestamp: u64, transmission_timestamp: u64 - ) { - let new_round_id = _latest_aggregator_round_id::read() + 1_u128; - - _transmissions::write( - new_round_id, - Transmission { - answer: answer, - block_num: block_num, - observation_timestamp: observation_timestamp, - transmission_timestamp: transmission_timestamp - } - ); + #[external(v0)] + impl MockImpl of super::IMockAggregator { + fn set_latest_round_data( + ref self: ContractState, + answer: u128, + block_num: u64, + observation_timestamp: u64, + transmission_timestamp: u64 + ) { + let new_round_id = self._latest_aggregator_round_id.read() + 1_u128; + self + ._transmissions + .write( + new_round_id, + Transmission { + answer: answer, + block_num: block_num, + observation_timestamp: observation_timestamp, + transmission_timestamp: transmission_timestamp + } + ); - let mut observations = ArrayTrait::new(); - observations.append(2_u128); - observations.append(3_u128); + let mut observations = ArrayTrait::new(); + observations.append(2_u128); + observations.append(3_u128); - _latest_aggregator_round_id::write(new_round_id); + self._latest_aggregator_round_id.write(new_round_id); - NewTransmission( - new_round_id, - answer, - contract_address_const::<42>(), - observation_timestamp, - 3, - observations, - 18_u128, - 1_u128, - 777, - 20_u64, - 100_u128 - ); + self + .emit( + Event::NewTransmission( + NewTransmission { + round_id: new_round_id, + answer: answer, + transmitter: contract_address_const::<42>(), + observation_timestamp: observation_timestamp, + observers: 3, + observations: observations, + juels_per_fee_coin: 18_u128, + gas_price: 1_u128, + config_digest: 777, + epoch_and_round: 20_u64, + reimbursement: 100_u128 + } + ) + ); + } } - #[view] - fn latest_round_data() -> Round { - let latest_round_id = _latest_aggregator_round_id::read(); - let transmission = _transmissions::read(latest_round_id); + #[external(v0)] + impl Aggregator of IAggregator { + fn round_data(self: @ContractState, round_id: u128) -> Round { + panic_with_felt252('unimplemented') + } + + fn latest_round_data(self: @ContractState) -> Round { + let latest_round_id = self._latest_aggregator_round_id.read(); + let transmission = self._transmissions.read(latest_round_id); - Round { - round_id: latest_round_id.into(), - answer: transmission.answer, - block_num: transmission.block_num, - started_at: transmission.observation_timestamp, - updated_at: transmission.transmission_timestamp + Round { + round_id: latest_round_id.into(), + answer: transmission.answer, + block_num: transmission.block_num, + started_at: transmission.observation_timestamp, + updated_at: transmission.transmission_timestamp + } + } + + fn decimals(self: @ContractState) -> u8 { + self._decimals.read() + } + + fn description(self: @ContractState) -> felt252 { + 'mock' } - } - #[view] - fn decimals() -> u8 { - _decimals::read() + fn type_and_version(self: @ContractState) -> felt252 { + 'mock_aggregator.cairo 1.0.0' + } } } diff --git a/contracts/src/tests/test_access_controller.cairo b/contracts/src/tests/test_access_controller.cairo index 179ee9d9b..f9d270b50 100644 --- a/contracts/src/tests/test_access_controller.cairo +++ b/contracts/src/tests/test_access_controller.cairo @@ -13,6 +13,13 @@ use option::OptionTrait; use core::result::ResultTrait; use chainlink::access_control::access_controller::AccessController; +use chainlink::libraries::access_control::{ + IAccessController, IAccessControllerDispatcher, IAccessControllerDispatcherTrait +}; + +fn STATE() -> AccessController::ContractState { + AccessController::contract_state_for_testing() +} fn setup() -> ContractAddress { let account: ContractAddress = contract_address_const::<777>(); @@ -25,8 +32,9 @@ fn setup() -> ContractAddress { #[should_panic(expected: ('Ownable: caller is not owner', ))] fn test_upgrade_not_owner() { let sender = setup(); + let mut state = STATE(); - AccessController::upgrade(class_hash_const::<2>()); + AccessController::upgrade(ref state, class_hash_const::<2>()); } #[test] @@ -34,11 +42,12 @@ fn test_upgrade_not_owner() { fn test_access_control() { let owner = setup(); // Deploy access controller - let mut calldata = ArrayTrait::new(); - calldata.append(owner.into()); // owner + let calldata = array![owner.into(), // owner + ]; let (accessControllerAddr, _) = deploy_syscall( AccessController::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false - ).unwrap(); + ) + .unwrap(); should_implement_access_control(accessControllerAddr, owner); } @@ -49,15 +58,6 @@ fn test_access_control() { // but this test does not check for that. // -#[abi] -trait IAccessController { - fn has_access(user: ContractAddress, data: Array) -> bool; - fn add_access(user: ContractAddress); - fn remove_access(user: ContractAddress); - fn enable_access_check(); - fn disable_access_check(); -} - fn should_implement_access_control(contract_addr: ContractAddress, owner: ContractAddress) { let contract = IAccessControllerDispatcher { contract_address: contract_addr }; let acc2: ContractAddress = contract_address_const::<2222987765>(); @@ -65,21 +65,21 @@ fn should_implement_access_control(contract_addr: ContractAddress, owner: Contra set_contract_address(owner); // required to call contract as owner // access check is enabled by default - assert(!contract.has_access(acc2, ArrayTrait::new()), 'should not have access'); + assert(!contract.has_access(acc2, array![]), 'should not have access'); // disable access check contract.disable_access_check(); - assert(contract.has_access(acc2, ArrayTrait::new()), 'should have access'); + assert(contract.has_access(acc2, array![]), 'should have access'); // enable access check contract.enable_access_check(); - assert(!contract.has_access(acc2, ArrayTrait::new()), 'should not have access'); + assert(!contract.has_access(acc2, array![]), 'should not have access'); // add_access for acc2 contract.add_access(acc2); - assert(contract.has_access(acc2, ArrayTrait::new()), 'should have access'); + assert(contract.has_access(acc2, array![]), 'should have access'); // remove_access for acc2 contract.remove_access(acc2); - assert(!contract.has_access(acc2, ArrayTrait::new()), 'should not have access'); + assert(!contract.has_access(acc2, array![]), 'should not have access'); } diff --git a/contracts/src/tests/test_aggregator.cairo b/contracts/src/tests/test_aggregator.cairo index afad0832f..db6eb6c70 100644 --- a/contracts/src/tests/test_aggregator.cairo +++ b/contracts/src/tests/test_aggregator.cairo @@ -7,6 +7,7 @@ use starknet::class_hash::Felt252TryIntoClassHash; use starknet::syscalls::deploy_syscall; use array::ArrayTrait; +use clone::Clone; use traits::Into; use traits::TryInto; use option::OptionTrait; @@ -14,13 +15,14 @@ use core::result::ResultTrait; use chainlink::ocr2::aggregator::pow; use chainlink::ocr2::aggregator::Aggregator; -use chainlink::ocr2::aggregator::Aggregator::Billing; +use chainlink::ocr2::aggregator::Aggregator::{AggregatorImpl, BillingImpl, PayeeManagementImpl}; +use chainlink::ocr2::aggregator::Aggregator::BillingConfig; +use chainlink::ocr2::aggregator::Aggregator::PayeeConfig; use chainlink::access_control::access_controller::AccessController; +use chainlink::token::link_token::LinkToken; use chainlink::tests::test_ownable::should_implement_ownable; use chainlink::tests::test_access_controller::should_implement_access_control; -// TODO: aggregator tests - #[test] #[available_gas(10000000)] fn test_pow_2_0() { @@ -58,33 +60,48 @@ fn test_pow_2_0() { assert(pow(2, 31) == 0x80000000, 'expected 0x80000000'); } -#[abi] -trait IAccessController { // importing from access_controller.cairo doesnt work - fn has_access(user: ContractAddress, data: Array) -> bool; - fn add_access(user: ContractAddress); - fn remove_access(user: ContractAddress); - fn enable_access_check(); - fn disable_access_check(); +use chainlink::libraries::access_control::{ + IAccessController, IAccessControllerDispatcher, IAccessControllerDispatcherTrait +}; + +#[starknet::interface] +trait ILinkToken {} + +fn STATE() -> Aggregator::ContractState { + Aggregator::contract_state_for_testing() } -fn setup() -> (ContractAddress, ContractAddress, ContractAddress, IAccessControllerDispatcher) { +fn setup() -> ( + ContractAddress, ContractAddress, IAccessControllerDispatcher, ILinkTokenDispatcher +) { let acc1: ContractAddress = contract_address_const::<777>(); let acc2: ContractAddress = contract_address_const::<888>(); // set acc1 as default caller set_caller_address(acc1); // deploy billing access controller - let mut calldata = ArrayTrait::new(); - calldata.append(acc1.into()); // owner = acc1; + let calldata = array![acc1.into(), // owner = acc1; + ]; let (billingAccessControllerAddr, _) = deploy_syscall( AccessController::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false - ).unwrap(); + ) + .unwrap(); let billingAccessController = IAccessControllerDispatcher { contract_address: billingAccessControllerAddr }; - // return accounts and billing access controller - (acc1, acc2, billingAccessControllerAddr, billingAccessController) + // deploy link token contract + let calldata = array![acc1.into(), // minter = acc1; + acc1.into(), // owner = acc1; + ]; + let (linkTokenAddr, _) = deploy_syscall( + LinkToken::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false + ) + .unwrap(); + let linkToken = ILinkTokenDispatcher { contract_address: linkTokenAddr }; + + // return accounts, billing access controller, link token + (acc1, acc2, billingAccessController, linkToken) } #[test] @@ -92,37 +109,41 @@ fn setup() -> (ContractAddress, ContractAddress, ContractAddress, IAccessControl fn test_ownable() { let (account, _, _, _) = setup(); // Deploy aggregator - let mut calldata = ArrayTrait::new(); - calldata.append(account.into()); // owner - calldata.append(contract_address_const::<777>().into()); // link token - calldata.append(0); // min_answer - calldata.append(100); // max_answer - calldata.append(contract_address_const::<999>().into()); // billing access controller - calldata.append(8); // decimals - calldata.append(123); // description + let calldata = array![ + account.into(), // owner + contract_address_const::<777>().into(), // link token + 0, // min_answer + 100, // max_answer + contract_address_const::<999>().into(), // billing access controller + 8, // decimals + 123, // description + ]; let (aggregatorAddr, _) = deploy_syscall( Aggregator::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false - ).unwrap(); + ) + .unwrap(); should_implement_ownable(aggregatorAddr, account); } #[test] -#[available_gas(2000000)] +#[available_gas(3000000)] fn test_access_control() { let (account, _, _, _) = setup(); // Deploy aggregator - let mut calldata = ArrayTrait::new(); - calldata.append(account.into()); // owner - calldata.append(contract_address_const::<777>().into()); // link token - calldata.append(0); // min_answer - calldata.append(100); // max_answer - calldata.append(contract_address_const::<999>().into()); // billing access controller - calldata.append(8); // decimals - calldata.append(123); // description + let mut calldata = array![ + account.into(), // owner + contract_address_const::<777>().into(), // link token + 0, // min_answer + 100, // max_answer + contract_address_const::<999>().into(), // billing access controller + 8, // decimals + 123, // description + ]; let (aggregatorAddr, _) = deploy_syscall( Aggregator::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false - ).unwrap(); + ) + .unwrap(); should_implement_access_control(aggregatorAddr, account); } @@ -133,7 +154,8 @@ fn test_access_control() { #[should_panic(expected: ('Ownable: caller is not owner', ))] fn test_upgrade_non_owner() { let sender = setup(); - Aggregator::upgrade(class_hash_const::<123>()); + let mut state = STATE(); + Aggregator::upgrade(ref state, class_hash_const::<123>()); } // --- Billing tests --- @@ -142,56 +164,72 @@ fn test_upgrade_non_owner() { #[available_gas(2000000)] #[should_panic(expected: ('Ownable: caller is not owner', ))] fn test_set_billing_access_controller_not_owner() { - let (owner, acc2, billingAccessControllerAddr, _) = setup(); - // Aggregator initialization - Aggregator::constructor(owner, contract_address_const::<777>(), 0, 100, acc2, 8, 123); + let (owner, acc2, billingAccessController, _) = setup(); + let mut state = STATE(); + Aggregator::constructor( + ref state, owner, contract_address_const::<777>(), 0, 100, acc2, 8, 123 + ); // set billing access controller should revert if caller is not owner set_caller_address(acc2); - Aggregator::set_billing_access_controller(billingAccessControllerAddr); + BillingImpl::set_billing_access_controller(ref state, billingAccessController.contract_address); } #[test] #[available_gas(2000000)] #[should_panic(expected: ('caller does not have access', ))] fn test_set_billing_config_no_access() { - let (owner, acc2, billingAccessControllerAddr, _) = setup(); - // Aggregator initialization + let (owner, acc2, billingAccessController, _) = setup(); + let mut state = STATE(); Aggregator::constructor( - owner, contract_address_const::<777>(), 0, 100, billingAccessControllerAddr, 8, 123 + ref state, + owner, + contract_address_const::<777>(), + 0, + 100, + billingAccessController.contract_address, + 8, + 123 ); // set billing config as acc2 with no access - let config: Billing = Billing { + let config = BillingConfig { observation_payment_gjuels: 1, transmission_payment_gjuels: 5, gas_base: 1, gas_per_signature: 1, }; set_caller_address(acc2); - Aggregator::set_billing(config); + BillingImpl::set_billing(ref state, config); } #[test] #[available_gas(2000000)] fn test_set_billing_config_as_owner() { - let (owner, _, billingAccessControllerAddr, _) = setup(); - // Aggregator initialization + let (owner, _, billingAccessController, _) = setup(); + let mut state = STATE(); Aggregator::constructor( - owner, contract_address_const::<777>(), 0, 100, billingAccessControllerAddr, 8, 123 + ref state, + owner, + contract_address_const::<777>(), + 0, + 100, + billingAccessController.contract_address, + 8, + 123 ); // set billing config as owner - let config: Billing = Billing { + let config = BillingConfig { observation_payment_gjuels: 1, transmission_payment_gjuels: 5, gas_base: 1, gas_per_signature: 1, }; - Aggregator::set_billing(config); + BillingImpl::set_billing(ref state, config); // check billing config - let billing = Aggregator::billing(); + let billing = BillingImpl::billing(@state); assert(billing.observation_payment_gjuels == 1, 'should be 1'); assert(billing.transmission_payment_gjuels == 5, 'should be 5'); assert(billing.gas_base == 1, 'should be 1'); @@ -201,30 +239,206 @@ fn test_set_billing_config_as_owner() { #[test] #[available_gas(2000000)] fn test_set_billing_config_as_acc_with_access() { - let (owner, acc2, billingAccessControllerAddr, billingAccessController) = setup(); + let (owner, acc2, billingAccessController, _) = setup(); + let mut state = STATE(); // grant acc2 access on access controller set_contract_address(owner); billingAccessController.add_access(acc2); - // Aggregator initialization Aggregator::constructor( - owner, contract_address_const::<777>(), 0, 100, billingAccessControllerAddr, 8, 123 + ref state, + owner, + contract_address_const::<777>(), + 0, + 100, + billingAccessController.contract_address, + 8, + 123 ); // set billing config as acc2 with access - let config: Billing = Billing { + let config = BillingConfig { observation_payment_gjuels: 1, transmission_payment_gjuels: 5, gas_base: 1, gas_per_signature: 1, }; set_caller_address(acc2); - Aggregator::set_billing(config); + BillingImpl::set_billing(ref state, config); // check billing config - let billing = Aggregator::billing(); + let billing = BillingImpl::billing(@state); assert(billing.observation_payment_gjuels == 1, 'should be 1'); assert(billing.transmission_payment_gjuels == 5, 'should be 5'); assert(billing.gas_base == 1, 'should be 1'); assert(billing.gas_per_signature == 1, 'should be 1'); } + +// --- Payee Management Tests --- + +#[test] +#[available_gas(2000000)] +#[should_panic(expected: ('Ownable: caller is not owner', ))] +fn test_set_payees_caller_not_owner() { + let (owner, acc2, _, _) = setup(); + let mut state = STATE(); + Aggregator::constructor( + ref state, owner, contract_address_const::<777>(), 0, 100, acc2, 8, 123 + ); + + let payees = array![PayeeConfig { transmitter: acc2, payee: acc2, }, ]; + + // set payee should revert if caller is not owner + set_caller_address(acc2); + PayeeManagementImpl::set_payees(ref state, payees); +} + +#[test] +#[available_gas(2000000)] +fn test_set_single_payee() { + let (owner, acc2, _, _) = setup(); + let mut state = STATE(); + Aggregator::constructor( + ref state, owner, contract_address_const::<777>(), 0, 100, acc2, 8, 123 + ); + + let payees = array![PayeeConfig { transmitter: acc2, payee: acc2, }, ]; + + set_caller_address(owner); + PayeeManagementImpl::set_payees(ref state, payees); +} + +#[test] +#[available_gas(2000000)] +fn test_set_multiple_payees() { + let (owner, acc2, _, _) = setup(); + let mut state = STATE(); + Aggregator::constructor( + ref state, owner, contract_address_const::<777>(), 0, 100, acc2, 8, 123 + ); + + let payees = array![ + PayeeConfig { + transmitter: acc2, payee: acc2, + }, PayeeConfig { + transmitter: owner, payee: owner, + }, + ]; + + set_caller_address(owner); + PayeeManagementImpl::set_payees(ref state, payees); +} + +#[test] +#[available_gas(2000000)] +#[should_panic(expected: ('only current payee can update', ))] +fn test_transfer_payeeship_caller_not_payee() { + let (owner, acc2, _, _) = setup(); + let mut state = STATE(); + Aggregator::constructor( + ref state, owner, contract_address_const::<777>(), 0, 100, acc2, 8, 123 + ); + + let transmitter = contract_address_const::<123>(); + let payees = array![PayeeConfig { transmitter: transmitter, payee: acc2, }, ]; + + set_caller_address(owner); + PayeeManagementImpl::set_payees(ref state, payees); + PayeeManagementImpl::transfer_payeeship(ref state, transmitter, owner); +} + +#[test] +#[available_gas(2000000)] +#[should_panic(expected: ('cannot transfer to self', ))] +fn test_transfer_payeeship_to_self() { + let (owner, acc2, _, _) = setup(); + let mut state = STATE(); + Aggregator::constructor( + ref state, owner, contract_address_const::<777>(), 0, 100, acc2, 8, 123 + ); + + let transmitter = contract_address_const::<123>(); + let payees = array![PayeeConfig { transmitter: transmitter, payee: acc2, }, ]; + + set_caller_address(owner); + PayeeManagementImpl::set_payees(ref state, payees); + set_caller_address(acc2); + PayeeManagementImpl::transfer_payeeship(ref state, transmitter, acc2); +} + +#[test] +#[available_gas(2000000)] +#[should_panic(expected: ('only proposed payee can accept', ))] +fn test_accept_payeeship_caller_not_proposed_payee() { + let (owner, acc2, _, _) = setup(); + let mut state = STATE(); + Aggregator::constructor( + ref state, owner, contract_address_const::<777>(), 0, 100, acc2, 8, 123 + ); + + let transmitter = contract_address_const::<123>(); + let payees = array![PayeeConfig { transmitter: transmitter, payee: acc2, }, ]; + + set_caller_address(owner); + PayeeManagementImpl::set_payees(ref state, payees); + set_caller_address(acc2); + PayeeManagementImpl::transfer_payeeship(ref state, transmitter, owner); + PayeeManagementImpl::accept_payeeship(ref state, transmitter); +} + +#[test] +#[available_gas(2000000)] +fn test_transfer_and_accept_payeeship() { + let (owner, acc2, _, _) = setup(); + let mut state = STATE(); + Aggregator::constructor( + ref state, owner, contract_address_const::<777>(), 0, 100, acc2, 8, 123 + ); + + let transmitter = contract_address_const::<123>(); + let payees = array![PayeeConfig { transmitter: transmitter, payee: acc2, }, ]; + + set_caller_address(owner); + PayeeManagementImpl::set_payees(ref state, payees); + set_caller_address(acc2); + PayeeManagementImpl::transfer_payeeship(ref state, transmitter, owner); + set_caller_address(owner); + PayeeManagementImpl::accept_payeeship(ref state, transmitter); +} +// --- Payments and Withdrawals Tests --- +// +// NOTE: this test suite largely incomplete as we cannot generate or mock +// off-chain signatures in cairo-test, and thus cannot generate aggregator rounds. +// We could explore testing against a mock aggregator contract with the signature +// verification logic removed in the future. + +#[test] +#[available_gas(2000000)] +fn test_owed_payment_no_rounds() { + let (owner, acc2, _, _) = setup(); + let mut state = STATE(); + Aggregator::constructor( + ref state, owner, contract_address_const::<777>(), 0, 100, acc2, 8, 123 + ); + + let transmitter = contract_address_const::<123>(); + let mut payees = array![PayeeConfig { transmitter: transmitter, payee: acc2, }, ]; + + set_caller_address(owner); + PayeeManagementImpl::set_payees(ref state, payees); + + let owed = BillingImpl::owed_payment(@state, transmitter); + assert(owed == 0, 'owed payment should be 0'); +} + +#[test] +#[available_gas(2000000)] +fn test_link_available_for_payment_no_rounds_or_funds() { + let (owner, acc2, _, linkToken) = setup(); + let mut state = STATE(); + Aggregator::constructor(ref state, owner, linkToken.contract_address, 0, 100, acc2, 8, 123); + + let (is_negative, diff) = BillingImpl::link_available_for_payment(@state); + assert(is_negative == true, 'is_negative should be true'); + assert(diff == 0, 'absolute_diff should be 0'); +} diff --git a/contracts/src/tests/test_aggregator_proxy.cairo b/contracts/src/tests/test_aggregator_proxy.cairo index 9c2c999c3..4ce1087e9 100644 --- a/contracts/src/tests/test_aggregator_proxy.cairo +++ b/contracts/src/tests/test_aggregator_proxy.cairo @@ -11,20 +11,21 @@ use traits::TryInto; use option::OptionTrait; use core::result::ResultTrait; -use chainlink::ocr2::mocks::mock_aggregator::MockAggregator; +use chainlink::ocr2::mocks::mock_aggregator::{ + MockAggregator, IMockAggregator, IMockAggregatorDispatcher, IMockAggregatorDispatcherTrait +}; +// use chainlink::ocr2::aggregator::{IAggregator, IAggregatorDispatcher, IAggregatorDispatcherTrait}; use chainlink::ocr2::aggregator_proxy::AggregatorProxy; +use chainlink::ocr2::aggregator_proxy::AggregatorProxy::{ + AggregatorProxyImpl, AggregatorProxyInternal, AccessControllerImpl +}; use chainlink::ocr2::aggregator::Round; use chainlink::utils::split_felt; use chainlink::tests::test_ownable::should_implement_ownable; use chainlink::tests::test_access_controller::should_implement_access_control; -#[abi] -trait IMockAggregator { - fn set_latest_round_data( - answer: u128, block_num: u64, observation_timestamp: u64, transmission_timestamp: u64 - ); - fn latest_round_data() -> Round; - fn decimals() -> u8; +fn STATE() -> AggregatorProxy::ContractState { + AggregatorProxy::contract_state_for_testing() } fn setup() -> ( @@ -43,13 +44,15 @@ fn setup() -> ( calldata.append(8); // decimals = 8 let (mockAggregatorAddr1, _) = deploy_syscall( MockAggregator::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false - ).unwrap(); + ) + .unwrap(); let mockAggregator1 = IMockAggregatorDispatcher { contract_address: mockAggregatorAddr1 }; // Deploy mock aggregator 2 let (mockAggregatorAddr2, _) = deploy_syscall( MockAggregator::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false - ).unwrap(); + ) + .unwrap(); let mockAggregator2 = IMockAggregatorDispatcher { contract_address: mockAggregatorAddr2 }; // Return account, mock aggregator address and mock aggregator contract @@ -61,27 +64,27 @@ fn setup() -> ( fn test_ownable() { let (account, mockAggregatorAddr, _, _, _) = setup(); // Deploy aggregator proxy - let mut calldata = ArrayTrait::new(); - calldata.append(account.into()); // owner = account - calldata.append(mockAggregatorAddr.into()); + let calldata = array![account.into(), // owner = account + mockAggregatorAddr.into(), ]; let (aggregatorProxyAddr, _) = deploy_syscall( AggregatorProxy::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false - ).unwrap(); + ) + .unwrap(); should_implement_ownable(aggregatorProxyAddr, account); } #[test] -#[available_gas(2000000)] +#[available_gas(3000000)] fn test_access_control() { let (account, mockAggregatorAddr, _, _, _) = setup(); // Deploy aggregator proxy - let mut calldata = ArrayTrait::new(); - calldata.append(account.into()); // owner = account - calldata.append(mockAggregatorAddr.into()); + let calldata = array![account.into(), // owner = account + mockAggregatorAddr.into(), ]; let (aggregatorProxyAddr, _) = deploy_syscall( AggregatorProxy::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false - ).unwrap(); + ) + .unwrap(); should_implement_access_control(aggregatorProxyAddr, account); } @@ -91,18 +94,20 @@ fn test_access_control() { #[should_panic(expected: ('Ownable: caller is not owner', ))] fn test_upgrade_non_owner() { let (_, _, _, _, _) = setup(); - AggregatorProxy::upgrade(class_hash_const::<123>()); + let mut state = STATE(); + AggregatorProxy::upgrade(ref state, class_hash_const::<123>()); } fn test_query_latest_round_data() { let (owner, mockAggregatorAddr, mockAggregator, _, _) = setup(); + let mut state = STATE(); // init aggregator proxy with mock aggregator - AggregatorProxy::constructor(owner, mockAggregatorAddr); - AggregatorProxy::add_access(owner); + AggregatorProxy::constructor(ref state, owner, mockAggregatorAddr); + AccessControllerImpl::add_access(ref state, owner); // insert round into mock aggregator mockAggregator.set_latest_round_data(10, 1, 9, 8); // query latest round - let round = AggregatorProxy::latest_round_data(); + let round = AggregatorProxyImpl::latest_round_data(@state); let (phase_id, round_id) = split_felt(round.round_id); assert(phase_id == 1, 'phase_id should be 1'); assert(round_id == 1, 'round_id should be 1'); @@ -117,72 +122,75 @@ fn test_query_latest_round_data() { #[should_panic(expected: ('user does not have read access', ))] fn test_query_latest_round_data_without_access() { let (owner, mockAggregatorAddr, mockAggregator, _, _) = setup(); + let mut state = STATE(); // init aggregator proxy with mock aggregator - AggregatorProxy::constructor(owner, mockAggregatorAddr); - AggregatorProxy::add_access(owner); + AggregatorProxy::constructor(ref state, owner, mockAggregatorAddr); + AccessControllerImpl::add_access(ref state, owner); // insert round into mock aggregator mockAggregator.set_latest_round_data(10, 1, 9, 8); // set caller to non-owner address with no read access set_caller_address(contract_address_const::<2>()); // query latest round - AggregatorProxy::latest_round_data(); + AggregatorProxyImpl::latest_round_data(@state); } #[test] -#[available_gas(2000000)] +#[available_gas(3000000)] fn test_propose_new_aggregator() { let (owner, mockAggregatorAddr1, mockAggregator1, mockAggregatorAddr2, mockAggregator2) = setup(); + let mut state = STATE(); // init aggregator proxy with mock aggregator 1 - AggregatorProxy::constructor(owner, mockAggregatorAddr1); - AggregatorProxy::add_access(owner); + AggregatorProxy::constructor(ref state, owner, mockAggregatorAddr1); + AccessControllerImpl::add_access(ref state, owner); // insert rounds into mock aggregators mockAggregator1.set_latest_round_data(10, 1, 9, 8); mockAggregator2.set_latest_round_data(12, 2, 10, 11); // propose new mock aggregator to AggregatorProxy - AggregatorProxy::propose_aggregator(mockAggregatorAddr2); + AggregatorProxyInternal::propose_aggregator(ref state, mockAggregatorAddr2); // latest_round_data should return old aggregator round data - let round = AggregatorProxy::latest_round_data(); + let round = AggregatorProxyImpl::latest_round_data(@state); assert(round.answer == 10, 'answer should be 10'); // proposed_round_data should return new aggregator round data - let proposed_round = AggregatorProxy::proposed_latest_round_data(); + let proposed_round = AggregatorProxyInternal::proposed_latest_round_data(@state); assert(proposed_round.answer == 12, 'answer should be 12'); // aggregator should still be set to the old aggregator - let aggregator = AggregatorProxy::aggregator(); + let aggregator = AggregatorProxyInternal::aggregator(@state); assert(aggregator == mockAggregatorAddr1, 'aggregator should be old addr'); } #[test] -#[available_gas(2000000)] +#[available_gas(3000000)] fn test_confirm_new_aggregator() { let (owner, mockAggregatorAddr1, mockAggregator1, mockAggregatorAddr2, mockAggregator2) = setup(); + let mut state = STATE(); // init aggregator proxy with mock aggregator 1 - AggregatorProxy::constructor(owner, mockAggregatorAddr1); - AggregatorProxy::add_access(owner); + AggregatorProxy::constructor(ref state, owner, mockAggregatorAddr1); + AccessControllerImpl::add_access(ref state, owner); // insert rounds into mock aggregators mockAggregator1.set_latest_round_data(10, 1, 9, 8); mockAggregator2.set_latest_round_data(12, 2, 10, 11); // propose new mock aggregator to AggregatorProxy - AggregatorProxy::propose_aggregator(mockAggregatorAddr2); + AggregatorProxyInternal::propose_aggregator(ref state, mockAggregatorAddr2); // confirm new mock aggregator - AggregatorProxy::confirm_aggregator(mockAggregatorAddr2); + AggregatorProxyInternal::confirm_aggregator(ref state, mockAggregatorAddr2); // aggregator should be set to the new aggregator - let aggregator = AggregatorProxy::aggregator(); + let aggregator = AggregatorProxyInternal::aggregator(@state); assert(aggregator == mockAggregatorAddr2, 'aggregator should be new addr'); // phase ID should be 2 - let phase_id = AggregatorProxy::phase_id(); + let phase_id = AggregatorProxyInternal::phase_id(@state); assert(phase_id == 2, 'phase_id should be 2'); // latest_round_data should return new aggregator round data - let round = AggregatorProxy::latest_round_data(); + let round = AggregatorProxyImpl::latest_round_data(@state); assert(round.answer == 12, 'answer should be 12'); } diff --git a/contracts/src/tests/test_erc677.cairo b/contracts/src/tests/test_erc677.cairo index 4aefdd8df..3b64e0f65 100644 --- a/contracts/src/tests/test_erc677.cairo +++ b/contracts/src/tests/test_erc677.cairo @@ -15,19 +15,14 @@ use chainlink::token::mock::valid_erc667_receiver::ValidReceiver; use chainlink::token::mock::invalid_erc667_receiver::InvalidReceiver; use chainlink::libraries::token::erc677::ERC677; -#[abi] -trait MockValidReceiver { - fn on_token_transfer(sender: ContractAddress, value: u256, data: Array); - fn supports_interface(interface_id: u32) -> bool; - fn verify() -> ContractAddress; -} - -#[abi] -trait MockInvalidReceiver { - fn supports_interface(interface_id: u32) -> bool; - fn set_supports(value: bool); +#[starknet::interface] +trait MockInvalidReceiver { + fn set_supports(ref self: TContractState, value: bool); } +use chainlink::token::mock::valid_erc667_receiver::{ + MockValidReceiver, MockValidReceiverDispatcher, MockValidReceiverDispatcherTrait +}; // Ignored tests are dependent on upgrading our version of cairo to include this PR https://github.com/starkware-libs/cairo/pull/2912/files @@ -42,7 +37,8 @@ fn setup_valid_receiver() -> (ContractAddress, MockValidReceiverDispatcher) { let calldata = ArrayTrait::new(); let (address, _) = deploy_syscall( ValidReceiver::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false - ).unwrap(); + ) + .unwrap(); let contract = MockValidReceiverDispatcher { contract_address: address }; (address, contract) } @@ -52,7 +48,8 @@ fn setup_invalid_receiver() -> (ContractAddress, MockInvalidReceiverDispatcher) let calldata = ArrayTrait::new(); let (address, _) = deploy_syscall( InvalidReceiver::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false - ).unwrap(); + ) + .unwrap(); let contract = MockInvalidReceiverDispatcher { contract_address: address }; (address, contract) } @@ -60,7 +57,8 @@ fn setup_invalid_receiver() -> (ContractAddress, MockInvalidReceiverDispatcher) fn transfer_and_call(receiver: ContractAddress) { let data = ArrayTrait::::new(); // have to send 0 because ERC20 is not initialized with starting supply when using this library by itself - ERC677::transfer_and_call(receiver, u256 { high: 0, low: 0 }, data); + let mut erc677 = ERC677::unsafe_new_contract_state(); + ERC677::transfer_and_call(ref erc677, receiver, u256 { high: 0, low: 0 }, data); } #[test] diff --git a/contracts/src/tests/test_link_token.cairo b/contracts/src/tests/test_link_token.cairo index 0f934e443..267ebf1dc 100644 --- a/contracts/src/tests/test_link_token.cairo +++ b/contracts/src/tests/test_link_token.cairo @@ -13,11 +13,16 @@ use option::OptionTrait; use core::result::ResultTrait; use chainlink::token::link_token::LinkToken; +use chainlink::token::link_token::LinkToken::{MintableToken, ERC20Impl}; use chainlink::tests::test_ownable::should_implement_ownable; // only tests link token specific functionality // erc20 and erc677 functionality is already tested elsewhere +fn STATE() -> LinkToken::ContractState { + LinkToken::contract_state_for_testing() +} + fn setup() -> ContractAddress { let account: ContractAddress = contract_address_const::<1>(); // Set account as default caller @@ -35,7 +40,8 @@ fn test_ownable() { calldata.append(account.into()); // owner let (linkAddr, _) = deploy_syscall( LinkToken::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false - ).unwrap(); + ) + .unwrap(); should_implement_ownable(linkAddr, account); } @@ -45,37 +51,40 @@ fn test_ownable() { #[should_panic(expected: ('minter is 0', ))] fn test_constructor_zero_address() { let sender = setup(); + let mut state = STATE(); - LinkToken::constructor(Zeroable::zero(), sender); + LinkToken::constructor(ref state, Zeroable::zero(), sender); } #[test] #[available_gas(2000000)] fn test_constructor() { let sender = setup(); - LinkToken::constructor(sender, sender); + let mut state = STATE(); + LinkToken::constructor(ref state, sender, sender); - assert(LinkToken::minter() == sender, 'minter valid'); - assert(LinkToken::name() == 'ChainLink Token', 'name valid'); - assert(LinkToken::symbol() == 'LINK', 'symbol valid'); + assert(LinkToken::minter(@state) == sender, 'minter valid'); + assert(ERC20Impl::name(@state) == 'ChainLink Token', 'name valid'); + assert(ERC20Impl::symbol(@state) == 'LINK', 'symbol valid'); } #[test] #[available_gas(2000000)] fn test_permissioned_mint_from_minter() { let sender = setup(); - LinkToken::constructor(sender, sender); + let mut state = STATE(); + LinkToken::constructor(ref state, sender, sender); let to = contract_address_const::<908>(); let zero: felt252 = 0; - assert(LinkToken::balance_of(sender) == zero.into(), 'zero balance'); - assert(LinkToken::balance_of(to) == zero.into(), 'zero balance'); + assert(ERC20Impl::balance_of(@state, sender) == zero.into(), 'zero balance'); + assert(ERC20Impl::balance_of(@state, to) == zero.into(), 'zero balance'); let amount: felt252 = 3000; - LinkToken::permissionedMint(to, amount.into()); + MintableToken::permissionedMint(ref state, to, amount.into()); - assert(LinkToken::balance_of(sender) == zero.into(), 'zero balance'); - assert(LinkToken::balance_of(to) == amount.into(), 'expect balance'); + assert(ERC20Impl::balance_of(@state, sender) == zero.into(), 'zero balance'); + assert(ERC20Impl::balance_of(@state, to) == amount.into(), 'expect balance'); } #[test] @@ -83,12 +92,13 @@ fn test_permissioned_mint_from_minter() { #[should_panic(expected: ('only minter', ))] fn test_permissioned_mint_from_nonminter() { let sender = setup(); + let mut state = STATE(); let minter = contract_address_const::<111>(); - LinkToken::constructor(minter, sender); + LinkToken::constructor(ref state, minter, sender); let to = contract_address_const::<908>(); let amount: felt252 = 3000; - LinkToken::permissionedMint(to, amount.into()); + MintableToken::permissionedMint(ref state, to, amount.into()); } #[test] @@ -97,25 +107,26 @@ fn test_permissioned_mint_from_nonminter() { fn test_permissioned_burn_from_minter() { let zero = 0; let sender = setup(); - LinkToken::constructor(sender, sender); + let mut state = STATE(); + LinkToken::constructor(ref state, sender, sender); let to = contract_address_const::<908>(); let amount: felt252 = 3000; - LinkToken::permissionedMint(to, amount.into()); - assert(LinkToken::balance_of(to) == amount.into(), 'expect balance'); + MintableToken::permissionedMint(ref state, to, amount.into()); + assert(ERC20Impl::balance_of(@state, to) == amount.into(), 'expect balance'); // burn some let burn_amount: felt252 = 2000; let remaining_amount: felt252 = amount - burn_amount; - LinkToken::permissionedBurn(to, burn_amount.into()); - assert(LinkToken::balance_of(to) == remaining_amount.into(), 'remaining balance'); + MintableToken::permissionedBurn(ref state, to, burn_amount.into()); + assert(ERC20Impl::balance_of(@state, to) == remaining_amount.into(), 'remaining balance'); // burn remaining - LinkToken::permissionedBurn(to, remaining_amount.into()); - assert(LinkToken::balance_of(to) == zero.into(), 'no balance'); + MintableToken::permissionedBurn(ref state, to, remaining_amount.into()); + assert(ERC20Impl::balance_of(@state, to) == zero.into(), 'no balance'); // burn too much - LinkToken::permissionedBurn(to, amount.into()); + MintableToken::permissionedBurn(ref state, to, amount.into()); } @@ -124,12 +135,13 @@ fn test_permissioned_burn_from_minter() { #[should_panic(expected: ('only minter', ))] fn test_permissioned_burn_from_nonminter() { let sender = setup(); + let mut state = STATE(); let minter = contract_address_const::<111>(); - LinkToken::constructor(minter, sender); + LinkToken::constructor(ref state, minter, sender); let to = contract_address_const::<908>(); let amount: felt252 = 3000; - LinkToken::permissionedBurn(to, amount.into()); + MintableToken::permissionedBurn(ref state, to, amount.into()); } #[test] @@ -137,8 +149,9 @@ fn test_permissioned_burn_from_nonminter() { #[should_panic(expected: ('Ownable: caller is not owner', ))] fn test_upgrade_non_owner() { let sender = setup(); - LinkToken::constructor(sender, contract_address_const::<111>()); + let mut state = STATE(); + LinkToken::constructor(ref state, sender, contract_address_const::<111>()); - LinkToken::upgrade(class_hash_const::<123>()); + LinkToken::upgrade(ref state, class_hash_const::<123>()); } diff --git a/contracts/src/tests/test_multisig.cairo b/contracts/src/tests/test_multisig.cairo index d99b67f8f..d8b64c3a3 100644 --- a/contracts/src/tests/test_multisig.cairo +++ b/contracts/src/tests/test_multisig.cairo @@ -12,17 +12,18 @@ use traits::TryInto; use chainlink::multisig::assert_unique_values; use chainlink::multisig::Multisig; +use chainlink::multisig::Multisig::MultisigImpl; -#[contract] +#[starknet::contract] mod MultisigTest { use array::ArrayTrait; - #[external] - fn increment(val1: felt252, val2: felt252) -> Array { - let mut ret = ArrayTrait::new(); - ret.append(val1 + 1); - ret.append(val2 + 1); - ret + #[storage] + struct Storage {} + + #[external(v0)] + fn increment(ref self: ContractState, val1: felt252, val2: felt252) -> Array { + array![val1 + 1, val2 + 1] } } @@ -30,28 +31,25 @@ mod MultisigTest { // TODO: test set_signers with recursive call // TODO: test set_signers_and_thershold with recursive call +fn STATE() -> Multisig::ContractState { + Multisig::contract_state_for_testing() +} + fn sample_calldata() -> Array:: { - let mut calldata = ArrayTrait::new(); - calldata.append(1); - calldata.append(2); - calldata.append(3); - calldata + array![1, 2, 32] } #[test] #[available_gas(2000000)] fn test_assert_unique_values_empty() { - let mut a = ArrayTrait::::new(); + let a = ArrayTrait::::new(); assert_unique_values(@a); } #[test] #[available_gas(2000000)] fn test_assert_unique_values_no_duplicates() { - let mut a = ArrayTrait::new(); - a.append(1); - a.append(2); - a.append(3); + let a = array![1, 2, 3]; assert_unique_values(@a); } @@ -59,55 +57,53 @@ fn test_assert_unique_values_no_duplicates() { #[available_gas(2000000)] #[should_panic] fn test_assert_unique_values_with_duplicate() { - let mut a = ArrayTrait::new(); - a.append(1); - a.append(2); - a.append(3); - a.append(3); + let a = array![1, 2, 3, 3]; assert_unique_values(@a); } #[test] #[available_gas(2000000)] fn test_is_signer_true() { + let mut state = STATE(); let signer = contract_address_const::<1>(); let mut signers = ArrayTrait::new(); signers.append(signer); - Multisig::constructor(:signers, threshold: 1); - assert(Multisig::is_signer(signer), 'should be signer'); + Multisig::constructor(ref state, :signers, threshold: 1); + assert(MultisigImpl::is_signer(@state, signer), 'should be signer'); } #[test] #[available_gas(2000000)] fn test_is_signer_false() { + let mut state = STATE(); let not_signer = contract_address_const::<2>(); let mut signers = ArrayTrait::new(); signers.append(contract_address_const::<1>()); - Multisig::constructor(:signers, threshold: 1); - assert(!Multisig::is_signer(not_signer), 'should be signer'); + Multisig::constructor(ref state, :signers, threshold: 1); + assert(!MultisigImpl::is_signer(@state, not_signer), 'should be signer'); } #[test] #[available_gas(2000000)] fn test_signer_len() { + let mut state = STATE(); let mut signers = ArrayTrait::new(); signers.append(contract_address_const::<1>()); signers.append(contract_address_const::<2>()); - Multisig::constructor(:signers, threshold: 1); - assert(Multisig::get_signers_len() == 2, 'should equal 2 signers'); + Multisig::constructor(ref state, :signers, threshold: 1); + assert(MultisigImpl::get_signers_len(@state) == 2, 'should equal 2 signers'); } #[test] #[available_gas(2000000)] fn test_get_signers() { + let mut state = STATE(); let signer1 = contract_address_const::<1>(); let signer2 = contract_address_const::<2>(); - let mut signers = ArrayTrait::new(); - signers.append(signer1); - signers.append(signer2); + let signers = array![signer1, signer2]; - Multisig::constructor(:signers, threshold: 1); - let returned_signers = Multisig::get_signers(); + Multisig::constructor(ref state, :signers, threshold: 1); + let returned_signers = MultisigImpl::get_signers(@state); assert(returned_signers.len() == 2, 'should match signers length'); assert(*returned_signers.at(0) == signer1, 'should match signer 1'); assert(*returned_signers.at(1) == signer2, 'should match signer 2'); @@ -116,27 +112,30 @@ fn test_get_signers() { #[test] #[available_gas(2000000)] fn test_get_threshold() { + let mut state = STATE(); let mut signers = ArrayTrait::new(); signers.append(contract_address_const::<1>()); signers.append(contract_address_const::<2>()); - Multisig::constructor(:signers, threshold: 1); - assert(Multisig::get_threshold() == 1, 'should equal threshold of 1'); + Multisig::constructor(ref state, :signers, threshold: 1); + assert(MultisigImpl::get_threshold(@state) == 1, 'should equal threshold of 1'); } #[test] #[available_gas(2000000)] fn test_submit_transaction() { + let mut state = STATE(); let signer = contract_address_const::<1>(); - let mut signers = ArrayTrait::new(); - signers.append(signer); - Multisig::constructor(:signers, threshold: 1); + let signers = array![signer]; + Multisig::constructor(ref state, :signers, threshold: 1); set_caller_address(signer); let to = contract_address_const::<42>(); let function_selector = 10; - Multisig::submit_transaction(:to, :function_selector, calldata: sample_calldata()); + MultisigImpl::submit_transaction( + ref state, :to, :function_selector, calldata: sample_calldata() + ); - let (transaction, calldata) = Multisig::get_transaction(0); + let (transaction, calldata) = MultisigImpl::get_transaction(@state, 0); assert(transaction.to == to, 'should match target address'); assert(transaction.function_selector == function_selector, 'should match function selector'); assert(transaction.calldata_len == sample_calldata().len(), 'should match calldata length'); @@ -149,36 +148,43 @@ fn test_submit_transaction() { #[available_gas(2000000)] #[should_panic] fn test_submit_transaction_not_signer() { + let mut state = STATE(); let signer = contract_address_const::<1>(); - let mut signers = ArrayTrait::new(); - signers.append(signer); - Multisig::constructor(:signers, threshold: 1); + let signers = array![signer]; + Multisig::constructor(ref state, :signers, threshold: 1); set_caller_address(contract_address_const::<3>()); - Multisig::submit_transaction( - to: contract_address_const::<42>(), function_selector: 10, calldata: sample_calldata(), + MultisigImpl::submit_transaction( + ref state, + to: contract_address_const::<42>(), + function_selector: 10, + calldata: sample_calldata(), ); } #[test] #[available_gas(2000000)] fn test_confirm_transaction() { + let mut state = STATE(); let signer1 = contract_address_const::<1>(); let signer2 = contract_address_const::<2>(); - let mut signers = ArrayTrait::new(); - signers.append(signer1); - signers.append(signer2); - Multisig::constructor(:signers, threshold: 2); + let signers = array![signer1, signer2]; + Multisig::constructor(ref state, :signers, threshold: 2); set_caller_address(signer1); - Multisig::submit_transaction( - to: contract_address_const::<42>(), function_selector: 10, calldata: sample_calldata(), + MultisigImpl::submit_transaction( + ref state, + to: contract_address_const::<42>(), + function_selector: 10, + calldata: sample_calldata(), ); - Multisig::confirm_transaction(nonce: 0); + MultisigImpl::confirm_transaction(ref state, nonce: 0); - assert(Multisig::is_confirmed(nonce: 0, signer: signer1), 'should be confirmed'); - assert(!Multisig::is_confirmed(nonce: 0, signer: signer2), 'should not be confirmed'); - let (transaction, _) = Multisig::get_transaction(0); + assert(MultisigImpl::is_confirmed(@state, nonce: 0, signer: signer1), 'should be confirmed'); + assert( + !MultisigImpl::is_confirmed(@state, nonce: 0, signer: signer2), 'should not be confirmed' + ); + let (transaction, _) = MultisigImpl::get_transaction(@state, 0); assert(transaction.confirmations == 1, 'should have confirmation'); } @@ -186,40 +192,49 @@ fn test_confirm_transaction() { #[available_gas(2000000)] #[should_panic] fn test_confirm_transaction_not_signer() { + let mut state = STATE(); let signer = contract_address_const::<1>(); let not_signer = contract_address_const::<2>(); - let mut signers = ArrayTrait::new(); - signers.append(signer); - Multisig::constructor(:signers, threshold: 1); + let signers = array![signer]; + Multisig::constructor(ref state, :signers, threshold: 1); set_caller_address(signer); - Multisig::submit_transaction( - to: contract_address_const::<42>(), function_selector: 10, calldata: sample_calldata(), + MultisigImpl::submit_transaction( + ref state, + to: contract_address_const::<42>(), + function_selector: 10, + calldata: sample_calldata(), ); set_caller_address(not_signer); - Multisig::confirm_transaction(nonce: 0); + MultisigImpl::confirm_transaction(ref state, nonce: 0); } #[test] #[available_gas(4000000)] fn test_revoke_confirmation() { + let mut state = STATE(); let signer1 = contract_address_const::<1>(); let signer2 = contract_address_const::<2>(); - let mut signers = ArrayTrait::new(); - signers.append(signer1); - signers.append(signer2); - Multisig::constructor(:signers, threshold: 2); + let signers = array![signer1, signer2]; + Multisig::constructor(ref state, :signers, threshold: 2); set_caller_address(signer1); - Multisig::submit_transaction( - to: contract_address_const::<42>(), function_selector: 10, calldata: sample_calldata(), + MultisigImpl::submit_transaction( + ref state, + to: contract_address_const::<42>(), + function_selector: 10, + calldata: sample_calldata(), ); - Multisig::confirm_transaction(nonce: 0); + MultisigImpl::confirm_transaction(ref state, nonce: 0); - Multisig::revoke_confirmation(nonce: 0); + MultisigImpl::revoke_confirmation(ref state, nonce: 0); - assert(!Multisig::is_confirmed(nonce: 0, signer: signer1), 'should not be confirmed'); - assert(!Multisig::is_confirmed(nonce: 0, signer: signer2), 'should not be confirmed'); - let (transaction, _) = Multisig::get_transaction(0); + assert( + !MultisigImpl::is_confirmed(@state, nonce: 0, signer: signer1), 'should not be confirmed' + ); + assert( + !MultisigImpl::is_confirmed(@state, nonce: 0, signer: signer2), 'should not be confirmed' + ); + let (transaction, _) = MultisigImpl::get_transaction(@state, 0); assert(transaction.confirmations == 0, 'should not have confirmation'); } @@ -227,76 +242,81 @@ fn test_revoke_confirmation() { #[available_gas(4000000)] #[should_panic] fn test_revoke_confirmation_not_signer() { + let mut state = STATE(); let signer = contract_address_const::<1>(); let not_signer = contract_address_const::<2>(); - let mut signers = ArrayTrait::new(); - signers.append(signer); - Multisig::constructor(:signers, threshold: 2); + let mut signers = array![signer]; + Multisig::constructor(ref state, :signers, threshold: 2); set_caller_address(signer); - Multisig::submit_transaction( - to: contract_address_const::<42>(), function_selector: 10, calldata: sample_calldata(), + MultisigImpl::submit_transaction( + ref state, + to: contract_address_const::<42>(), + function_selector: 10, + calldata: sample_calldata(), ); - Multisig::confirm_transaction(nonce: 0); + MultisigImpl::confirm_transaction(ref state, nonce: 0); set_caller_address(not_signer); - Multisig::revoke_confirmation(nonce: 0); + MultisigImpl::revoke_confirmation(ref state, nonce: 0); } #[test] #[available_gas(2000000)] #[should_panic] fn test_execute_confirmation_below_threshold() { + let mut state = STATE(); let signer1 = contract_address_const::<1>(); let signer2 = contract_address_const::<2>(); - let mut signers = ArrayTrait::new(); - signers.append(signer1); - signers.append(signer2); - Multisig::constructor(:signers, threshold: 2); + let signers = array![signer1, signer2]; + Multisig::constructor(ref state, :signers, threshold: 2); set_caller_address(signer1); - Multisig::submit_transaction( - to: contract_address_const::<42>(), function_selector: 10, calldata: sample_calldata(), + MultisigImpl::submit_transaction( + ref state, + to: contract_address_const::<42>(), + function_selector: 10, + calldata: sample_calldata(), ); - Multisig::confirm_transaction(nonce: 0); - Multisig::execute_transaction(nonce: 0); + MultisigImpl::confirm_transaction(ref state, nonce: 0); + MultisigImpl::execute_transaction(ref state, nonce: 0); } #[test] #[available_gas(2000000)] #[should_panic(expected: ('only multisig allowed', ))] fn test_upgrade_not_multisig() { + let mut state = STATE(); let account = contract_address_const::<777>(); set_caller_address(account); - Multisig::upgrade(class_hash_const::<1>()) + MultisigImpl::upgrade(ref state, class_hash_const::<1>()) } #[test] #[available_gas(80000000)] fn test_execute() { + let mut state = STATE(); let signer1 = contract_address_const::<1>(); let signer2 = contract_address_const::<2>(); - let mut signers = ArrayTrait::new(); - signers.append(signer1); - signers.append(signer2); - Multisig::constructor(:signers, threshold: 2); + let signers = array![signer1, signer2]; + Multisig::constructor(ref state, :signers, threshold: 2); let (test_address, _) = deploy_syscall( MultisigTest::TEST_CLASS_HASH.try_into().unwrap(), 0, ArrayTrait::new().span(), false - ).unwrap(); + ) + .unwrap(); set_caller_address(signer1); - let mut increment_calldata = ArrayTrait::new(); - increment_calldata.append(42); - increment_calldata.append(100); - Multisig::submit_transaction( + let increment_calldata = array![42, 100]; + MultisigImpl::submit_transaction( + ref state, to: test_address, // increment() function_selector: 0x7a44dde9fea32737a5cf3f9683b3235138654aa2d189f6fe44af37a61dc60d, calldata: increment_calldata, ); - Multisig::confirm_transaction(nonce: 0); + MultisigImpl::confirm_transaction(ref state, nonce: 0); set_caller_address(signer2); - Multisig::confirm_transaction(nonce: 0); + MultisigImpl::confirm_transaction(ref state, nonce: 0); - let response = Multisig::execute_transaction(nonce: 0); + let response = MultisigImpl::execute_transaction(ref state, nonce: 0); assert(response.len() == 3, 'expected response length 3'); assert(*response.at(0) == 2, 'expected array length 2'); assert(*response.at(1) == 43, 'expected array value 43'); @@ -307,106 +327,110 @@ fn test_execute() { #[available_gas(8000000)] #[should_panic(expected: ('invalid signer', ))] fn test_execute_not_signer() { + let mut state = STATE(); let signer1 = contract_address_const::<1>(); let signer2 = contract_address_const::<2>(); - let mut signers = ArrayTrait::new(); - signers.append(signer1); - signers.append(signer2); - Multisig::constructor(:signers, threshold: 2); + let signers = array![signer1, signer2]; + Multisig::constructor(ref state, :signers, threshold: 2); set_caller_address(signer1); - Multisig::submit_transaction( - to: contract_address_const::<42>(), function_selector: 10, calldata: sample_calldata(), + MultisigImpl::submit_transaction( + ref state, + to: contract_address_const::<42>(), + function_selector: 10, + calldata: sample_calldata(), ); - Multisig::confirm_transaction(nonce: 0); + MultisigImpl::confirm_transaction(ref state, nonce: 0); set_caller_address(signer2); - Multisig::confirm_transaction(nonce: 0); + MultisigImpl::confirm_transaction(ref state, nonce: 0); set_caller_address(contract_address_const::<3>()); - Multisig::execute_transaction(nonce: 0); + MultisigImpl::execute_transaction(ref state, nonce: 0); } #[test] #[available_gas(8000000)] #[should_panic(expected: ('transaction invalid', ))] fn test_execute_after_set_signers() { + let mut state = STATE(); let contract_address = contract_address_const::<100>(); set_contract_address(contract_address); let signer1 = contract_address_const::<1>(); let signer2 = contract_address_const::<2>(); let signer3 = contract_address_const::<3>(); - let mut signers = ArrayTrait::new(); - signers.append(signer1); - signers.append(signer2); - Multisig::constructor(:signers, threshold: 2); + let signers = array![signer1, signer2]; + Multisig::constructor(ref state, :signers, threshold: 2); set_caller_address(signer1); - Multisig::submit_transaction( - to: contract_address_const::<42>(), function_selector: 10, calldata: sample_calldata(), + MultisigImpl::submit_transaction( + ref state, + to: contract_address_const::<42>(), + function_selector: 10, + calldata: sample_calldata(), ); - Multisig::confirm_transaction(nonce: 0); + MultisigImpl::confirm_transaction(ref state, nonce: 0); set_caller_address(signer2); - Multisig::confirm_transaction(nonce: 0); + MultisigImpl::confirm_transaction(ref state, nonce: 0); set_caller_address(contract_address); - let mut new_signers = ArrayTrait::new(); - new_signers.append(signer2); - new_signers.append(signer3); - Multisig::set_signers(new_signers); + let new_signers = array![signer2, signer3]; + MultisigImpl::set_signers(ref state, new_signers); set_caller_address(signer2); - Multisig::execute_transaction(nonce: 0); + MultisigImpl::execute_transaction(ref state, nonce: 0); } #[test] #[available_gas(8000000)] #[should_panic(expected: ('transaction invalid', ))] fn test_execute_after_set_signers_and_threshold() { + let mut state = STATE(); let contract_address = contract_address_const::<100>(); set_contract_address(contract_address); let signer1 = contract_address_const::<1>(); let signer2 = contract_address_const::<2>(); let signer3 = contract_address_const::<3>(); - let mut signers = ArrayTrait::new(); - signers.append(signer1); - signers.append(signer2); - Multisig::constructor(:signers, threshold: 2); + let signers = array![signer1, signer2]; + Multisig::constructor(ref state, :signers, threshold: 2); set_caller_address(signer1); - Multisig::submit_transaction( - to: contract_address_const::<42>(), function_selector: 10, calldata: sample_calldata(), + MultisigImpl::submit_transaction( + ref state, + to: contract_address_const::<42>(), + function_selector: 10, + calldata: sample_calldata(), ); - Multisig::confirm_transaction(nonce: 0); + MultisigImpl::confirm_transaction(ref state, nonce: 0); set_caller_address(signer2); - Multisig::confirm_transaction(nonce: 0); + MultisigImpl::confirm_transaction(ref state, nonce: 0); set_caller_address(contract_address); - let mut new_signers = ArrayTrait::new(); - new_signers.append(signer2); - new_signers.append(signer3); - Multisig::set_signers_and_threshold(new_signers, 1); + let new_signers = array![signer2, signer3]; + MultisigImpl::set_signers_and_threshold(ref state, new_signers, 1); set_caller_address(signer2); - Multisig::execute_transaction(nonce: 0); + MultisigImpl::execute_transaction(ref state, nonce: 0); } #[test] #[available_gas(8000000)] #[should_panic(expected: ('transaction invalid', ))] fn test_execute_after_set_threshold() { + let mut state = STATE(); let contract_address = contract_address_const::<100>(); set_contract_address(contract_address); let signer1 = contract_address_const::<1>(); let signer2 = contract_address_const::<2>(); - let mut signers = ArrayTrait::new(); - signers.append(signer1); - signers.append(signer2); - Multisig::constructor(:signers, threshold: 2); + let signers = array![signer1, signer2]; + Multisig::constructor(ref state, :signers, threshold: 2); set_caller_address(signer1); - Multisig::submit_transaction( - to: contract_address_const::<42>(), function_selector: 10, calldata: sample_calldata(), + MultisigImpl::submit_transaction( + ref state, + to: contract_address_const::<42>(), + function_selector: 10, + calldata: sample_calldata(), ); - Multisig::confirm_transaction(nonce: 0); + MultisigImpl::confirm_transaction(ref state, nonce: 0); set_caller_address(signer2); - Multisig::confirm_transaction(nonce: 0); + MultisigImpl::confirm_transaction(ref state, nonce: 0); set_caller_address(contract_address); - Multisig::set_threshold(1); + MultisigImpl::set_threshold(ref state, 1); set_caller_address(signer1); - Multisig::execute_transaction(nonce: 0); + MultisigImpl::execute_transaction(ref state, nonce: 0); } diff --git a/contracts/src/tests/test_ownable.cairo b/contracts/src/tests/test_ownable.cairo index 537b14a75..63593fda3 100644 --- a/contracts/src/tests/test_ownable.cairo +++ b/contracts/src/tests/test_ownable.cairo @@ -3,7 +3,12 @@ use starknet::ContractAddress; use starknet::testing::set_caller_address; use starknet::testing::set_contract_address; use zeroable::Zeroable; -use chainlink::libraries::ownable::Ownable; +use chainlink::libraries::ownable::{Ownable, IOwnable, IOwnableDispatcher, IOwnableDispatcherTrait}; +use chainlink::libraries::ownable::Ownable::OwnableImpl; + +fn STATE() -> Ownable::ContractState { + Ownable::contract_state_for_testing() +} fn setup() -> (ContractAddress, ContractAddress) { let owner: ContractAddress = contract_address_const::<1>(); @@ -17,8 +22,9 @@ fn setup() -> (ContractAddress, ContractAddress) { fn test_assert_only_owner() { let (owner, _) = setup(); - Ownable::constructor(owner); - Ownable::assert_only_owner(); + let mut state = STATE(); + Ownable::constructor(ref state, owner); + Ownable::assert_only_owner(@state); } #[test] @@ -26,31 +32,34 @@ fn test_assert_only_owner() { #[should_panic] fn test_assert_only_owner_panics_if_not_owner() { let (owner, other_user) = setup(); + let mut state = STATE(); - Ownable::constructor(owner); + Ownable::constructor(ref state, owner); set_caller_address(other_user); - Ownable::assert_only_owner(); + Ownable::assert_only_owner(@state); } #[test] #[available_gas(2000000)] fn test_owner() { let (owner, _) = setup(); + let mut state = STATE(); - Ownable::constructor(owner); + Ownable::constructor(ref state, owner); - assert(owner == Ownable::owner(), 'should equal owner'); + assert(owner == OwnableImpl::owner(@state), 'should equal owner'); } #[test] #[available_gas(2000000)] fn test_transfer_ownership() { let (owner, other_user) = setup(); + let mut state = STATE(); - Ownable::constructor(owner); - Ownable::transfer_ownership(other_user); + Ownable::constructor(ref state, owner); + OwnableImpl::transfer_ownership(ref state, other_user); - assert(other_user == Ownable::proposed_owner(), 'should equal proposed owner'); + assert(other_user == OwnableImpl::proposed_owner(@state), 'should equal proposed owner'); } #[test] @@ -58,9 +67,10 @@ fn test_transfer_ownership() { #[should_panic] fn test_transfer_ownership_panics_if_zero_address() { let (owner, other_user) = setup(); + let mut state = STATE(); - Ownable::constructor(owner); - Ownable::transfer_ownership(Zeroable::zero()); + Ownable::constructor(ref state, owner); + OwnableImpl::transfer_ownership(ref state, Zeroable::zero()); } #[test] @@ -68,23 +78,25 @@ fn test_transfer_ownership_panics_if_zero_address() { #[should_panic] fn test_transfer_ownership_panics_if_not_owner() { let (owner, other_user) = setup(); + let mut state = STATE(); - Ownable::constructor(owner); + Ownable::constructor(ref state, owner); set_caller_address(other_user); - Ownable::transfer_ownership(other_user); + OwnableImpl::transfer_ownership(ref state, other_user); } #[test] #[available_gas(2000000)] fn test_accept_ownership() { let (owner, other_user) = setup(); + let mut state = STATE(); - Ownable::constructor(owner); - Ownable::transfer_ownership(other_user); + Ownable::constructor(ref state, owner); + OwnableImpl::transfer_ownership(ref state, other_user); set_caller_address(other_user); - Ownable::accept_ownership(); + OwnableImpl::accept_ownership(ref state); - assert(Ownable::owner() == other_user, 'failed to accept ownership'); + assert(OwnableImpl::owner(@state) == other_user, 'failed to accept ownership'); } #[test] @@ -92,24 +104,26 @@ fn test_accept_ownership() { #[should_panic] fn test_accept_ownership_panics_if_not_proposed_owner() { let (owner, other_user) = setup(); + let mut state = STATE(); - Ownable::constructor(owner); - Ownable::transfer_ownership(other_user); + Ownable::constructor(ref state, owner); + OwnableImpl::transfer_ownership(ref state, other_user); set_caller_address(contract_address_const::<3>()); - Ownable::accept_ownership(); + OwnableImpl::accept_ownership(ref state); } #[test] #[available_gas(2000000)] fn test_renounce_ownership() { let (owner, _) = setup(); + let mut state = STATE(); set_caller_address(owner); - Ownable::constructor(owner); - Ownable::renounce_ownership(); + Ownable::constructor(ref state, owner); + OwnableImpl::renounce_ownership(ref state); - assert(Ownable::owner().is_zero(), 'owner not 0 after renounce'); + assert(OwnableImpl::owner(@state).is_zero(), 'owner not 0 after renounce'); } #[test] @@ -117,24 +131,16 @@ fn test_renounce_ownership() { #[should_panic] fn test_renounce_ownership_panics_if_not_owner() { let (owner, other_user) = setup(); + let mut state = STATE(); - Ownable::constructor(owner); + Ownable::constructor(ref state, owner); set_caller_address(other_user); - Ownable::renounce_ownership(); + OwnableImpl::renounce_ownership(ref state); } // // General ownable contract tests // -#[abi] -trait IOwnable { - fn owner() -> ContractAddress; - fn proposed_owner() -> ContractAddress; - fn transfer_ownership(new_owner: ContractAddress); - fn accept_ownership(); - fn renounce_ownership(); -} - fn should_implement_ownable(contract_addr: ContractAddress, owner: ContractAddress) { let contract = IOwnableDispatcher { contract_address: contract_addr }; let acc2: ContractAddress = contract_address_const::<2222>(); diff --git a/contracts/src/tests/test_sequencer_uptime_feed.cairo b/contracts/src/tests/test_sequencer_uptime_feed.cairo index c0451eafd..1292e394e 100644 --- a/contracts/src/tests/test_sequencer_uptime_feed.cairo +++ b/contracts/src/tests/test_sequencer_uptime_feed.cairo @@ -15,14 +15,20 @@ use core::result::ResultTrait; use chainlink::emergency::sequencer_uptime_feed::SequencerUptimeFeed; use chainlink::ocr2::aggregator_proxy::AggregatorProxy; +use chainlink::ocr2::aggregator_proxy::AggregatorProxy::AggregatorProxyImpl; use chainlink::tests::test_ownable::should_implement_ownable; use chainlink::tests::test_access_controller::should_implement_access_control; -// NOTE: move to separate interface file once we can directly use the trait -#[abi] -trait ISequencerUptimeFeed { - fn l1_sender() -> EthAddress; - fn set_l1_sender(address: EthAddress); +use chainlink::emergency::sequencer_uptime_feed::{ + ISequencerUptimeFeed, ISequencerUptimeFeedDispatcher, ISequencerUptimeFeedDispatcherTrait +}; + +fn PROXY() -> AggregatorProxy::ContractState { + AggregatorProxy::contract_state_for_testing() +} + +fn STATE() -> SequencerUptimeFeed::ContractState { + SequencerUptimeFeed::contract_state_for_testing() } fn setup() -> (ContractAddress, ContractAddress, ISequencerUptimeFeedDispatcher) { @@ -30,12 +36,13 @@ fn setup() -> (ContractAddress, ContractAddress, ISequencerUptimeFeedDispatcher) set_caller_address(account); // Deploy seqeuencer uptime feed - let mut calldata = ArrayTrait::new(); - calldata.append(0); // initial status - calldata.append(account.into()); // owner + let calldata = array![0, // initial status + account.into() // owner + ]; let (sequencerFeedAddr, _) = deploy_syscall( SequencerUptimeFeed::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false - ).unwrap(); + ) + .unwrap(); let sequencerUptimeFeed = ISequencerUptimeFeedDispatcher { contract_address: sequencerFeedAddr }; @@ -51,7 +58,7 @@ fn test_ownable() { } #[test] -#[available_gas(2000000)] +#[available_gas(3000000)] fn test_access_control() { let (account, sequencerFeedAddr, _) = setup(); should_implement_access_control(sequencerFeedAddr, account); @@ -62,7 +69,7 @@ fn test_access_control() { #[should_panic()] fn test_set_l1_sender_not_owner() { let (_, _, sequencerUptimeFeed) = setup(); - sequencerUptimeFeed.set_l1_sender(contract_address_const::<789>().into().try_into().unwrap()); + sequencerUptimeFeed.set_l1_sender(EthAddress { address: 789 }); } #[test] @@ -70,11 +77,8 @@ fn test_set_l1_sender_not_owner() { fn test_set_l1_sender() { let (owner, _, sequencerUptimeFeed) = setup(); set_contract_address(owner); - sequencerUptimeFeed.set_l1_sender(contract_address_const::<789>().into().try_into().unwrap()); - assert( - sequencerUptimeFeed.l1_sender() == contract_address_const::<789>().into().try_into().unwrap(), - 'l1_sender should be set to 789' - ); + sequencerUptimeFeed.set_l1_sender(EthAddress { address: 789 }); + assert(sequencerUptimeFeed.l1_sender().address == 789, 'l1_sender should be set to 789'); } #[test] @@ -82,8 +86,9 @@ fn test_set_l1_sender() { #[should_panic(expected: ('user does not have read access', ))] fn test_latest_round_data_no_access() { let (owner, sequencerFeedAddr, _) = setup(); - AggregatorProxy::constructor(owner, sequencerFeedAddr); - AggregatorProxy::latest_round_data(); + let mut proxy = PROXY(); + AggregatorProxy::constructor(ref proxy, owner, sequencerFeedAddr); + AggregatorProxyImpl::latest_round_data(@proxy); } #[test] @@ -91,17 +96,18 @@ fn test_latest_round_data_no_access() { #[should_panic(expected: ('user does not have read access', ))] fn test_aggregator_proxy_response() { let (owner, sequencerFeedAddr, _) = setup(); - AggregatorProxy::constructor(owner, sequencerFeedAddr); + let mut proxy = PROXY(); + AggregatorProxy::constructor(ref proxy, owner, sequencerFeedAddr); // latest round data - let latest_round_data = AggregatorProxy::latest_round_data(); + let latest_round_data = AggregatorProxyImpl::latest_round_data(@proxy); assert(latest_round_data.answer == 0, 'latest_round_data should be 0'); // description - let description = AggregatorProxy::description(); + let description = AggregatorProxyImpl::description(@proxy); assert(description == 'L2 Sequencer Uptime Status Feed', 'description does not match'); // decimals - let decimals = AggregatorProxy::decimals(); + let decimals = AggregatorProxyImpl::decimals(@proxy); assert(decimals == 0, 'decimals should be 0'); } diff --git a/contracts/src/token/link_token.cairo b/contracts/src/token/link_token.cairo index c4b1e9b07..eb534871b 100644 --- a/contracts/src/token/link_token.cairo +++ b/contracts/src/token/link_token.cairo @@ -1,14 +1,14 @@ use starknet::ContractAddress; -#[abi] -trait IMintableToken { - #[external] - fn permissionedMint(account: ContractAddress, amount: u256); - #[external] - fn permissionedBurn(account: ContractAddress, amount: u256); +#[starknet::interface] +trait IMintableToken { + #[external(v0)] + fn permissionedMint(ref self: TContractState, account: ContractAddress, amount: u256); + #[external(v0)] + fn permissionedBurn(ref self: TContractState, account: ContractAddress, amount: u256); } -#[contract] +#[starknet::contract] mod LinkToken { use super::IMintableToken; @@ -17,46 +17,56 @@ mod LinkToken { use starknet::ContractAddress; use starknet::class_hash::ClassHash; - use chainlink::libraries::token::erc20::ERC20; + use openzeppelin::token::erc20::ERC20; + use openzeppelin::token::erc20::interface::{IERC20, IERC20Dispatcher, IERC20DispatcherTrait}; use chainlink::libraries::token::erc677::ERC677; - use chainlink::libraries::ownable::Ownable; + use chainlink::libraries::ownable::{Ownable, IOwnable}; use chainlink::libraries::upgradeable::Upgradeable; const NAME: felt252 = 'ChainLink Token'; const SYMBOL: felt252 = 'LINK'; + #[storage] struct Storage { _minter: ContractAddress, } - impl MintableToken of IMintableToken { - fn permissionedMint(account: ContractAddress, amount: u256) { - only_minter(); - ERC20::_mint(account, amount); + // + // IMintableToken (StarkGate) + // + #[external(v0)] + impl MintableToken of IMintableToken { + fn permissionedMint(ref self: ContractState, account: ContractAddress, amount: u256) { + only_minter(@self); + let mut state = ERC20::unsafe_new_contract_state(); + ERC20::InternalImpl::_mint(ref state, account, amount); } - fn permissionedBurn(account: ContractAddress, amount: u256) { - only_minter(); - ERC20::_burn(account, amount); + fn permissionedBurn(ref self: ContractState, account: ContractAddress, amount: u256) { + only_minter(@self); + let mut state = ERC20::unsafe_new_contract_state(); + ERC20::InternalImpl::_burn(ref state, account, amount); } } #[constructor] - fn constructor(minter: ContractAddress, owner: ContractAddress) { - ERC20::initializer(NAME, SYMBOL); + fn constructor(ref self: ContractState, minter: ContractAddress, owner: ContractAddress) { + let mut state = ERC20::unsafe_new_contract_state(); + ERC20::InternalImpl::initializer(ref state, NAME, SYMBOL); assert(!minter.is_zero(), 'minter is 0'); - _minter::write(minter); - Ownable::initializer(owner); + self._minter.write(minter); + let mut ownable = Ownable::unsafe_new_contract_state(); + Ownable::constructor(ref ownable, owner); // Ownable::initializer(owner); } #[view] - fn minter() -> ContractAddress { - _minter::read() + fn minter(self: @ContractState) -> ContractAddress { + self._minter.read() } #[view] - fn type_and_version() -> felt252 { + fn type_and_version(self: @ContractState) -> felt252 { 'LinkToken 1.0.0' } @@ -64,31 +74,21 @@ mod LinkToken { // ERC677 // - #[external] - fn transfer_and_call(to: ContractAddress, value: u256, data: Array) -> bool { - ERC677::transfer_and_call(to, value, data) - } - - // - // IMintableToken (StarkGate) - // - - #[external] - fn permissionedMint(account: ContractAddress, amount: u256) { - MintableToken::permissionedMint(account, amount) - } - - #[external] - fn permissionedBurn(account: ContractAddress, amount: u256) { - MintableToken::permissionedBurn(account, amount) + #[external(v0)] + fn transfer_and_call( + ref self: ContractState, to: ContractAddress, value: u256, data: Array + ) -> bool { + let mut erc677 = ERC677::unsafe_new_contract_state(); + ERC677::transfer_and_call(ref erc677, to, value, data) } // // Upgradeable // - #[external] - fn upgrade(new_impl: ClassHash) { - Ownable::assert_only_owner(); + #[external(v0)] + fn upgrade(ref self: ContractState, new_impl: ClassHash) { + let ownable = Ownable::unsafe_new_contract_state(); + Ownable::assert_only_owner(@ownable); Upgradeable::upgrade(new_impl) } @@ -96,99 +96,110 @@ mod LinkToken { // Ownership // - #[view] - fn owner() -> ContractAddress { - Ownable::owner() - } + #[external(v0)] + impl OwnableImpl of IOwnable { + fn owner(self: @ContractState) -> ContractAddress { + let state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::owner(@state) + } - #[view] - fn proposed_owner() -> ContractAddress { - Ownable::proposed_owner() - } + fn proposed_owner(self: @ContractState) -> ContractAddress { + let state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::proposed_owner(@state) + } - #[external] - fn transfer_ownership(new_owner: ContractAddress) { - Ownable::transfer_ownership(new_owner) - } + fn transfer_ownership(ref self: ContractState, new_owner: ContractAddress) { + let mut state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::transfer_ownership(ref state, new_owner) + } - #[external] - fn accept_ownership() { - Ownable::accept_ownership() - } + fn accept_ownership(ref self: ContractState) { + let mut state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::accept_ownership(ref state) + } - #[external] - fn renounce_ownership() { - Ownable::renounce_ownership() + fn renounce_ownership(ref self: ContractState) { + let mut state = Ownable::unsafe_new_contract_state(); + Ownable::OwnableImpl::renounce_ownership(ref state) + } } - // // ERC20 // - #[view] - fn name() -> felt252 { - ERC20::name() - } - - #[view] - fn symbol() -> felt252 { - ERC20::symbol() - } + #[external(v0)] + impl ERC20Impl of IERC20 { + fn name(self: @ContractState) -> felt252 { + let state = ERC20::unsafe_new_contract_state(); + ERC20::ERC20Impl::name(@state) + } - #[view] - fn decimals() -> u8 { - ERC20::decimals() - } + fn symbol(self: @ContractState) -> felt252 { + let state = ERC20::unsafe_new_contract_state(); + ERC20::ERC20Impl::symbol(@state) + } - #[view] - fn total_supply() -> u256 { - ERC20::total_supply() - } + fn decimals(self: @ContractState) -> u8 { + let state = ERC20::unsafe_new_contract_state(); + ERC20::ERC20Impl::decimals(@state) + } - #[view] - fn balance_of(account: ContractAddress) -> u256 { - ERC20::balance_of(account) - } + fn total_supply(self: @ContractState) -> u256 { + let state = ERC20::unsafe_new_contract_state(); + ERC20::ERC20Impl::total_supply(@state) + } - #[view] - fn allowance(owner: ContractAddress, spender: ContractAddress) -> u256 { - ERC20::allowance(owner, spender) - } + fn balance_of(self: @ContractState, account: ContractAddress) -> u256 { + let state = ERC20::unsafe_new_contract_state(); + ERC20::ERC20Impl::balance_of(@state, account) + } - #[external] - fn transfer(recipient: ContractAddress, amount: u256) -> bool { - ERC20::transfer(recipient, amount) - } + fn allowance( + self: @ContractState, owner: ContractAddress, spender: ContractAddress + ) -> u256 { + let state = ERC20::unsafe_new_contract_state(); + ERC20::ERC20Impl::allowance(@state, owner, spender) + } - #[external] - fn transfer_from(sender: ContractAddress, recipient: ContractAddress, amount: u256) -> bool { - ERC20::transfer_from(sender, recipient, amount) - } + fn transfer(ref self: ContractState, recipient: ContractAddress, amount: u256) -> bool { + let mut state = ERC20::unsafe_new_contract_state(); + ERC20::ERC20Impl::transfer(ref state, recipient, amount) + } - #[external] - fn approve(spender: ContractAddress, amount: u256) -> bool { - ERC20::approve(spender, amount) - } + fn transfer_from( + ref self: ContractState, + sender: ContractAddress, + recipient: ContractAddress, + amount: u256 + ) -> bool { + let mut state = ERC20::unsafe_new_contract_state(); + ERC20::ERC20Impl::transfer_from(ref state, sender, recipient, amount) + } - #[external] - fn increase_allowance(spender: ContractAddress, added_value: u256) -> bool { - ERC20::increase_allowance(spender, added_value) + fn approve(ref self: ContractState, spender: ContractAddress, amount: u256) -> bool { + let mut state = ERC20::unsafe_new_contract_state(); + ERC20::ERC20Impl::approve(ref state, spender, amount) + } } - #[external] - fn decrease_allowance(spender: ContractAddress, subtracted_value: u256) -> bool { - ERC20::decrease_allowance(spender, subtracted_value) - } + // fn increase_allowance(ref self: ContractState, spender: ContractAddress, added_value: u256) -> bool { + // let mut state = ERC20::unsafe_new_contract_state(); + // ERC20::ERC20Impl::increase_allowance(ref state, spender, added_value) + // } + // fn decrease_allowance(ref self: ContractState, spender: ContractAddress, subtracted_value: u256) -> bool { + // let mut state = ERC20::unsafe_new_contract_state(); + // ERC20::ERC20Impl::decrease_allowance(ref state, spender, subtracted_value) + // } // // Internal // - fn only_minter() { + fn only_minter(self: @ContractState) { let caller = starknet::get_caller_address(); - let minter = minter(); + let minter = self._minter.read(); assert(caller == minter, 'only minter'); } } diff --git a/contracts/src/token/mock/invalid_erc667_receiver.cairo b/contracts/src/token/mock/invalid_erc667_receiver.cairo index 49bcb5fcf..6b2ef658b 100644 --- a/contracts/src/token/mock/invalid_erc667_receiver.cairo +++ b/contracts/src/token/mock/invalid_erc667_receiver.cairo @@ -1,25 +1,22 @@ -#[contract] +#[starknet::contract] mod InvalidReceiver { - use starknet::ContractAddress; - use array::ArrayTrait; - - + #[storage] struct Storage { _supports: bool } #[constructor] - fn constructor() {} + fn constructor(ref self: ContractState) {} // toggle whether or not receiver says it supports the interface id - #[external] - fn set_supports(support: bool) { - _supports::write(support); + #[external(v0)] + fn set_supports(ref self: ContractState, support: bool) { + self._supports.write(support); } - #[external] - fn supports_interface(interface_id: u32) -> bool { - _supports::read() + #[external(v0)] + fn supports_interface(self: @ContractState, interface_id: u32) -> bool { + self._supports.read() } } diff --git a/contracts/src/token/mock/valid_erc667_receiver.cairo b/contracts/src/token/mock/valid_erc667_receiver.cairo index fb3eebbf9..fce48fe5c 100644 --- a/contracts/src/token/mock/valid_erc667_receiver.cairo +++ b/contracts/src/token/mock/valid_erc667_receiver.cairo @@ -1,28 +1,40 @@ -#[contract] +use starknet::ContractAddress; +#[starknet::interface] +trait MockValidReceiver { + fn verify(self: @TContractState) -> ContractAddress; +} + +#[starknet::contract] mod ValidReceiver { use starknet::ContractAddress; use array::ArrayTrait; + use chainlink::libraries::token::erc677::IERC677Receiver; - + #[storage] struct Storage { _sender: ContractAddress, } #[constructor] - fn constructor() {} + fn constructor(ref self: ContractState) {} - #[external] - fn on_token_transfer(sender: ContractAddress, value: u256, data: Array) { - _sender::write(sender); - } + #[external(v0)] + impl ERC677Receiver of IERC677Receiver { + fn on_token_transfer( + ref self: ContractState, sender: ContractAddress, value: u256, data: Array + ) { + self._sender.write(sender); + } - #[external] - fn supports_interface(interface_id: u32) -> bool { - true + fn supports_interface(ref self: ContractState, interface_id: u32) -> bool { + true + } } - #[view] - fn verify() -> ContractAddress { - _sender::read() + #[external(v0)] + impl ValidReceiver of super::MockValidReceiver { + fn verify(self: @ContractState) -> ContractAddress { + self._sender.read() + } } } diff --git a/contracts/test/ocr2/aggregator.test.ts b/contracts/test/ocr2/aggregator.test.ts index 31b8b865d..42fc89c95 100644 --- a/contracts/test/ocr2/aggregator.test.ts +++ b/contracts/test/ocr2/aggregator.test.ts @@ -206,17 +206,6 @@ describe('Aggregator', function () { }) } - it("should 'set_billing' successfully", async () => { - await owner.invoke(aggregator, 'set_billing', { - config: { - observation_payment_gjuels: 1, - transmission_payment_gjuels: 5, - gas_base: 1, - gas_per_signature: 1, - }, - }) - }) - it("should emit 'NewTransmission' event on transmit", async () => { const txHash = await transmit(1, 99) const receipt = await starknet.getTransactionReceipt(txHash) @@ -280,67 +269,16 @@ describe('Aggregator', function () { await expectInvokeError(transmit(4, UINT128_MAX), 'median is out of min-max range') }) - it('payee management', async () => { + it('payments and withdrawals', async () => { + // set up payees let payees = oracles.map((oracle) => ({ transmitter: oracle.transmitter.starknetContract.address, payee: oracle.transmitter.starknetContract.address, // reusing transmitter acocunts as payees for simplicity })) - // call set_payees, should succeed because all payees are zero - await owner.invoke(aggregator, 'set_payees', { payees }) - // call set_payees, should succeed because values are unchanged await owner.invoke(aggregator, 'set_payees', { payees }) - let oracle = oracles[0].transmitter - let transmitter = oracle.starknetContract.address - let payee = transmitter - - let proposed_oracle = oracles[1].transmitter - let proposed_transmitter = proposed_oracle.starknetContract.address - let proposed_payee = proposed_transmitter - - // can't transfer to self - try { - await oracle.invoke(aggregator, 'transfer_payeeship', { - transmitter, - proposed: payee, - }) - expect.fail() - } catch (err: any) { - // TODO: expect(err.message).to.contain(""); - } - - // only payee can transfer - try { - await proposed_oracle.invoke(aggregator, 'transfer_payeeship', { - transmitter, - proposed: proposed_payee, - }) - expect.fail() - } catch (err: any) { } - - // successful transfer - await oracle.invoke(aggregator, 'transfer_payeeship', { - transmitter, - proposed: proposed_payee, - }) - - // only proposed payee can accept - try { - await oracle.invoke(aggregator, 'accept_payeeship', { transmitter }) - expect.fail() - } catch (err: any) { } - - // successful accept - await proposed_oracle.invoke(aggregator, 'accept_payeeship', { - transmitter, - }) - }) - - it('payments and withdrawals', async () => { let oracle = oracles[0] - // NOTE: previous test changed oracle0's payee to oracle1 - let payee = oracles[1].transmitter - aggregator.call + let payee = oracle.transmitter let { response: owed } = await aggregator.call('owed_payment', { transmitter: oracle.transmitter.starknetContract.address, }) diff --git a/contracts/test/ocr2/aggregator_proxy.test.ts b/contracts/test/ocr2/aggregator_proxy.test.ts deleted file mode 100644 index e8421c0b8..000000000 --- a/contracts/test/ocr2/aggregator_proxy.test.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { assert } from 'chai' -import { starknet } from 'hardhat' -import { num } from 'starknet' -import { Account, StarknetContract, StarknetContractFactory } from 'hardhat/types/runtime' -import { TIMEOUT } from '../constants' -import { account, expectSuccessOrDeclared } from '@chainlink/starknet' - -describe('AggregatorProxy', function () { - this.timeout(TIMEOUT) - const opts = account.makeFunderOptsFromEnv() - const funder = new account.Funder(opts) - let aggregatorContractFactory: StarknetContractFactory - let proxyContractFactory: StarknetContractFactory - - let owner: Account - let aggregator: StarknetContract - let proxy: StarknetContract - - before(async function () { - aggregatorContractFactory = await starknet.getContractFactory('mock_aggregator') - proxyContractFactory = await starknet.getContractFactory('aggregator_proxy') - - owner = await starknet.OpenZeppelinAccount.createAccount() - - await funder.fund([{ account: owner.address, amount: 1e21 }]) - await owner.deployAccount() - - await expectSuccessOrDeclared(owner.declare(aggregatorContractFactory, { maxFee: 1e20 })) - aggregator = await owner.deploy(aggregatorContractFactory, { decimals: 8 }) - - await expectSuccessOrDeclared(owner.declare(proxyContractFactory, { maxFee: 1e20 })) - proxy = await owner.deploy(proxyContractFactory, { - owner: owner.address, - address: aggregator.address, - }) - - console.log(proxy.address) - }) - - describe('proxy behaviour', function () { - it('works', async () => { - // insert round into the mock - await owner.invoke(aggregator, 'set_latest_round_data', { - answer: 10, - block_num: 1, - observation_timestamp: 9, - transmission_timestamp: 8, - }) - - // query latest round - let { response: round } = await proxy.call('latest_round_data') - // TODO: split_felt the round_id and check phase=1 round=1 - assert.equal(round.answer, '10') - assert.equal(round.block_num, '1') - assert.equal(round.started_at, '9') - assert.equal(round.updated_at, '8') - - // insert a second ocr2 aggregator - let new_aggregator = await owner.deploy(aggregatorContractFactory, { decimals: 8 }) - - // insert round into the mock - await owner.invoke(new_aggregator, 'set_latest_round_data', { - answer: 12, - block_num: 2, - observation_timestamp: 10, - transmission_timestamp: 11, - }) - - // propose it to the proxy - await owner.invoke(proxy, 'propose_aggregator', { - address: new_aggregator.address, - }) - - // query latest round, it should still point to the old aggregator - round = (await proxy.call('latest_round_data')).response - assert.equal(round.answer, '10') - - // but the proposed round should be newer - round = (await proxy.call('proposed_latest_round_data')).response - assert.equal(round.answer, '12') - - // confirm the new aggregator - await owner.invoke(proxy, 'confirm_aggregator', { - address: new_aggregator.address, - }) - - const { response: address } = await proxy.call('aggregator', {}) - assert.equal(address, num.toBigInt(new_aggregator.address)) - - const { response: phaseId } = await proxy.call('phase_id', {}) - assert.equal(phaseId, 2n) - - // query latest round, it should now point to the new aggregator - round = (await proxy.call('latest_round_data')).response - assert.equal(round.answer, '12') - }) - }) -}) diff --git a/docs/integration-tests/README.md b/docs/integration-tests/README.md index 132d4ee22..874a88346 100644 --- a/docs/integration-tests/README.md +++ b/docs/integration-tests/README.md @@ -122,6 +122,15 @@ ListenAddresses = ['0.0.0.0:6690'] NODE_URL= ACCOUNT= PRIVATE_KEY= +CHAINLINK_ENV_USER=John; +CHAINLINK_IMAGE={AWS_OIDC}.dkr.ecr.{AWS_REGION}.amazonaws.com/chainlink; +CHAINLINK_VERSION=develop; +INTERNAL_DOCKER_REPO={AWS_OIDC}.dkr.ecr.{AWS_REGION}.amazonaws.com; # required for mock adapter +L2_RPC_URL=https://alpha4.starknet.io; # testnet only +NODE_COUNT=5; +TEST_DURATION=70h; # for soak +TEST_USE_ENV_VAR_CONFIG=true; # for soak +TTL=72h # for soak ``` 1. Deploy link @@ -218,7 +227,7 @@ yarn gauntlet ocr2:set_billing --observationPaymentGjuels= --transmission "alphaAcceptPpb": 0, "deltaCNanoseconds": 1000000000 }, - "maxDurationQueryNanoseconds": 0, + "maxDurationQueryNanoseconds": 2000000000, "maxDurationObservationNanoseconds": 1000000000, "maxDurationReportNanoseconds": 2000000000, "maxDurationShouldAcceptFinalizedReportNanoseconds": 2000000000, diff --git a/integration-tests/common/common.go b/integration-tests/common/common.go index f460c5a7a..d5ee17976 100644 --- a/integration-tests/common/common.go +++ b/integration-tests/common/common.go @@ -11,14 +11,14 @@ import ( "github.com/lib/pq" "github.com/rs/zerolog/log" uuid "github.com/satori/go.uuid" - "github.com/smartcontractkit/caigo/gateway" "gopkg.in/guregu/null.v4" + "github.com/smartcontractkit/caigo/gateway" + "github.com/smartcontractkit/chainlink-env/environment" "github.com/smartcontractkit/chainlink-env/pkg/alias" "github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver" - mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg" + "github.com/smartcontractkit/chainlink-env/pkg/helm/mock-adapter" "github.com/smartcontractkit/chainlink-starknet/ops/devnet" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/v2/core/services/job" @@ -154,9 +154,9 @@ func (c *Common) CreateJobsForContract(cc *ChainlinkClient, observationSource st // Define node[0] as bootstrap node cc.bootstrapPeers = []client.P2PData{ { - RemoteIP: cc.ChainlinkNodes[0].RemoteIP(), - RemotePort: c.P2PPort, - PeerID: cc.NKeys[0].PeerID, + InternalIP: cc.ChainlinkNodes[0].InternalIP(), + InternalPort: c.P2PPort, + PeerID: cc.NKeys[0].PeerID, }, } @@ -236,7 +236,7 @@ func (c *Common) CreateJobsForContract(cc *ChainlinkClient, observationSource st func (c *Common) Default(t *testing.T) { c.K8Config = &environment.Config{NamespacePrefix: "chainlink-ocr-starknet", TTL: c.TTL, Test: t} - starknetUrl := fmt.Sprintf("http://%s:%d", serviceKeyL2, 5000) + starknetUrl := fmt.Sprintf("http://%s:%d/rpc", serviceKeyL2, 5000) if c.Testnet { starknetUrl = c.L2RPCUrl } @@ -267,7 +267,6 @@ ListenAddresses = ['0.0.0.0:6690'] } c.Env = environment.New(c.K8Config). AddHelm(devnet.New(nil)). - AddHelm(mockservercfg.New(nil)). - AddHelm(mockserver.New(nil)). + AddHelm(mock_adapter.New(nil)). AddHelm(chainlink.New(0, c.ClConfig)) } diff --git a/integration-tests/common/test_common.go b/integration-tests/common/test_common.go index fc1f3c2df..f8b0a8863 100644 --- a/integration-tests/common/test_common.go +++ b/integration-tests/common/test_common.go @@ -23,7 +23,6 @@ import ( "github.com/smartcontractkit/chainlink-starknet/ops" "github.com/smartcontractkit/chainlink-starknet/ops/devnet" "github.com/smartcontractkit/chainlink-starknet/ops/gauntlet" - ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink-starknet/integration-tests/utils" @@ -35,7 +34,6 @@ var ( defaultWalletAddress string // derived in init() rpcRequestTimeout = time.Second * 300 dumpPath = "/dumps/dump.pkl" - mockServerValue = 900000 ) func init() { @@ -79,7 +77,6 @@ type Test struct { Starknet *starknet.Client OCR2Client *ocr2.Client Sg *gauntlet.StarknetGauntlet - mockServer *ctfClient.MockserverClient L1RPCUrl string Common *Common AccountAddresses []string @@ -116,7 +113,12 @@ func (testState *Test) DeployCluster() { var err error testState.Cc.NKeys, testState.Cc.ChainlinkNodes, err = testState.Common.CreateKeys(testState.Common.Env) require.NoError(testState.T, err, "Creating chains and keys should not fail") - testState.Starknet, err = starknet.NewClient(testState.Common.ChainId, testState.Common.L2RPCUrl, lggr, &rpcRequestTimeout) + baseURL := testState.Common.L2RPCUrl + if !testState.Common.Testnet { // devnet! + // chainlink starknet client needs the RPC API url which is at /rpc on devnet + baseURL += "/rpc" + } + testState.Starknet, err = starknet.NewClient(testState.Common.ChainId, baseURL, lggr, &rpcRequestTimeout) require.NoError(testState.T, err, "Creating starknet client should not fail") testState.OCR2Client, err = ocr2.NewClient(testState.Starknet, lggr) require.NoError(testState.T, err, "Creating ocr2 client should not fail") @@ -136,8 +138,6 @@ func (testState *Test) DeployEnv() { if testState.Common.Env.WillUseRemoteRunner() { return // short circuit here if using a remote runner } - testState.mockServer, err = ctfClient.ConnectMockServer(testState.Common.Env) - require.NoError(testState.T, err, "Creating mockserver clients shouldn't fail") } // SetupClients Sets up the starknet client @@ -180,14 +180,12 @@ func (testState *Test) LoadOCR2Config() (*ops.OCR2Config, error) { return &payload, nil } -func (testState *Test) SetUpNodes(mockServerVal int) { +func (testState *Test) SetUpNodes() { testState.SetBridgeTypeAttrs(&client.BridgeTypeAttributes{ Name: "bridge-mockserver", - URL: testState.GetMockServerURL(), + URL: fmt.Sprintf("%s/%s", testState.Common.Env.URLs["qa_mock_adapter_internal"][0], "five"), }) - err := testState.SetMockServerValue("", mockServerVal) - require.NoError(testState.T, err, "Setting mock server value should not fail") - err = testState.Common.CreateJobsForContract(testState.GetChainlinkClient(), testState.ObservationSource, testState.JuelsPerFeeCoinSource, testState.OCRAddr, testState.AccountAddresses) + err := testState.Common.CreateJobsForContract(testState.GetChainlinkClient(), testState.ObservationSource, testState.JuelsPerFeeCoinSource, testState.OCRAddr, testState.AccountAddresses) require.NoError(testState.T, err, "Creating jobs should not fail") } @@ -230,14 +228,6 @@ func (testState *Test) SetBridgeTypeAttrs(attr *client.BridgeTypeAttributes) { testState.Cc.bTypeAttr = attr } -func (testState *Test) GetMockServerURL() string { - return testState.mockServer.Config.ClusterURL -} - -func (testState *Test) SetMockServerValue(path string, val int) error { - return testState.mockServer.SetValuePath(path, val) -} - // ConfigureL1Messaging Sets the L1 messaging contract location and RPC url on L2 func (testState *Test) ConfigureL1Messaging() { err := testState.Devnet.LoadL1MessagingContract(testState.L1RPCUrl) @@ -272,13 +262,13 @@ func (testState *Test) ValidateRounds(rounds int, isSoak bool) error { // validate balance in aggregator resLINK, errLINK := testState.Starknet.CallContract(ctx, starknet.CallOps{ - ContractAddress: caigotypes.HexToHash(testState.LinkTokenAddr), + ContractAddress: caigotypes.StrToFelt(testState.LinkTokenAddr), Selector: "balance_of", - Calldata: []string{caigotypes.HexToBN(testState.OCRAddr).String()}, + Calldata: []string{testState.OCRAddr}, }) require.NoError(testState.T, errLINK, "Reader balance from LINK contract should not fail") resAgg, errAgg := testState.Starknet.CallContract(ctx, starknet.CallOps{ - ContractAddress: caigotypes.HexToHash(testState.OCRAddr), + ContractAddress: caigotypes.StrToFelt(testState.OCRAddr), Selector: "link_available_for_payment", }) require.NoError(testState.T, errAgg, "Reader balance from LINK contract should not fail") @@ -294,7 +284,7 @@ func (testState *Test) ValidateRounds(rounds int, isSoak bool) error { for start := time.Now(); time.Since(start) < testState.Common.TestDuration; { l.Info().Msg(fmt.Sprintf("Elapsed time: %s, Round wait: %s ", time.Since(start), testState.Common.TestDuration)) - res, err := testState.OCR2Client.LatestTransmissionDetails(ctx, caigotypes.HexToHash(testState.OCRAddr)) + res, err := testState.OCR2Client.LatestTransmissionDetails(ctx, caigotypes.StrToFelt(testState.OCRAddr)) require.NoError(testState.T, err, "Failed to get latest transmission details") // end condition: enough rounds have occurred if !isSoak && increasing >= rounds && positive { @@ -307,11 +297,6 @@ func (testState *Test) ValidateRounds(rounds int, isSoak bool) error { break } - l.Info().Msg(fmt.Sprintf("Setting adapter value to %d", mockServerValue)) - err = testState.SetMockServerValue("", mockServerValue) - if err != nil { - l.Error().Msg(fmt.Sprintf("Setting mock server value error: %+v", err)) - } // try to fetch rounds time.Sleep(5 * time.Second) @@ -372,16 +357,18 @@ func (testState *Test) ValidateRounds(rounds int, isSoak bool) error { // Test proxy reading // TODO: would be good to test proxy switching underlying feeds roundDataRaw, err := testState.Starknet.CallContract(ctx, starknet.CallOps{ - ContractAddress: caigotypes.HexToHash(testState.ProxyAddr), + ContractAddress: caigotypes.StrToFelt(testState.ProxyAddr), Selector: "latest_round_data", }) if !isSoak { require.NoError(testState.T, err, "Reading round data from proxy should not fail") assert.Equal(testState.T, len(roundDataRaw), 5, "Round data from proxy should match expected size") } - value := starknet.HexToSignedBig(roundDataRaw[1]).Int64() + valueBig, err := starknet.HexToUnsignedBig(roundDataRaw[1]) + require.NoError(testState.T, err) + value := valueBig.Int64() if value < 0 { - assert.Equal(testState.T, value, int64(mockServerValue), "Reading from proxy should return correct value") + assert.Equal(testState.T, value, int64(5), "Reading from proxy should return correct value") } return nil diff --git a/integration-tests/go.mod b/integration-tests/go.mod index a6f6dff19..2290db7ce 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -5,14 +5,19 @@ go 1.20 require ( github.com/rs/zerolog v1.29.1 github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b - github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e - github.com/smartcontractkit/chainlink-env v0.3.29 - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230531014621-9c303da4c086 + github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 + github.com/smartcontractkit/chainlink-env v0.36.1-0.20230802063028-a432269a7384 + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230801204930-f46c3ccc7815 github.com/smartcontractkit/chainlink-starknet/ops v0.0.0-20230329050701-40e3b18bb026 - github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230530233948-90c8af98011e - github.com/smartcontractkit/chainlink-testing-framework v1.11.5 - github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20230420131147-ce3c53a39d07 - github.com/smartcontractkit/chainlink/v2 v2.2.0-mercury-20230527.0.20230531010141-105ba3488387 + github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230727062727-a4de5195c8f9 + github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20230713025544-29b418df4ded + github.com/smartcontractkit/chainlink/v2 v2.2.1-0.20230713025544-29b418df4ded +) + +require ( + github.com/smartcontractkit/chainlink-testing-framework v1.14.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect ) require ( @@ -25,7 +30,6 @@ require ( github.com/DataDog/zstd v1.5.2 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect - github.com/NethermindEth/juno v0.0.0-20220630151419-cbd368b222ac // indirect github.com/VictoriaMetrics/fastcache v1.10.0 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/armon/go-metrics v0.4.1 // indirect @@ -39,7 +43,7 @@ require ( github.com/blendle/zapdriver v1.3.1 // indirect github.com/btcsuite/btcd v0.23.4 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect - github.com/bytedance/sonic v1.8.6 // indirect + github.com/bytedance/sonic v1.9.1 // indirect github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.7.5 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect @@ -60,8 +64,8 @@ require ( github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect - github.com/deckarep/golang-set/v2 v2.1.0 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/deckarep/golang-set/v2 v2.3.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 // indirect github.com/dgraph-io/badger/v2 v2.2007.4 // indirect github.com/dgraph-io/ristretto v0.1.0 // indirect @@ -80,6 +84,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fvbommel/sortorder v1.0.2 // indirect github.com/fxamacker/cbor/v2 v2.4.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gagliardetto/binary v0.7.1 // indirect github.com/gagliardetto/solana-go v1.4.1-0.20220428092759-5250b4abbb27 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect @@ -87,26 +92,27 @@ require ( github.com/getsentry/sentry-go v0.19.0 // indirect github.com/gin-contrib/sessions v0.0.5 // indirect github.com/gin-contrib/sse v0.1.0 // indirect - github.com/gin-gonic/gin v1.9.0 // indirect + github.com/gin-gonic/gin v1.9.1 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect - github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.3 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.12.0 // indirect + github.com/go-playground/validator/v10 v10.14.0 // indirect github.com/go-resty/resty/v2 v2.7.0 // indirect github.com/go-stack/stack v1.8.1 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.3 // indirect - github.com/golang/glog v1.0.0 // indirect + github.com/golang/glog v1.1.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect @@ -116,7 +122,7 @@ require ( github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20230228050547-1710fef4ab10 // indirect + github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gorilla/context v1.1.1 // indirect @@ -124,6 +130,8 @@ require ( github.com/gorilla/sessions v1.2.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect @@ -132,16 +140,16 @@ require ( github.com/hashicorp/go-hclog v1.4.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-plugin v1.4.9 // indirect + github.com/hashicorp/go-plugin v1.4.10 // indirect github.com/hashicorp/golang-lru v0.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce // indirect github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect - github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect + github.com/holiman/uint256 v1.2.2 // indirect github.com/huin/goupnp v1.0.3 // indirect github.com/imdario/mergo v0.3.15 // indirect - github.com/inconshreveable/mousetrap v1.0.1 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/go-cid v0.0.7 // indirect github.com/ipfs/go-datastore v0.4.5 // indirect github.com/ipfs/go-ipfs-util v0.0.2 // indirect @@ -171,7 +179,7 @@ require ( github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a // indirect - github.com/leodido/go-urn v1.2.2 // indirect + github.com/leodido/go-urn v1.2.4 // indirect github.com/lib/pq v1.10.9 github.com/libp2p/go-addr-util v0.0.2 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect @@ -213,16 +221,15 @@ require ( github.com/libp2p/go-yamux/v2 v2.0.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/logrusorgru/aurora v2.0.3+incompatible // indirect - github.com/magiconair/properties v1.8.6 // indirect + github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.18 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect github.com/minio/sha256-simd v0.1.1 // indirect - github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -249,16 +256,16 @@ require ( github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pelletier/go-toml/v2 v2.0.7 // indirect + github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect - github.com/prometheus/client_golang v1.15.1 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.42.0 // indirect - github.com/prometheus/procfs v0.9.0 // indirect + github.com/prometheus/client_golang v1.16.0 // indirect + github.com/prometheus/client_model v0.4.0 // indirect + github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/procfs v0.11.0 // indirect github.com/pyroscope-io/client v0.7.1 // indirect github.com/pyroscope-io/godeltaprof v0.1.0 // indirect github.com/rivo/uniseg v0.4.4 // indirect @@ -270,24 +277,24 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.22.12 // indirect github.com/shopspring/decimal v1.3.1 // indirect - github.com/sirupsen/logrus v1.9.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect github.com/slack-go/slack v0.12.2 // indirect - github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3 // indirect - github.com/smartcontractkit/ocr2keepers v0.6.15 // indirect - github.com/smartcontractkit/ocr2vrf v0.0.0-20230510102715-c58be582bf19 // indirect + github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1 // indirect + github.com/smartcontractkit/ocr2keepers v0.7.0 // indirect + github.com/smartcontractkit/ocr2vrf v0.0.0-20230616201444-d8b4222aff3c // indirect github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb // indirect github.com/smartcontractkit/wsrpc v0.7.2 // indirect github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect - github.com/spf13/afero v1.9.2 // indirect + github.com/spf13/afero v1.9.3 // indirect github.com/spf13/cast v1.5.1 // indirect - github.com/spf13/cobra v1.6.0 // indirect + github.com/spf13/cobra v1.6.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.14.0 // indirect + github.com/spf13/viper v1.15.0 // indirect github.com/status-im/keycard-go v0.2.0 // indirect - github.com/stretchr/testify v1.8.3 - github.com/subosito/gotenv v1.4.1 // indirect + github.com/stretchr/testify v1.8.4 + github.com/subosito/gotenv v1.4.2 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect github.com/tendermint/btcd v0.1.1 // indirect github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 // indirect @@ -300,7 +307,7 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/tklauser/go-sysconf v0.3.11 // indirect - github.com/tklauser/numcpus v0.6.0 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/ugorji/go/codec v1.2.11 // indirect @@ -312,35 +319,40 @@ require ( github.com/x448/float16 v0.8.4 // indirect github.com/xlab/treeprint v1.1.0 // indirect github.com/yuin/goldmark v1.4.13 // indirect - github.com/yusufpapurcu/wmi v1.2.2 // indirect + github.com/yusufpapurcu/wmi v1.2.3 // indirect github.com/zondax/hid v0.9.0 // indirect go.dedis.ch/fixbuf v1.0.3 // indirect - go.dedis.ch/kyber/v3 v3.0.14 // indirect + go.dedis.ch/kyber/v3 v3.1.0 // indirect go.etcd.io/bbolt v1.3.6 // indirect go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 // indirect + go.opentelemetry.io/otel v1.16.0 // indirect + go.opentelemetry.io/otel/metric v1.16.0 // indirect + go.opentelemetry.io/otel/sdk v1.16.0 // indirect + go.opentelemetry.io/otel/trace v1.16.0 // indirect go.starlark.net v0.0.0-20220817180228-f738f5508c12 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 - golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.9.0 // indirect - golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect + golang.org/x/arch v0.4.0 // indirect + golang.org/x/crypto v0.11.0 // indirect + golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect - golang.org/x/mod v0.10.0 // indirect - golang.org/x/net v0.10.0 // indirect - golang.org/x/oauth2 v0.6.0 // indirect - golang.org/x/sync v0.2.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/term v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect + golang.org/x/mod v0.12.0 // indirect + golang.org/x/net v0.12.0 // indirect + golang.org/x/oauth2 v0.10.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.9.1 // indirect + golang.org/x/tools v0.11.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect - gonum.org/v1/gonum v0.12.0 // indirect + gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect - google.golang.org/grpc v1.53.0 // indirect - google.golang.org/protobuf v1.30.0 // indirect + google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc // indirect + google.golang.org/grpc v1.55.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect gopkg.in/guregu/null.v4 v4.0.0 gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect @@ -348,15 +360,15 @@ require ( gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.25.4 // indirect + k8s.io/api v0.25.11 // indirect k8s.io/apiextensions-apiserver v0.25.3 // indirect - k8s.io/apimachinery v0.25.4 // indirect - k8s.io/cli-runtime v0.25.4 // indirect - k8s.io/client-go v0.25.4 // indirect - k8s.io/component-base v0.25.4 // indirect + k8s.io/apimachinery v0.25.11 // indirect + k8s.io/cli-runtime v0.25.11 // indirect + k8s.io/client-go v0.25.11 // indirect + k8s.io/component-base v0.25.11 // indirect k8s.io/klog/v2 v2.80.1 // indirect k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect - k8s.io/kubectl v0.25.4 // indirect + k8s.io/kubectl v0.25.11 // indirect k8s.io/utils v0.0.0-20221107191617-1a15be271d1d // indirect sigs.k8s.io/controller-runtime v0.13.0 // indirect sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect @@ -373,6 +385,9 @@ replace ( github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 + // until merged upstream: https://github.com/hashicorp/go-plugin/pull/257 + github.com/hashicorp/go-plugin => github.com/jmank88/go-plugin v0.0.0-20230604120638-7bb12ec27e75 + github.com/prometheus/client_golang => github.com/prometheus/client_golang v1.14.0 github.com/prometheus/common => github.com/prometheus/common v0.10.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index f54c612e2..63d68ec68 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -18,12 +18,15 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= @@ -78,8 +81,6 @@ github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0 github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/NethermindEth/juno v0.0.0-20220630151419-cbd368b222ac h1:TQ2m26VW06Df1P82Ed/jZhBtf13pReWyl2XQ8hy+J08= -github.com/NethermindEth/juno v0.0.0-20220630151419-cbd368b222ac/go.mod h1:FTk2+xybtQe5X+oNFx+a0n5EeZMD9Nc+LCH4fxFwrEE= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.6 h1:U68crOE3y3MPttCMQGywZOLrTeF5HHJ3/vDBCJn9/bA= @@ -146,8 +147,8 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bxcodec/faker v2.0.1+incompatible h1:P0KUpUw5w6WJXwrPfv35oc91i4d8nf40Nwln+M/+faA= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.8.6 h1:aUgO9S8gvdN6SyW2EhIpAw5E4ChworywIEndZCkCVXk= -github.com/bytedance/sonic v1.8.6/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= +github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.7.5 h1:rvc39Ol6z3MvaBzXkxFC6Nfsnixq/dRypushKDd7Nc0= github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.7.5/go.mod h1:R/pdNYDYFQk+tuuOo7QES1kkv6OLmp5ze2XBZQIVffM= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= @@ -241,11 +242,11 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= -github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= -github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +github.com/deckarep/golang-set/v2 v2.3.0 h1:qs18EKUfHm2X9fA50Mr/M5hccg2tNnVqsiBImnyDs0g= +github.com/deckarep/golang-set/v2 v2.3.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/dfuse-io/logging v0.0.0-20201110202154-26697de88c79/go.mod h1:V+ED4kT/t/lKtH99JQmKIb0v9WL3VaYkJ36CfHlVECI= github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 h1:CuJS05R9jmNlUK8GOxrEELPbfXm0EuGh/30LjkjN5vo= @@ -324,6 +325,8 @@ github.com/fvbommel/sortorder v1.0.2 h1:mV4o8B2hKboCdkJm+a7uX/SIpZob4JzUpc5GGnM4 github.com/fvbommel/sortorder v1.0.2/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88= github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= +github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= +github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gagliardetto/binary v0.6.1/go.mod h1:aOfYkc20U0deHaHn/LVZXiqlkDbFAX0FpTlDhsXa0S0= github.com/gagliardetto/binary v0.7.1 h1:6ggDQ26vR+4xEvl/S13NcdLK3MUCi4oSy73pS9aI1cI= github.com/gagliardetto/binary v0.7.1/go.mod h1:aOfYkc20U0deHaHn/LVZXiqlkDbFAX0FpTlDhsXa0S0= @@ -344,13 +347,13 @@ github.com/gin-contrib/cors v1.4.0 h1:oJ6gwtUl3lqV0WEIwM/LxPF1QZ5qe2lGWdY2+bz7y0 github.com/gin-contrib/expvar v0.0.1 h1:IuU5ArEgihz50vG8Onrwz22kJr7Mcvgv9xSSpfU5g+w= github.com/gin-contrib/sessions v0.0.5 h1:CATtfHmLMQrMNpJRgzjWXD7worTh7g7ritsQfmF+0jE= github.com/gin-contrib/sessions v0.0.5/go.mod h1:vYAuaUPqie3WUSsft6HUlCjlwwoJQs97miaG2+7neKY= -github.com/gin-contrib/size v0.0.0-20220707104239-f5a650759656 h1:IxCENnXjmppSWzMedenibLt8tvKg4b7kQ7lTGjGjsgw= +github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 h1:Z9J0PVIt1PuibOShaOw1jH8hUYz+Ak8NLsR/GI0Hv5I= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= -github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8= -github.com/gin-gonic/gin v1.9.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k= +github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= +github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= @@ -369,8 +372,11 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= @@ -386,8 +392,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.12.0 h1:E4gtWgxWxp8YSxExrQFv5BpCahla0PVF2oTTEYaWQGI= -github.com/go-playground/validator/v10 v10.12.0/go.mod h1:hCAPuzYvKdP33pxWa+2+6AIKXEKqjIUyqsNCtbsSJrA= +github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= +github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= @@ -411,7 +417,7 @@ github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gofrs/uuid v4.3.0+incompatible h1:CaSVZxm5B+7o45rtab4jC2G37WGYX1zQfuU2i6DSvnc= +github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI= github.com/gogo/gateway v1.1.0 h1:u0SuhL9+Il+UbjM9VIE3ntfRujKbvVpFvNB4HbjeVQ0= github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= @@ -420,8 +426,8 @@ github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keL github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -509,8 +515,8 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230228050547-1710fef4ab10 h1:CqYfpuYIjnlNxM3msdyPRKabhXZWbKjf3Q8BWROFBso= -github.com/google/pprof v0.0.0-20230228050547-1710fef4ab10/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= +github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= +github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= @@ -542,6 +548,10 @@ github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJr github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0 h1:mdLirNAJBxnGgyB6pjZLcs6ue/6eZGBui6gXspfq4ks= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0/go.mod h1:kdXbOySqcQeTxiqglW7aahTmWZy3Pgi6SYL36yvKeyA= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 h1:o95KDiV/b1xdkumY5YbLR0/n2+wBxUpgf3HgfKgTyLI= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3/go.mod h1:hTxjzRcX49ogbTGVJ1sM5mz5s+SSgiGIyL3jjPxl32E= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= @@ -573,8 +583,6 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-plugin v1.4.9 h1:ESiK220/qE0aGxWdzKIvRH69iLiuN/PjoLTm69RoWtU= -github.com/hashicorp/go-plugin v1.4.9/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= @@ -602,8 +610,8 @@ github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 h1:aSV github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3/go.mod h1:5PC6ZNPde8bBqU/ewGZig35+UIZtw9Ytxez8/q5ZyFE= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8= -github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= +github.com/holiman/uint256 v1.2.2 h1:TXKcSGc2WaxPD2+bmzAsVthL4+pEN0YwXcL5qED83vk= +github.com/holiman/uint256 v1.2.2/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= @@ -616,8 +624,9 @@ github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= @@ -730,6 +739,8 @@ github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0 github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jhump/protoreflect v1.12.1-0.20220721211354-060cc04fc18b h1:izTof8BKh/nE1wrKOrloNA5q4odOarjf+Xpe+4qow98= +github.com/jmank88/go-plugin v0.0.0-20230604120638-7bb12ec27e75 h1:KYTOmcwuezD27O7vNF15lj8H7imCBMXCq1RzCdj4e3A= +github.com/jmank88/go-plugin v0.0.0-20230604120638-7bb12ec27e75/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= @@ -796,8 +807,8 @@ github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awS github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a h1:dHCfT5W7gghzPtfsW488uPmEOm85wewI+ypUwibyTdU= github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/leodido/go-urn v1.2.2 h1:7z68G0FCGvDk646jz1AelTYNYWrTNm0bEcFAo147wt4= -github.com/leodido/go-urn v1.2.2/go.mod h1:kUaIbLZWttglzwNuG0pgsh5vuV6u2YcGBYz1hIPjtOQ= +github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= +github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -1016,8 +1027,8 @@ github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/z github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= -github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= @@ -1043,8 +1054,8 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= -github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= @@ -1194,7 +1205,7 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw= +github.com/onsi/ginkgo/v2 v2.5.0 h1:TRtrvv2vdQqzkwrQ1ke6vtXf7IK34RBUJafIy1wMwls= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -1203,7 +1214,7 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E= +github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8= github.com/opencontainers/runc v1.1.7 h1:y2EZDS8sNng4Ksf0GUYNhKbTShZJPJg1FiXJNH/uoCk= @@ -1220,8 +1231,8 @@ github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaR github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.7 h1:muncTPStnKRos5dpVKULv2FVd4bMOhNePj9CjgDb8Us= -github.com/pelletier/go-toml/v2 v2.0.7/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= +github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= +github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= @@ -1244,14 +1255,15 @@ github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= -github.com/prometheus/prometheus v0.43.1 h1:Z/Z0S0CoPUVtUnHGokFksWMssSw2Y1Ir9NnWS1pPWU0= +github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk= +github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/prometheus/prometheus v0.45.0 h1:O/uG+Nw4kNxx/jDPxmjsSDd+9Ohql6E7ZSY1x5x/0KI= github.com/pyroscope-io/client v0.7.1 h1:yFRhj3vbgjBxehvxQmedmUWJQ4CAfCHhn+itPsuWsHw= github.com/pyroscope-io/client v0.7.1/go.mod h1:4h21iOU4pUOq0prKyDlvYRL+SCKsBc5wKiEtV+rJGqU= github.com/pyroscope-io/godeltaprof v0.1.0 h1:UBqtjt0yZi4jTxqZmLAs34XG6ycS3vUTlhEUSq4NHLE= @@ -1287,7 +1299,6 @@ github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNl github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/rwtodd/Go.Sed v0.0.0-20210816025313-55464686f9ef/go.mod h1:8AEUvGVi2uQ5b24BIhcr0GCcpd/RNAFWaN2CJFrWIIQ= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= @@ -1312,32 +1323,34 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ= github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= -github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e h1:XY8DncHICYQ1WDVpoXM7Tv3tztNHa1/DctDlSmqgU10= -github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= -github.com/smartcontractkit/chainlink-cosmos v0.4.0 h1:xYLAcJJIm0cyMtYtMaosO45bykEwcwQOmZz3mz46Y2A= -github.com/smartcontractkit/chainlink-env v0.3.29 h1:hcIw/BeuB0wKiiE3umAUNBZzWkHO24XF3OW9xSrlMbI= -github.com/smartcontractkit/chainlink-env v0.3.29/go.mod h1:9c0Czq4a6wZKY20BcoAlK29DnejQIiLo/MwKYtSFnHk= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230531014621-9c303da4c086 h1:d2WiCTnsCtA16KVabnX3E9SZH1irp2/d0MLT0/UI3XY= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230531014621-9c303da4c086/go.mod h1:zfUba6Okm7zTBxap24I78Vq9z+twHmjXSMBAl2C2Qgc= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230518143827-0b7a6e43719c h1:pM7FH+S92F7Xa/VSfbIs941FDKqSmo9pYeUBWHl1Pq0= -github.com/smartcontractkit/chainlink-testing-framework v1.11.5 h1:gYSnOQhLxgE0mxwnv015nNnPgH9kcosx+AzPboEFo38= -github.com/smartcontractkit/chainlink-testing-framework v1.11.5/go.mod h1:0ktPcDE5fFSvNewsaHuC4tGVaiCMQsl5RN/cWO5k0rg= -github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20230420131147-ce3c53a39d07 h1:UW3llKpFIfVmtu5F1GDLz0S4cze9Un46k15M+JDXSCU= -github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20230420131147-ce3c53a39d07/go.mod h1:dvEXSlzknoPm6YFaa0Ubs57CPFjhBbXnMju7WgiqiD4= -github.com/smartcontractkit/chainlink/v2 v2.2.0-mercury-20230527.0.20230531010141-105ba3488387 h1:6TI7kysRc1vZuRDPdU66Gvfc8k51Bh5qYf3YWPP/NFI= -github.com/smartcontractkit/chainlink/v2 v2.2.0-mercury-20230527.0.20230531010141-105ba3488387/go.mod h1:euMZJQMObJPBsmMD8Klvy/xvXg/hOzbU2D4eal8phiM= -github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3 h1:/Gel/U5eIZ/BGGr25OrHaXiVDTAJ5DYX5+UlXp3q7Gg= -github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3/go.mod h1:5JnCHuYgmIP9ZyXzgAfI5Iwu0WxBtBKp+ApeT5o1Cjw= -github.com/smartcontractkit/ocr2keepers v0.6.15 h1:dFhg+qT+tc6b3G8N4qnAHuHe8N0m8CSA8g4YGSeTGPo= -github.com/smartcontractkit/ocr2keepers v0.6.15/go.mod h1:gqIksJFzdXFsHfGdCWm1uTxbwvAltgcwcaqIgAStC1A= -github.com/smartcontractkit/ocr2vrf v0.0.0-20230510102715-c58be582bf19 h1:RxaC+V34UEP2u/riXfcvWPZEglri4UsfQi5joUObZ08= -github.com/smartcontractkit/ocr2vrf v0.0.0-20230510102715-c58be582bf19/go.mod h1:AZbOisIoA3cOUku8suZ+KWBnzbRiafmhi7UKiXoezrk= +github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumvbfM1u/etVq42Afwq/jtNSBSOA8n5jntnNPo= +github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230525203711-20bed74ac906 h1:u7Lw7oqLEjADlJPJQnzlCLNSbj038QttaKY0lCa3V78= +github.com/smartcontractkit/chainlink-env v0.36.1-0.20230802063028-a432269a7384 h1:AGEK80chNqkA9VouRtxkHZPG/WDrNGfpR/P7NyhRyYA= +github.com/smartcontractkit/chainlink-env v0.36.1-0.20230802063028-a432269a7384/go.mod h1:NbRExHmJGnKSYXmvNuJx5VErSx26GtE1AEN/CRzYOg8= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230801204930-f46c3ccc7815 h1:X8RMerGDjQKoEv7/jfh27egjye6yKmXBIf3iqwBLxsI= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230801204930-f46c3ccc7815/go.mod h1:MfZBUifutkv3aK7abyw5YmTJbqt8iFwcQDFikrxC/uI= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230612131011-369bfb503592 h1:3Ul/LkULxrolCVguHUFnWJamgUDsSGISlm/DzclstmE= +github.com/smartcontractkit/chainlink-testing-framework v1.14.0 h1:XJSE2xnXCij1Pdnykg1YUeFwfuaDQmpiMHQmygf2xYk= +github.com/smartcontractkit/chainlink-testing-framework v1.14.0/go.mod h1:Wio/JS9GuEAWOI0k46sUs4+/wLMZnZKz9IwCpdV/miY= +github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20230713025544-29b418df4ded h1:ByQpagkr0ne7Zy6ruoZcmtTqBopAsInk1BJwaT3eQrE= +github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20230713025544-29b418df4ded/go.mod h1:KCQ3I8BDGMMsJWACIYpqEANG1ExCQ3mgxthqmZePMoc= +github.com/smartcontractkit/chainlink/v2 v2.2.1-0.20230713025544-29b418df4ded h1:ohu+8roGude0mrwE+hAa45hSx8PD9YWrn2f95aDV2I8= +github.com/smartcontractkit/chainlink/v2 v2.2.1-0.20230713025544-29b418df4ded/go.mod h1:3xtrqeN9j4gEzShUbKr4pAYz/4St25xH2U7uhJFAgQM= +github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1 h1:caG9BWjnCxN/HPBA5ltDGadDraZAsjGIct4S8lh8D5c= +github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= +github.com/smartcontractkit/ocr2keepers v0.7.0 h1:5csjgDFQEO+kXr45vPX3o/v//X2bznNCWhgn94Qp6n0= +github.com/smartcontractkit/ocr2keepers v0.7.0/go.mod h1:13Q6zuYWLByKXzzcSoi7L01bT8OzxM//XgMZQeCZVP0= +github.com/smartcontractkit/ocr2vrf v0.0.0-20230616201444-d8b4222aff3c h1:BX1ibMdGE2QdD8rJEI5nxE4jA6v2bf7LULrSbDrNM+A= +github.com/smartcontractkit/ocr2vrf v0.0.0-20230616201444-d8b4222aff3c/go.mod h1:AT1OrDDOCd8vzmMsCnA70N+tZdq9AbdZAiAw+gQq260= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb h1:OMaBUb4X9IFPLbGbCHsMU+kw/BPCrewaVwWGIBc0I4A= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb/go.mod h1:HNUu4cJekUdsJbwRBCiOybtkPJEfGRELQPe2tkoDEyk= +github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230616141813-ca0ecf03ca5c h1:B7jWegIHCHXY32qWGwlNalrJYSz4uZh5zAgd2rQ3Iyc= +github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230625174811-4934857d1c4a h1:/ZJnNxcdJ75yDJHnKMjd3G9oZ6lcQRvFUdmiR2DPAgQ= github.com/smartcontractkit/wsrpc v0.7.2 h1:iBXzMeg7vc5YoezIQBq896y25BARw7OKbhrb6vPbtRQ= github.com/smartcontractkit/wsrpc v0.7.2/go.mod h1:sj7QX2NQibhkhxTfs3KOhAj/5xwgqMipTvJVSssT9i0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -1351,15 +1364,15 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw= -github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= +github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk= +github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= -github.com/spf13/cobra v1.6.0 h1:42a0n6jwCot1pUmomAp4T7DeMD+20LFv4Q54pxLf2LI= -github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= +github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= @@ -1369,8 +1382,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.14.0 h1:Rg7d3Lo706X9tHsJMUjdiwMpHB7W8WnSVOssIY+JElU= -github.com/spf13/viper v1.14.0/go.mod h1:WT//axPky3FdvXHzGw33dNdXXXfFQqmEalje+egj8As= +github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= +github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= @@ -1392,11 +1405,12 @@ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1F github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= -github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= +github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a h1:1ur3QoCqvE5fl+nylMaIr9PVV1w343YRDtsy+Rwu7XI= github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= @@ -1426,8 +1440,9 @@ github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= -github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms= github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= @@ -1440,12 +1455,12 @@ github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljT github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/ulule/limiter/v3 v3.11.1 h1:wm6YaA2JwIXc0S+z8TK8/neWMOTf4m20I5jL1dwLRcw= +github.com/ulule/limiter/v3 v3.11.2 h1:P4yOrxoEMJbOTfRJR2OzjL90oflzYPPmWg+dvwN2tHA= github.com/umbracle/ethgo v0.1.3 h1:s8D7Rmphnt71zuqrgsGTMS5gTNbueGO1zKLh7qsFzTM= github.com/umbracle/ethgo v0.1.3/go.mod h1:g9zclCLixH8liBI27Py82klDkW7Oo33AxUOr+M9lzrU= github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 h1:10Nbw6cACsnQm7r34zlpJky+IzxVLRk6MKTS2d3Vp0E= github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722/go.mod h1:c8J0h9aULj2i3umrfyestM6jCq0LK0U6ly6bWy96nd4= -github.com/unrolled/secure v0.0.0-20190624173513-716474489ad3 h1:Is9lt18DCzmbgaXowC/LuO1prTus8ejfgMn+GelBuHs= +github.com/unrolled/secure v1.13.0 h1:sdr3Phw2+f8Px8HE5sd1EHdj1aV3yUwed/uZXChLFsk= github.com/urfave/cli v1.22.13 h1:wsLILXG8qCJNse/qAgLNf23737Cx05GflHg/PJGe1Ok= github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= @@ -1486,8 +1501,9 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= +github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8= github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= @@ -1495,8 +1511,8 @@ go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw= go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= go.dedis.ch/kyber/v3 v3.0.9/go.mod h1:rhNjUUg6ahf8HEg5HUvVBYoWY4boAafX8tYxX+PS+qg= -go.dedis.ch/kyber/v3 v3.0.14 h1:vnHb/Q5ape/e98oYZdbOrs3CkQ1bUIZFANmOxb/3zyo= -go.dedis.ch/kyber/v3 v3.0.14/go.mod h1:kXy7p3STAurkADD+/aZcsznZGKVHEqbtmdIzvPfrs1U= +go.dedis.ch/kyber/v3 v3.1.0 h1:ghu+kiRgM5JyD9TJ0hTIxTLQlJBR/ehjWvWwYW3XsC0= +go.dedis.ch/kyber/v3 v3.1.0/go.mod h1:kXy7p3STAurkADD+/aZcsznZGKVHEqbtmdIzvPfrs1U= go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRLo= go.dedis.ch/protobuf v1.0.7/go.mod h1:pv5ysfkDX/EawiPqcW3ikOxsL5t+BqnV6xHSmE79KI4= go.dedis.ch/protobuf v1.0.11 h1:FTYVIEzY/bfl37lu3pR4lIj+F9Vp1jE8oh91VmxKgLo= @@ -1513,6 +1529,16 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 h1:ZOLJc06r4CB42laIXg/7udr0pbZyuAihN10A/XuiQRY= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0/go.mod h1:5z+/ZWJQKXa9YT34fQNx5K8Hd1EoIhvtUygUQPqEOgQ= +go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= +go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= +go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= +go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= +go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= +go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= +go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= +go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.starlark.net v0.0.0-20220817180228-f738f5508c12 h1:xOBJXWGEDwU5xSDxH6macxO11Us0AH2fTa9rmsbbF7g= go.starlark.net v0.0.0-20220817180228-f738f5508c12/go.mod h1:VZcBMdr3cT3PnBoWunTabuSEXwVAH+ZJ5zxfs3AdASk= @@ -1545,8 +1571,8 @@ go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= -golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc= +golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1583,8 +1609,8 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1595,8 +1621,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= -golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1624,8 +1650,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1673,6 +1699,7 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -1683,8 +1710,8 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1694,9 +1721,10 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= -golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= +golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= +golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1710,8 +1738,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1799,15 +1827,16 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1818,8 +1847,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1894,8 +1923,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= -golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= +golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1905,8 +1934,8 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= -gonum.org/v1/gonum v0.12.0 h1:xKuo6hzt+gMav00meVPUlXwSdoEJP46BR+wdxQEFK2o= -gonum.org/v1/gonum v0.12.0/go.mod h1:73TDxJfAAHeA8Mk9mf8NlIppyhQNo5GLTcYeqgo2lvY= +gonum.org/v1/gonum v0.13.0 h1:a0T3bh+7fhRyqeNbiC3qVHYmkiQgit3wnNan/2c0HMM= +gonum.org/v1/gonum v0.13.0/go.mod h1:/WPYRckkfWrhWefxyYTfrTtQR0KH4iyHNuzxqXAKyAU= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1969,6 +1998,7 @@ google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEY google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -1979,8 +2009,12 @@ google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= -google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc h1:8DyZCyvI8mE1IdLy/60bS+52xfymkE72wv1asokgtao= +google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= +google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc h1:kVKPf/IiYSBWEWtkIn6wZXwWGCnLKcC8oWfZvXjsGnM= +google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -2003,10 +2037,12 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc/examples v0.0.0-20210424002626-9572fd6faeae/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -2021,8 +2057,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -2083,20 +2119,20 @@ k8s.io/api v0.25.4 h1:3YO8J4RtmG7elEgaWMb4HgmpS2CfY1QlaOz9nwB+ZSs= k8s.io/api v0.25.4/go.mod h1:IG2+RzyPQLllQxnhzD8KQNEu4c4YvyDTpSMztf4A0OQ= k8s.io/apiextensions-apiserver v0.25.3 h1:bfI4KS31w2f9WM1KLGwnwuVlW3RSRPuIsfNF/3HzR0k= k8s.io/apiextensions-apiserver v0.25.3/go.mod h1:ZJqwpCkxIx9itilmZek7JgfUAM0dnTsA48I4krPqRmo= -k8s.io/apimachinery v0.25.4 h1:CtXsuaitMESSu339tfhVXhQrPET+EiWnIY1rcurKnAc= -k8s.io/apimachinery v0.25.4/go.mod h1:jaF9C/iPNM1FuLl7Zuy5b9v+n35HGSh6AQ4HYRkCqwo= -k8s.io/cli-runtime v0.25.4 h1:GTSBN7aKBrc2LqpdO30CmHQqJtRmotxV7XsMSP+QZIk= -k8s.io/cli-runtime v0.25.4/go.mod h1:JGOw1CR8v4Mcz6cEKA7bFQe0bPrNn1l5sGAX1/Ke4Eg= +k8s.io/apimachinery v0.25.11 h1:2EhfdrSAMvBxsswvOGCEymKk4ZnHZkranuZqdR0rsO4= +k8s.io/apimachinery v0.25.11/go.mod h1:IFwbcNi3gKkfDhuy0VYu3+BwbxbiIov3p6FR8ge1Epc= +k8s.io/cli-runtime v0.25.11 h1:GE2yNZm1tN+MJtw1SGMOLesLF7Kp7NVAVqRSTbXfu4o= +k8s.io/cli-runtime v0.25.11/go.mod h1:r/nEINuHVEpgGhcd2WamU7hD1t/lMnSz8XM44Autltc= k8s.io/client-go v0.25.4 h1:3RNRDffAkNU56M/a7gUfXaEzdhZlYhoW8dgViGy5fn8= k8s.io/client-go v0.25.4/go.mod h1:8trHCAC83XKY0wsBIpbirZU4NTUpbuhc2JnI7OruGZw= -k8s.io/component-base v0.25.4 h1:n1bjg9Yt+G1C0WnIDJmg2fo6wbEU1UGMRiQSjmj7hNQ= -k8s.io/component-base v0.25.4/go.mod h1:nnZJU8OP13PJEm6/p5V2ztgX2oyteIaAGKGMYb2L2cY= +k8s.io/component-base v0.25.11 h1:3QmISCE9n9CJkVpTA4spQO1IZCrLlOwbKdzSN9dqZZA= +k8s.io/component-base v0.25.11/go.mod h1:wFR4pfB+xTc6FBak+RoWRNeTmelGE4XWJP/xVOvn3vM= k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= -k8s.io/kubectl v0.25.4 h1:O3OA1z4V1ZyvxCvScjq0pxAP7ABgznr8UvnVObgI6Dc= -k8s.io/kubectl v0.25.4/go.mod h1:CKMrQ67Bn2YCP26tZStPQGq62zr9pvzEf65A0navm8k= +k8s.io/kubectl v0.25.11 h1:6bsft5Gan6BCvQ7cJbDRFjTm4Zfq8GuUYpsWAdVngYE= +k8s.io/kubectl v0.25.11/go.mod h1:8mIfgkFgT+yJ8/TlmPW1qoRh46H2si9q5nW8id7i9iM= k8s.io/utils v0.0.0-20221107191617-1a15be271d1d h1:0Smp/HP1OH4Rvhe+4B8nWGERtlqAGSftbSbbmm45oFs= k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/integration-tests/infra_deployments/deployer_test.go b/integration-tests/infra_deployments/deployer_test.go index ed9ca21d2..7f5ac0e2d 100644 --- a/integration-tests/infra_deployments/deployer_test.go +++ b/integration-tests/infra_deployments/deployer_test.go @@ -5,11 +5,12 @@ import ( "net/url" "testing" + "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-starknet/integration-tests/common" "github.com/smartcontractkit/chainlink-starknet/ops/gauntlet" "github.com/smartcontractkit/chainlink-starknet/ops/utils" "github.com/smartcontractkit/chainlink/integration-tests/client" - "github.com/stretchr/testify/require" ) const ( @@ -40,10 +41,10 @@ func createKeys(testState *testing.T) ([]*client.Chainlink, error) { for _, nodeUrl := range urls { u, _ := url.Parse(nodeUrl[0]) c, err := client.NewChainlink(&client.ChainlinkConfig{ - URL: nodeUrl[0], - Email: nodeUrl[1], - Password: nodeUrl[2], - RemoteIP: u.Host, + URL: nodeUrl[0], + Email: nodeUrl[1], + Password: nodeUrl[2], + InternalIP: u.Host, }) if err != nil { return nil, err diff --git a/integration-tests/smoke/ocr2_test.go b/integration-tests/smoke/ocr2_test.go index 341821e5c..b3c45a5ae 100644 --- a/integration-tests/smoke/ocr2_test.go +++ b/integration-tests/smoke/ocr2_test.go @@ -23,10 +23,9 @@ func init() { } var ( - err error - testState *common.Test - decimals = 9 - mockServerVal = 900000000 + err error + testState *common.Test + decimals = 9 ) func TestOCRBasic(t *testing.T) { @@ -51,7 +50,7 @@ func TestOCRBasic(t *testing.T) { if !testState.Common.Testnet { testState.Devnet.AutoLoadState(testState.OCR2Client, testState.OCRAddr) } - testState.SetUpNodes(mockServerVal) + testState.SetUpNodes() err = testState.ValidateRounds(10, false) require.NoError(t, err, "Validating round should not fail") diff --git a/integration-tests/soak/ocr2_test.go b/integration-tests/soak/ocr2_test.go index bbc8bd803..b66c1a1a6 100644 --- a/integration-tests/soak/ocr2_test.go +++ b/integration-tests/soak/ocr2_test.go @@ -15,11 +15,10 @@ import ( ) var ( - keepAlive bool - err error - testState *common.Test - decimals = 9 - mockServerVal = 900000000 + keepAlive bool + err error + testState *common.Test + decimals = 9 ) func init() { @@ -46,7 +45,6 @@ func TestOCRSoak(t *testing.T) { if !testState.Common.Testnet { testState.Devnet.AutoLoadState(testState.OCR2Client, testState.OCRAddr) } - testState.SetUpNodes(mockServerVal) err = testState.ValidateRounds(99999999, true) require.NoError(t, err, "Validating round should not fail") t.Cleanup(func() { diff --git a/integration-tests/utils/common.go b/integration-tests/utils/common.go index e6b59132b..0cdb3e9af 100644 --- a/integration-tests/utils/common.go +++ b/integration-tests/utils/common.go @@ -19,6 +19,8 @@ func GetTestLogger(t *testing.T) zerolog.Logger { } lvl, err := zerolog.ParseLevel(lvlStr) require.NoError(t, err, "error parsing log level") - l := zerolog.New(zerolog.NewTestWriter(t)).Output(zerolog.ConsoleWriter{Out: os.Stderr}).Level(lvl).With().Timestamp().Logger() + l := zerolog.New(zerolog.NewTestWriter(t)). + Output(zerolog.ConsoleWriter{Out: os.Stderr, NoColor: true}). + Level(lvl).With().Timestamp().Logger() return l } diff --git a/monitoring/go.mod b/monitoring/go.mod index 5daccf3d6..2dc2eacc4 100644 --- a/monitoring/go.mod +++ b/monitoring/go.mod @@ -3,13 +3,13 @@ module github.com/smartcontractkit/chainlink-starknet/monitoring go 1.20 require ( - github.com/prometheus/client_golang v1.14.0 - github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230531014621-9c303da4c086 + github.com/prometheus/client_golang v1.15.0 + github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230801204930-f46c3ccc7815 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230508053614-9f2fd5fd4ff1 - github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3 - github.com/stretchr/testify v1.8.2 - go.uber.org/multierr v1.9.0 + github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1 + github.com/stretchr/testify v1.8.4 + go.uber.org/multierr v1.11.0 ) require ( @@ -22,31 +22,35 @@ require ( github.com/deckarep/golang-set/v2 v2.1.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect github.com/ethereum/go-ethereum v1.11.5 // indirect - github.com/fatih/color v1.7.0 // indirect + github.com/fatih/color v1.13.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-stack/stack v1.8.1 // indirect - github.com/golang/protobuf v1.5.2 // indirect - github.com/golang/snappy v0.0.4 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 // indirect github.com/hashicorp/go-hclog v0.14.1 // indirect - github.com/hashicorp/go-plugin v1.4.9 // indirect + github.com/hashicorp/go-plugin v1.4.10 // indirect github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb // indirect - github.com/holiman/uint256 v1.2.0 // indirect + github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/linkedin/goavro/v2 v2.12.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.16 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/oklog/run v1.0.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.39.0 // indirect + github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/riferrei/srclient v0.5.4 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.1.1 // indirect @@ -55,16 +59,21 @@ require ( github.com/tklauser/go-sysconf v0.3.10 // indirect github.com/tklauser/numcpus v0.5.0 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 // indirect + go.opentelemetry.io/otel v1.16.0 // indirect + go.opentelemetry.io/otel/metric v1.16.0 // indirect + go.opentelemetry.io/otel/sdk v1.16.0 // indirect + go.opentelemetry.io/otel/trace v1.16.0 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.7.0 // indirect + golang.org/x/crypto v0.9.0 // indirect golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 // indirect - golang.org/x/net v0.8.0 // indirect + golang.org/x/net v0.10.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.7.0 // indirect - golang.org/x/text v0.8.0 // indirect - google.golang.org/genproto v0.0.0-20230223222841-637eb2293923 // indirect - google.golang.org/grpc v1.53.0 // indirect + golang.org/x/sys v0.8.0 // indirect + golang.org/x/text v0.9.0 // indirect + google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect + google.golang.org/grpc v1.55.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/monitoring/go.sum b/monitoring/go.sum index 5886a6221..9bdb8fead 100644 --- a/monitoring/go.sum +++ b/monitoring/go.sum @@ -1,6 +1,41 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o= github.com/actgardner/gogen-avro/v10 v10.1.0/go.mod h1:o+ybmVjEa27AAr35FRqU98DJu1fXES56uXniYFv4yDA= @@ -55,8 +90,9 @@ github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go. github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ethereum/go-ethereum v1.11.5 h1:3M1uan+LAUvdn+7wCEFrcMM4LJTeuxDrPTg/f31a5QQ= github.com/ethereum/go-ethereum v1.11.5/go.mod h1:it7x0DWnTDMfVFdXcU6Ti4KEFQynLHVRarcSlPr0HBo= -github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/frankban/quicktest v1.2.2/go.mod h1:Qh/WofXFeiAFII1aEBu529AtJo6Zg2VHscnEsbBnJ20= github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o= github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= @@ -66,16 +102,35 @@ github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbS github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -86,18 +141,24 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.2.1-0.20190312032427-6f77996f0c42/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -105,26 +166,45 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20211008130755-947d60d73cc0/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0 h1:mdLirNAJBxnGgyB6pjZLcs6ue/6eZGBui6gXspfq4ks= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0/go.mod h1:kdXbOySqcQeTxiqglW7aahTmWZy3Pgi6SYL36yvKeyA= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 h1:o95KDiV/b1xdkumY5YbLR0/n2+wBxUpgf3HgfKgTyLI= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3/go.mod h1:hTxjzRcX49ogbTGVJ1sM5mz5s+SSgiGIyL3jjPxl32E= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hamba/avro v1.5.6/go.mod h1:3vNT0RLXXpFm2Tb/5KC71ZRJlOroggq1Rcitb6k4Fr8= github.com/hashicorp/go-hclog v0.14.1 h1:nQcJDQwIAGnmoUWp8ubocEX40cCml/17YkF6csQLReU= github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-plugin v1.4.9 h1:ESiK220/qE0aGxWdzKIvRH69iLiuN/PjoLTm69RoWtU= -github.com/hashicorp/go-plugin v1.4.9/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= +github.com/hashicorp/go-plugin v1.4.10 h1:xUbmA4jC6Dq163/fWcp8P3JuHilrHHMLNRxzGQJ9hNk= +github.com/hashicorp/go-plugin v1.4.10/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/heetch/avro v0.3.1/go.mod h1:4xn38Oz/+hiEUTpbVfGVLfvOg0yKLlRP7Q9+gJJILgA= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= -github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM= -github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8= +github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/invopop/jsonschema v0.4.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= @@ -138,8 +218,11 @@ github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/juju/qthttptest v0.1.1/go.mod h1:aTlAv8TYaflIiTDIQYzxnl1QdPjAg8Q8qJMErpKy6A4= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -158,17 +241,20 @@ github.com/linkedin/goavro/v2 v2.11.1/go.mod h1:UgQUb2N/pmueQYH9bfqFioWxzYCZXSfF github.com/linkedin/goavro/v2 v2.12.0 h1:rIQQSj8jdAUlKQh6DttK8wCRv4t4QO09g1C4aBWXslg= github.com/linkedin/goavro/v2 v2.12.0/go.mod h1:KXx+erlq+RPlGSPmLF7xGo6SAbh8sCQ53x064+ioxhk= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 h1:7GoSOOW2jpsfkntVKaS2rAr1TJqfcxotyaUcuxoZSzg= -github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -186,13 +272,13 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= +github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= -github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= @@ -200,6 +286,7 @@ github.com/riferrei/srclient v0.5.4 h1:dfwyR5u23QF7beuVl2WemUY2KXh5+Sc4DHKyPXBNY github.com/riferrei/srclient v0.5.4/go.mod h1:vbkLmWcgYa7JgfPvuy/+K8fTS0p1bApqadxrxi/S1MI= github.com/rogpeppe/clock v0.0.0-20190514195947-2896927a307a/go.mod h1:4r5QyqhjIWCcK8DO4KMclc5Iknq5qVBAlbYYzAbUScQ= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= @@ -208,12 +295,12 @@ github.com/santhosh-tekuri/jsonschema/v5 v5.1.1 h1:lEOLY2vyGIqKWUI9nzsOJRV3mb3WC github.com/santhosh-tekuri/jsonschema/v5 v5.1.1/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e h1:XY8DncHICYQ1WDVpoXM7Tv3tztNHa1/DctDlSmqgU10= -github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230531014621-9c303da4c086 h1:d2WiCTnsCtA16KVabnX3E9SZH1irp2/d0MLT0/UI3XY= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230531014621-9c303da4c086/go.mod h1:zfUba6Okm7zTBxap24I78Vq9z+twHmjXSMBAl2C2Qgc= -github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3 h1:/Gel/U5eIZ/BGGr25OrHaXiVDTAJ5DYX5+UlXp3q7Gg= -github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3/go.mod h1:5JnCHuYgmIP9ZyXzgAfI5Iwu0WxBtBKp+ApeT5o1Cjw= +github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumvbfM1u/etVq42Afwq/jtNSBSOA8n5jntnNPo= +github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230801204930-f46c3ccc7815 h1:X8RMerGDjQKoEv7/jfh27egjye6yKmXBIf3iqwBLxsI= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230801204930-f46c3ccc7815/go.mod h1:MfZBUifutkv3aK7abyw5YmTJbqt8iFwcQDFikrxC/uI= +github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1 h1:caG9BWjnCxN/HPBA5ltDGadDraZAsjGIct4S8lh8D5c= +github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -222,13 +309,14 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= @@ -236,51 +324,120 @@ github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hM github.com/tklauser/numcpus v0.5.0 h1:ooe7gN0fg6myJ0EKoTAf5hebTZrH52px3New/D9iJ+A= github.com/tklauser/numcpus v0.5.0/go.mod h1:OGzpTxpcIMNGYQdit2BYL1pvk/dSOaJWjKoflh+RQjo= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 h1:ZOLJc06r4CB42laIXg/7udr0pbZyuAihN10A/XuiQRY= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0/go.mod h1:5z+/ZWJQKXa9YT34fQNx5K8Hd1EoIhvtUygUQPqEOgQ= +go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= +go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= +go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= +go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= +go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= +go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= +go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= +go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= -go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= -go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= +go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o= golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= @@ -288,59 +445,181 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20220503193339-ba3ae3f07e29/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20230223222841-637eb2293923 h1:znp6mq/drrY+6khTAlJUDNFFcDGV2ENLYKpMq8SyCds= -google.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc/examples v0.0.0-20210424002626-9572fd6faeae/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -349,6 +628,7 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= @@ -377,4 +657,12 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/monitoring/ops/Dockerfile b/monitoring/ops/Dockerfile index 2b9dbdffa..895d4a9c9 100644 --- a/monitoring/ops/Dockerfile +++ b/monitoring/ops/Dockerfile @@ -4,15 +4,18 @@ FROM golang:1.20-buster as build # Copy source -RUN mkdir -p /starknet-monitoring/cmd -COPY ./cmd/monitoring /starknet-monitoring/cmd/monitoring -COPY ./pkg /starknet-monitoring/pkg -COPY ./go.mod /starknet-monitoring/ -COPY ./go.sum /starknet-monitoring/ +RUN mkdir -p /build/starknet-monitoring/cmd +COPY ./monitoring/cmd/monitoring /build/starknet-monitoring/cmd/monitoring +COPY ./monitoring/pkg /build/starknet-monitoring/pkg +COPY ./monitoring/go.mod /build/starknet-monitoring/ +COPY ./monitoring/go.sum /build/starknet-monitoring/ + +# Copy relayer +COPY ./relayer /build/relayer # Compile binary -WORKDIR /starknet-monitoring +WORKDIR /build/starknet-monitoring RUN go build -o ./monitoring ./cmd/monitoring/*.go # Production image @@ -20,7 +23,7 @@ RUN go build -o ./monitoring ./cmd/monitoring/*.go FROM ubuntu:20.04 RUN apt-get update && apt-get install -y ca-certificates -COPY --from=build /starknet-monitoring/monitoring /monitoring +COPY --from=build /build/starknet-monitoring/monitoring /monitoring # Expose prometheus default port EXPOSE 9090/tcp diff --git a/monitoring/pkg/monitoring/source_envelope.go b/monitoring/pkg/monitoring/source_envelope.go index 744385d09..ac4bd9266 100644 --- a/monitoring/pkg/monitoring/source_envelope.go +++ b/monitoring/pkg/monitoring/source_envelope.go @@ -37,8 +37,8 @@ func (s *envelopeSourceFactory) NewSource( return nil, fmt.Errorf("expected feedConfig to be of type StarknetFeedConfig not %T", feedConfig) } return &envelopeSource{ - caigotypes.HexToHash(feedConfig.GetContractAddress()), - caigotypes.HexToHash(starknetChainConfig.GetLinkTokenAddress()), + caigotypes.StrToFelt(feedConfig.GetContractAddress()), + caigotypes.StrToFelt(starknetChainConfig.GetLinkTokenAddress()), s.ocr2Reader, }, nil } @@ -48,8 +48,8 @@ func (s *envelopeSourceFactory) GetType() string { } type envelopeSource struct { - contractAddress caigotypes.Hash - linkTokenAddress caigotypes.Hash + contractAddress caigotypes.Felt + linkTokenAddress caigotypes.Felt ocr2Reader ocr2.OCR2Reader } @@ -68,9 +68,7 @@ func (s *envelopeSource) Fetch(ctx context.Context) (interface{}, error) { return } envelope.BlockNumber = latestRoundData.BlockNumber - if newTransmissionEvent.Transmitter != nil { - envelope.Transmitter = types.Account(newTransmissionEvent.Transmitter.String()) - } + envelope.Transmitter = types.Account(newTransmissionEvent.Transmitter.String()) envelope.AggregatorRoundID = latestRoundData.RoundID envelope.ConfigDigest = newTransmissionEvent.ConfigDigest envelope.Epoch = newTransmissionEvent.Epoch @@ -117,7 +115,7 @@ func (s *envelopeSource) Fetch(ctx context.Context) (interface{}, error) { return envelope, envelopeErr } -func (s *envelopeSource) fetchLatestNewTransmissionEvent(ctx context.Context, contractAddress caigotypes.Hash) ( +func (s *envelopeSource) fetchLatestNewTransmissionEvent(ctx context.Context, contractAddress caigotypes.Felt) ( latestRound ocr2.RoundData, transmission ocr2.NewTransmissionEvent, err error, @@ -143,7 +141,7 @@ func (s *envelopeSource) fetchLatestNewTransmissionEvent(ctx context.Context, co return latestRound, transmission, fmt.Errorf("no new_trasmission event found to correspond with the round id %d in block %d", latestRound.RoundID, latestRound.BlockNumber) } -func (s *envelopeSource) fetchContractConfig(ctx context.Context, contractAddress caigotypes.Hash) (config ocr2.ContractConfig, err error) { +func (s *envelopeSource) fetchContractConfig(ctx context.Context, contractAddress caigotypes.Felt) (config ocr2.ContractConfig, err error) { configDetails, err := s.ocr2Reader.LatestConfigDetails(ctx, contractAddress) if err != nil { return config, fmt.Errorf("couldn't fetch latest config details for contract '%s': %w", contractAddress, err) @@ -157,7 +155,7 @@ func (s *envelopeSource) fetchContractConfig(ctx context.Context, contractAddres var zeroBigInt = big.NewInt(0) -func (s *envelopeSource) fetchLinkBalance(ctx context.Context, linkTokenAddress, contractAddress caigotypes.Hash) (*big.Int, error) { +func (s *envelopeSource) fetchLinkBalance(ctx context.Context, linkTokenAddress, contractAddress caigotypes.Felt) (*big.Int, error) { results, err := s.ocr2Reader.BaseReader().CallContract(ctx, starknet.CallOps{ ContractAddress: linkTokenAddress, Selector: "balanceOf", diff --git a/ops/charts/devnet/templates/deployment.yaml b/ops/charts/devnet/templates/deployment.yaml index 80fc165ac..8e4466a5e 100644 --- a/ops/charts/devnet/templates/deployment.yaml +++ b/ops/charts/devnet/templates/deployment.yaml @@ -31,7 +31,7 @@ spec: - "-c" - | mkdir -p cairo-build - curl -L --output release.tgz https://github.com/starkware-libs/cairo/releases/download/v1.0.0-rc0/release-x86_64-unknown-linux-musl.tar.gz + curl -L --output release.tgz https://github.com/starkware-libs/cairo/releases/download/v2.0.2/release-x86_64-unknown-linux-musl.tar.gz tar xzf release.tgz mv cairo/* cairo-build/ volumeMounts: @@ -47,7 +47,7 @@ spec: {{- else }} - name: cairo-build mountPath: /cairo-build - image: "{{ .Values.repository | default "shardlabs/starknet-devnet"}}:{{ .Values.tag | default "0.5.2"}}" + image: "{{ .Values.repository | default "shardlabs/starknet-devnet"}}:{{ .Values.tag | default "0.6.0a0"}}" args: ["--sierra-compiler-path", "/cairo-build/bin/starknet-sierra-compile", "--lite-mode", "--port", {{ .Values.service.internalPort | quote}}, "--seed", {{ .Values.seed | quote}}] {{- end }} imagePullPolicy: IfNotPresent diff --git a/ops/devnet/devnet.go b/ops/devnet/devnet.go index 4ddc4333a..8b886b54f 100644 --- a/ops/devnet/devnet.go +++ b/ops/devnet/devnet.go @@ -83,7 +83,7 @@ func (devnet *StarknetDevnetClient) AutoLoadState(client *ocr2.Client, ocrAddres return case <-t.C: log.Debug().Msg("Checking for devnet OCR contract errors") - _, err := client.LatestTransmissionDetails(devnet.ctx, caigotypes.HexToHash(ocrAddress)) + _, err := client.LatestTransmissionDetails(devnet.ctx, caigotypes.StrToFelt(ocrAddress)) if err != nil && strings.Contains(err.Error(), "is not deployed") { _, err = devnet.client.R().SetBody(map[string]any{ "path": devnet.dumpPath, diff --git a/ops/devnet/environment.go b/ops/devnet/environment.go index 4858ee022..c2f7f00cf 100644 --- a/ops/devnet/environment.go +++ b/ops/devnet/environment.go @@ -71,7 +71,7 @@ func defaultProps() map[string]any { "starknet-dev": map[string]any{ "image": map[string]any{ "image": "shardlabs/starknet-devnet", - "version": "v0.5.2", + "version": "v0.6.0a0", }, "resources": map[string]any{ "requests": map[string]any{ diff --git a/ops/go.mod b/ops/go.mod index 50467d77d..8a9bc86e3 100644 --- a/ops/go.mod +++ b/ops/go.mod @@ -5,7 +5,7 @@ go 1.20 require ( github.com/go-resty/resty/v2 v2.7.0 github.com/rs/zerolog v1.29.1 - github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e + github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 github.com/smartcontractkit/chainlink-env v0.3.29 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230530233948-90c8af98011e github.com/smartcontractkit/chainlink-testing-framework v1.11.5 @@ -42,7 +42,8 @@ require ( github.com/fvbommel/sortorder v1.0.2 // indirect github.com/getsentry/sentry-go v0.19.0 // indirect github.com/go-errors/errors v1.4.2 // indirect - github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect @@ -60,8 +61,10 @@ require ( github.com/google/uuid v1.3.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 // indirect github.com/hashicorp/go-hclog v1.4.0 // indirect - github.com/hashicorp/go-plugin v1.4.9 // indirect + github.com/hashicorp/go-plugin v1.4.10 // indirect github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce // indirect github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect github.com/imdario/mergo v0.3.15 // indirect @@ -99,17 +102,22 @@ require ( github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/russross/blackfriday v1.6.0 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230531014621-9c303da4c086 // indirect - github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3 // indirect + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230801204930-f46c3ccc7815 // indirect + github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1 // indirect github.com/spf13/cobra v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/testify v1.8.3 // indirect + github.com/stretchr/testify v1.8.4 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect github.com/tklauser/go-sysconf v0.3.11 // indirect github.com/tklauser/numcpus v0.6.0 // indirect github.com/xlab/treeprint v1.1.0 // indirect github.com/yuin/goldmark v1.4.13 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 // indirect + go.opentelemetry.io/otel v1.16.0 // indirect + go.opentelemetry.io/otel/metric v1.16.0 // indirect + go.opentelemetry.io/otel/sdk v1.16.0 // indirect + go.opentelemetry.io/otel/trace v1.16.0 // indirect go.starlark.net v0.0.0-20220817180228-f738f5508c12 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect @@ -129,7 +137,7 @@ require ( gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect - google.golang.org/grpc v1.53.0 // indirect + google.golang.org/grpc v1.55.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect @@ -159,5 +167,8 @@ replace ( github.com/btcsuite/btcd => github.com/btcsuite/btcd v0.22.1 github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 + // until merged upstream: https://github.com/hashicorp/go-plugin/pull/257 + github.com/hashicorp/go-plugin => github.com/jmank88/go-plugin v0.0.0-20230604120638-7bb12ec27e75 + github.com/smartcontractkit/chainlink-starknet/relayer => ../relayer ) diff --git a/ops/go.sum b/ops/go.sum index ffe65af32..ff1963793 100644 --- a/ops/go.sum +++ b/ops/go.sum @@ -1,9 +1,44 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= @@ -79,6 +114,7 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ethereum/go-ethereum v1.12.0 h1:bdnhLPtqETd4m3mS8BGMNvBTf36bO5bx/hxE2zljOa0= @@ -109,9 +145,15 @@ github.com/getsentry/sentry-go v0.19.0/go.mod h1:y3+lGEFEFexZtpbG1GUE2WD/f9zGyKY github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= @@ -129,13 +171,23 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg78 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -151,6 +203,8 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= @@ -159,6 +213,7 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -170,22 +225,38 @@ github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0 h1:mdLirNAJBxnGgyB6pjZLcs6ue/6eZGBui6gXspfq4ks= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0/go.mod h1:kdXbOySqcQeTxiqglW7aahTmWZy3Pgi6SYL36yvKeyA= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 h1:o95KDiV/b1xdkumY5YbLR0/n2+wBxUpgf3HgfKgTyLI= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3/go.mod h1:hTxjzRcX49ogbTGVJ1sM5mz5s+SSgiGIyL3jjPxl32E= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/go-hclog v1.4.0 h1:ctuWFGrhFha8BnnzxqeRGidlEcQkDyL5u8J8t5eA11I= github.com/hashicorp/go-hclog v1.4.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -github.com/hashicorp/go-plugin v1.4.9 h1:ESiK220/qE0aGxWdzKIvRH69iLiuN/PjoLTm69RoWtU= -github.com/hashicorp/go-plugin v1.4.9/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce h1:7UnVY3T/ZnHUrfviiAgIUjg2PXxsQfs5bphsG8F7Keo= github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= @@ -193,6 +264,7 @@ github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= @@ -201,6 +273,8 @@ github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= +github.com/jmank88/go-plugin v0.0.0-20230604120638-7bb12ec27e75 h1:KYTOmcwuezD27O7vNF15lj8H7imCBMXCq1RzCdj4e3A= +github.com/jmank88/go-plugin v0.0.0-20230604120638-7bb12ec27e75/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= @@ -208,9 +282,12 @@ github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2E github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -301,6 +378,7 @@ github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= @@ -312,16 +390,16 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e h1:XY8DncHICYQ1WDVpoXM7Tv3tztNHa1/DctDlSmqgU10= -github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= +github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumvbfM1u/etVq42Afwq/jtNSBSOA8n5jntnNPo= +github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-env v0.3.29 h1:hcIw/BeuB0wKiiE3umAUNBZzWkHO24XF3OW9xSrlMbI= github.com/smartcontractkit/chainlink-env v0.3.29/go.mod h1:9c0Czq4a6wZKY20BcoAlK29DnejQIiLo/MwKYtSFnHk= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230531014621-9c303da4c086 h1:d2WiCTnsCtA16KVabnX3E9SZH1irp2/d0MLT0/UI3XY= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230531014621-9c303da4c086/go.mod h1:zfUba6Okm7zTBxap24I78Vq9z+twHmjXSMBAl2C2Qgc= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230801204930-f46c3ccc7815 h1:X8RMerGDjQKoEv7/jfh27egjye6yKmXBIf3iqwBLxsI= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230801204930-f46c3ccc7815/go.mod h1:MfZBUifutkv3aK7abyw5YmTJbqt8iFwcQDFikrxC/uI= github.com/smartcontractkit/chainlink-testing-framework v1.11.5 h1:gYSnOQhLxgE0mxwnv015nNnPgH9kcosx+AzPboEFo38= github.com/smartcontractkit/chainlink-testing-framework v1.11.5/go.mod h1:0ktPcDE5fFSvNewsaHuC4tGVaiCMQsl5RN/cWO5k0rg= -github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3 h1:/Gel/U5eIZ/BGGr25OrHaXiVDTAJ5DYX5+UlXp3q7Gg= -github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3/go.mod h1:5JnCHuYgmIP9ZyXzgAfI5Iwu0WxBtBKp+ApeT5o1Cjw= +github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1 h1:caG9BWjnCxN/HPBA5ltDGadDraZAsjGIct4S8lh8D5c= +github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/cobra v1.6.0 h1:42a0n6jwCot1pUmomAp4T7DeMD+20LFv4Q54pxLf2LI= github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= @@ -343,8 +421,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a h1:1ur3QoCqvE5fl+nylMaIr9PVV1w343YRDtsy+Rwu7XI= github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= @@ -357,12 +435,29 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk= github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 h1:ZOLJc06r4CB42laIXg/7udr0pbZyuAihN10A/XuiQRY= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0/go.mod h1:5z+/ZWJQKXa9YT34fQNx5K8Hd1EoIhvtUygUQPqEOgQ= +go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= +go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= +go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= +go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= +go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= +go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= +go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= +go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.starlark.net v0.0.0-20220817180228-f738f5508c12 h1:xOBJXWGEDwU5xSDxH6macxO11Us0AH2fTa9rmsbbF7g= go.starlark.net v0.0.0-20220817180228-f738f5508c12/go.mod h1:VZcBMdr3cT3PnBoWunTabuSEXwVAH+ZJ5zxfs3AdASk= @@ -374,19 +469,44 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8 go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= @@ -398,14 +518,30 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -414,29 +550,55 @@ golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -462,7 +624,9 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -470,17 +634,53 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= @@ -492,28 +692,84 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc/examples v0.0.0-20210424002626-9572fd6faeae/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -522,6 +778,7 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= @@ -529,9 +786,11 @@ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= @@ -553,7 +812,12 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.25.4 h1:3YO8J4RtmG7elEgaWMb4HgmpS2CfY1QlaOz9nwB+ZSs= k8s.io/api v0.25.4/go.mod h1:IG2+RzyPQLllQxnhzD8KQNEu4c4YvyDTpSMztf4A0OQ= k8s.io/apiextensions-apiserver v0.25.3 h1:bfI4KS31w2f9WM1KLGwnwuVlW3RSRPuIsfNF/3HzR0k= @@ -574,6 +838,9 @@ k8s.io/kubectl v0.25.4 h1:O3OA1z4V1ZyvxCvScjq0pxAP7ABgznr8UvnVObgI6Dc= k8s.io/kubectl v0.25.4/go.mod h1:CKMrQ67Bn2YCP26tZStPQGq62zr9pvzEf65A0navm8k= k8s.io/utils v0.0.0-20221107191617-1a15be271d1d h1:0Smp/HP1OH4Rvhe+4B8nWGERtlqAGSftbSbbmm45oFs= k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= diff --git a/ops/scripts/devnet-hardhat.sh b/ops/scripts/devnet-hardhat.sh index 70b8c2cb5..f51be53e7 100755 --- a/ops/scripts/devnet-hardhat.sh +++ b/ops/scripts/devnet-hardhat.sh @@ -31,10 +31,10 @@ echo "Checking CPU structure..." if [[ $cpu_struct == *"arm"* ]] then echo "Starting arm devnet container..." - container_version="0.5.2-arm" + container_version="0.5.5-arm" else echo "Starting i386 devnet container..." - container_version="0.5.2" + container_version="0.5.5" fi echo "Starting starknet-devnet: ${startup_args}" diff --git a/ops/test_helpers.go b/ops/test_helpers.go index 9b2eebfa5..6819b7aba 100644 --- a/ops/test_helpers.go +++ b/ops/test_helpers.go @@ -76,7 +76,7 @@ var TestOCR2Config = OCR2Config{ AlphaAcceptPpb: 0, DeltaCNanoseconds: 1000000000, }, - MaxDurationQueryNanoseconds: 0, + MaxDurationQueryNanoseconds: 2000000000, MaxDurationObservationNanoseconds: 1000000000, MaxDurationReportNanoseconds: 2000000000, MaxDurationShouldAcceptFinalizedReportNanoseconds: 2000000000, diff --git a/package.json b/package.json index 29a2b4bc7..ffe481d1c 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "main": "packages-ts/starknet-gauntlet-cli/dist/index.js", "bin": "packages-ts/starknet-gauntlet-cli/dist/index.js", "scripts": { - "gauntlet": "yarn build && node ./packages-ts/starknet-gauntlet-cli/dist/index.js", + "gauntlet": "node ./packages-ts/starknet-gauntlet-cli/dist/index.js", "test": "yarn build && yarn workspaces run test", "test:coverage": "yarn test --collectCoverage", "test:ci": "yarn test --ci", @@ -44,10 +44,8 @@ }, "devDependencies": { "@changesets/cli": "^2.22.0", - "@types/bn.js": "^5.1.1", "@types/jest": "^28.1.0", "@types/node": "^18.7.11", - "bn.js": "^5.2.1", "jest": "^28.1.0", "pkg": "^5.2.1", "prettier": "2.1.1", @@ -56,6 +54,6 @@ "typescript": "4.7.2" }, "dependencies": { - "starknet": "^5.10.0" + "starknet": "^5.17.0" } } diff --git a/packages-ts/starknet-gauntlet-argent/README.md b/packages-ts/starknet-gauntlet-argent/README.md index 864ad4e38..797839713 100644 --- a/packages-ts/starknet-gauntlet-argent/README.md +++ b/packages-ts/starknet-gauntlet-argent/README.md @@ -2,14 +2,32 @@ ## Account -### Deploy +### Declare + +This declare a new account class hash onto the L2 layer. +```bash +yarn gauntlet argent_account:declare --network=testnet ``` + +Once it has been declared, you can use the class hash for a deployment (see Deploy command below) + +### Deploy + +```bash yarn gauntlet argent_account:deploy --network= ``` +Optionally, you can deploy by referencing a previously deployed class hash + +```bash +yarn gauntlet argent_account:deploy --classHash= --network= +``` + Note the contract address. The contract is not configured yet. A signer needs to be specified in it: + + ### Initialize ```bash diff --git a/packages-ts/starknet-gauntlet-argent/src/commands/account/declare.ts b/packages-ts/starknet-gauntlet-argent/src/commands/account/declare.ts new file mode 100644 index 000000000..64c1d2bb9 --- /dev/null +++ b/packages-ts/starknet-gauntlet-argent/src/commands/account/declare.ts @@ -0,0 +1,7 @@ +import { makeExecuteCommand, declareCommandConfig } from '@chainlink/starknet-gauntlet' +import { CATEGORIES } from '../../lib/categories' +import { CONTRACT_LIST, accountContractLoader } from '../../lib/contracts' + +export default makeExecuteCommand( + declareCommandConfig(CONTRACT_LIST.ACCOUNT, CATEGORIES.ACCOUNT, accountContractLoader), +) diff --git a/packages-ts/starknet-gauntlet-argent/src/commands/account/deploy.ts b/packages-ts/starknet-gauntlet-argent/src/commands/account/deploy.ts index b85874ff2..220044077 100644 --- a/packages-ts/starknet-gauntlet-argent/src/commands/account/deploy.ts +++ b/packages-ts/starknet-gauntlet-argent/src/commands/account/deploy.ts @@ -4,15 +4,30 @@ import { ExecutionContext, makeExecuteCommand, Validation, + isValidAddress, } from '@chainlink/starknet-gauntlet' import { CATEGORIES } from '../../lib/categories' import { accountContractLoader, CONTRACT_LIST } from '../../lib/contracts' -type UserInput = {} +type UserInput = { + classHash?: string +} type ContractInput = [] -const makeUserInput = async (flags, args): Promise => ({}) +const makeUserInput = async (flags, args): Promise => { + if (flags.input) return flags.input as UserInput + return { + classHash: flags.classHash, + } +} + +const validateClassHash = async (input) => { + if (isValidAddress(input.classHash) || input.classHash === undefined) { + return true + } + throw new Error(`Invalid Class Hash: ${input.classHash}`) +} const makeContractInput = async ( input: UserInput, @@ -35,11 +50,11 @@ const commandConfig: ExecuteCommandConfig = { action: 'deploy', ux: { description: 'Deploys an Argent Labs Account contract', - examples: [`${CATEGORIES.ACCOUNT}:deploy --network=`], + examples: [`${CATEGORIES.ACCOUNT}:deploy --classHash= --network=`], }, makeUserInput, makeContractInput, - validations: [], + validations: [validateClassHash], loadContract: accountContractLoader, hooks: { beforeExecute, diff --git a/packages-ts/starknet-gauntlet-argent/src/commands/account/index.ts b/packages-ts/starknet-gauntlet-argent/src/commands/account/index.ts index dc9ac9aa5..ba3a7ad46 100644 --- a/packages-ts/starknet-gauntlet-argent/src/commands/account/index.ts +++ b/packages-ts/starknet-gauntlet-argent/src/commands/account/index.ts @@ -1,4 +1,5 @@ import Deploy from './deploy' import Initialize from './initialize' +import Declare from './declare' -export default [Deploy, Initialize] +export default [Deploy, Initialize, Declare] diff --git a/packages-ts/starknet-gauntlet-emergency-protocol/README.md b/packages-ts/starknet-gauntlet-emergency-protocol/README.md index 09c2f6d51..e89664aac 100644 --- a/packages-ts/starknet-gauntlet-emergency-protocol/README.md +++ b/packages-ts/starknet-gauntlet-emergency-protocol/README.md @@ -66,6 +66,17 @@ yarn gauntlet starknet_validator:validate --previousRoundId= --pr ### Sequencer Uptime Feed +- Declare + +This declare a new `sequencer_uptime_feed` class hash onto the L2 layer. + +```bash +yarn gauntlet SequencerUptimeFeed:declare --network=testnet +``` + +Once it has been declared, you can use the class hash for a deployment (see Deploy command below) + + - Deploy This deploys a new `sequencer_uptime_feed` contract to L2. @@ -74,10 +85,19 @@ This deploys a new `sequencer_uptime_feed` contract to L2. `--owner` flag can be omitted. In such a case, it will default to the account specified in .env +`--classHash` flag can be omitted. If used, the deployment will be based off an already declared class on starknet rather than the local contract source code. + ```bash yarn gauntlet sequencer_uptime_feed:deploy --initialStatus= --owner= --network= ``` +Optionally, you can deploy by referencing a previously deployed class hash + +```bash +yarn gauntlet sequencer_uptime_feed:deploy --initialStatus= --owner= --classHash= --network= +``` + + - setL1Sender This sets the L1 sender address. This is to control, which L1 address can write new statuses to the uptime feed. @@ -88,6 +108,14 @@ This sets the L1 sender address. This is to control, which L1 address can write yarn gauntlet sequencer_uptime_feed:set_l1_sender --network= --address=
``` +- upgrade + +This upgrades the contract to point to a new class hash. + +```bash +yarn gauntlet SequencerUptimeFeed:upgrade --network=testnet --classHash= +``` + - Inspect Inspect the latest round data diff --git a/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/declare.ts b/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/declare.ts new file mode 100644 index 000000000..8b624fb0c --- /dev/null +++ b/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/declare.ts @@ -0,0 +1,11 @@ +import { makeExecuteCommand, declareCommandConfig } from '@chainlink/starknet-gauntlet' +import { CATEGORIES } from '../../lib/categories' +import { CONTRACT_LIST, uptimeFeedContractLoader } from '../../lib/contracts' + +export default makeExecuteCommand( + declareCommandConfig( + CONTRACT_LIST.SEQUENCER_UPTIME_FEED, + CATEGORIES.SEQUENCER_UPTIME_FEED, + uptimeFeedContractLoader, + ), +) diff --git a/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/deploy.ts b/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/deploy.ts index fd642e576..c50369bc6 100644 --- a/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/deploy.ts +++ b/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/deploy.ts @@ -9,6 +9,7 @@ import { CATEGORIES } from '../../lib/categories' type ContractInput = [initial_status: number, owner_address: string] export interface UserInput { + classHash?: string initialStatus: number owner?: string } @@ -24,6 +25,13 @@ const validateOwner = async (input) => { return true } +const validateClassHash = async (input) => { + if (isValidAddress(input.classHash) || input.classHash === undefined) { + return true + } + throw new Error(`Invalid Class Hash: ${input.classHash}`) +} + const validateInitialStatus = async (input) => { const status = Number(input.initialStatus) if (status !== 1 && status !== 0) { @@ -37,6 +45,7 @@ const makeUserInput = async (flags, args, env): Promise => { return { owner: flags.owner || env.account, initialStatus: flags.initialStatus, + classHash: flags.classHash, } } @@ -53,7 +62,7 @@ const commandConfig: ExecuteCommandConfig = { }, makeUserInput, makeContractInput, - validations: [validateOwner, validateInitialStatus], + validations: [validateOwner, validateInitialStatus, validateClassHash], loadContract: uptimeFeedContractLoader, } diff --git a/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/index.ts b/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/index.ts index 8618d2f56..ed37bf06f 100644 --- a/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/index.ts +++ b/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/index.ts @@ -1,7 +1,8 @@ import Deploy from './deploy' import SetL1Sender from './setL1Sender' - +import Declare from './declare' +import Upgrade from './upgrade' import Inspection from './inspection' -export const executionCommands = [Deploy, SetL1Sender] +export const executionCommands = [Deploy, Declare, SetL1Sender, Upgrade] export const inspectionCommands = [...Inspection] diff --git a/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/inspection/inspection.ts b/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/inspection/inspection.ts index 76e582ef2..33f46217f 100644 --- a/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/inspection/inspection.ts +++ b/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/inspection/inspection.ts @@ -3,16 +3,15 @@ import { IStarknetProvider, makeInspectionCommand, } from '@chainlink/starknet-gauntlet' -import { BN } from 'bn.js' import { CATEGORIES } from '../../../lib/categories' import { uptimeFeedContractLoader } from '../../../lib/contracts' type Round = { - round_id: number - answer: number - block_num: number - started_at: number - updated_at: number + round_id: string + answer: string + block_num: string + started_at: string + updated_at: string } type QueryResult = { @@ -31,7 +30,7 @@ const makeComparisionData = (provider: IStarknetProvider) => async ( for (var key in latest_round_data) { if (latest_round_data.hasOwnProperty(key)) { - latest_round_data[key] = new BN(latest_round_data[key]).toString() + latest_round_data[key] = BigInt(latest_round_data[key]).toString() } } diff --git a/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/setL1Sender.ts b/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/setL1Sender.ts index f24dc11a3..805b8783c 100644 --- a/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/setL1Sender.ts +++ b/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/setL1Sender.ts @@ -6,7 +6,7 @@ import { import { CATEGORIES } from '../../lib/categories' import { CONTRACT_LIST, uptimeFeedContractLoader } from '../../lib/contracts' -type ContractInput = [address: string] +type ContractInput = { address: string } export interface SetL1SenderInput { address: string @@ -27,7 +27,7 @@ const makeUserInput = async (flags): Promise => { } const makeContractInput = async (input: SetL1SenderInput): Promise => { - return [input.address] + return { address: input.address } } const commandConfig: ExecuteCommandConfig = { diff --git a/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/upgrade.ts b/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/upgrade.ts new file mode 100644 index 000000000..bbd18da1d --- /dev/null +++ b/packages-ts/starknet-gauntlet-emergency-protocol/src/commands/sequencerUptimeFeed/upgrade.ts @@ -0,0 +1,11 @@ +import { makeExecuteCommand, upgradeCommandConfig } from '@chainlink/starknet-gauntlet' +import { CATEGORIES } from '../../lib/categories' +import { CONTRACT_LIST, uptimeFeedContractLoader } from '../../lib/contracts' + +export default makeExecuteCommand( + upgradeCommandConfig( + CONTRACT_LIST.SEQUENCER_UPTIME_FEED, + CATEGORIES.SEQUENCER_UPTIME_FEED, + uptimeFeedContractLoader, + ), +) diff --git a/packages-ts/starknet-gauntlet-example/src/commands/example/inspection/inspect.ts b/packages-ts/starknet-gauntlet-example/src/commands/example/inspection/inspect.ts index c230c101e..ff4d9bbda 100644 --- a/packages-ts/starknet-gauntlet-example/src/commands/example/inspection/inspect.ts +++ b/packages-ts/starknet-gauntlet-example/src/commands/example/inspection/inspect.ts @@ -1,4 +1,3 @@ -import { BN } from '@chainlink/gauntlet-core/dist/utils' import { InspectCommandConfig, IStarknetProvider, @@ -23,7 +22,7 @@ const makeComparisionData = (provider: IStarknetProvider) => async ( return { toCompare: null, result: { - balance: new BN(balance.res).toString(), + balance: BigInt(balance.res).toString(), }, } } diff --git a/packages-ts/starknet-gauntlet-example/test/commands/example.test.ts b/packages-ts/starknet-gauntlet-example/test/commands/example.test.ts index 353b76a47..6049615fb 100644 --- a/packages-ts/starknet-gauntlet-example/test/commands/example.test.ts +++ b/packages-ts/starknet-gauntlet-example/test/commands/example.test.ts @@ -1,4 +1,3 @@ -import { BN } from '@chainlink/gauntlet-core/dist/utils' import { makeProvider } from '@chainlink/starknet-gauntlet' import { Contract } from 'starknet' import deployCommand from '../../src/commands/example/deploy' @@ -22,7 +21,7 @@ const getBalance = async (address: string) => { ) const balance = await contract.get_balance() - return new BN(balance.res).toString() + return BigInt(balance.res).toString() } describe('Example Contract', () => { diff --git a/packages-ts/starknet-gauntlet-multisig/README.md b/packages-ts/starknet-gauntlet-multisig/README.md index f6052af89..a484d3dd2 100644 --- a/packages-ts/starknet-gauntlet-multisig/README.md +++ b/packages-ts/starknet-gauntlet-multisig/README.md @@ -34,6 +34,10 @@ Threshold can only be updated through a transaction executed from the multisig i yarn gauntlet multisig:set_thresold:multisig --network= --threshold= ``` +### Upgrade + +To upgrade the multisig, you will need to create a proposal calling the `upgrade` function on the multisig contract. Please read the instructions below for how to create a proposal + ## Wrapping Gauntlet commands A [wrap function](./src/wrapper/index.ts#L30) is exposed from this package. It allows to wrap any Gauntlet command and make its functionality available to be executed from a multisig wallet. The process is the same for every command: diff --git a/packages-ts/starknet-gauntlet-multisig/src/commands/multisig/declare.ts b/packages-ts/starknet-gauntlet-multisig/src/commands/multisig/declare.ts new file mode 100644 index 000000000..266546e1a --- /dev/null +++ b/packages-ts/starknet-gauntlet-multisig/src/commands/multisig/declare.ts @@ -0,0 +1,7 @@ +import { makeExecuteCommand, declareCommandConfig } from '@chainlink/starknet-gauntlet' +import { CATEGORIES } from '../../lib/categories' +import { CONTRACT_LIST, contractLoader } from '../../lib/contracts' + +export default makeExecuteCommand( + declareCommandConfig(CONTRACT_LIST.MULTISIG, CATEGORIES.MULTISIG, contractLoader), +) diff --git a/packages-ts/starknet-gauntlet-multisig/src/commands/multisig/deploy.ts b/packages-ts/starknet-gauntlet-multisig/src/commands/multisig/deploy.ts index 8a5e8f53d..192e68ef5 100644 --- a/packages-ts/starknet-gauntlet-multisig/src/commands/multisig/deploy.ts +++ b/packages-ts/starknet-gauntlet-multisig/src/commands/multisig/deploy.ts @@ -5,13 +5,13 @@ import { isValidAddress, makeExecuteCommand, } from '@chainlink/starknet-gauntlet' -import { num } from 'starknet' import { CATEGORIES } from '../../lib/categories' import { contractLoader } from '../../lib/contracts' type UserInput = { signers: string[] threshold: string + classHash?: string } type ContractInput = [signersLen: number, ...signers: string[], threshold: number] @@ -22,6 +22,7 @@ const makeUserInput = async (flags, args): Promise => { return { signers: flags.signers, threshold: flags.threshold, + classHash: flags.classHash, } } @@ -35,6 +36,13 @@ export const validateThreshold = async (input: UserInput) => { return true } +const validateClassHash = async (input) => { + if (isValidAddress(input.classHash) || input.classHash === undefined) { + return true + } + throw new Error(`Invalid Class Hash: ${input.classHash}`) +} + export const validateSigners = async (input) => { const areValid = input.signers.every(isValidAddress) if (!areValid) throw new Error('Signers are not valid accounts') @@ -73,7 +81,7 @@ const commandConfig: ExecuteCommandConfig = { }, makeUserInput, makeContractInput, - validations: [validateSigners, validateThreshold], + validations: [validateSigners, validateThreshold, validateClassHash], loadContract: contractLoader, hooks: { beforeExecute, diff --git a/packages-ts/starknet-gauntlet-multisig/src/commands/multisig/index.ts b/packages-ts/starknet-gauntlet-multisig/src/commands/multisig/index.ts index 53773a017..7a5e76e12 100644 --- a/packages-ts/starknet-gauntlet-multisig/src/commands/multisig/index.ts +++ b/packages-ts/starknet-gauntlet-multisig/src/commands/multisig/index.ts @@ -1,8 +1,9 @@ import Deploy from './deploy' +import Declare from './declare' import SetSigners from './setSigners' import SetThreshold from './setThreshold' import Inspection from './inspection' -export const executeCommands = [Deploy, SetSigners, SetThreshold] +export const executeCommands = [Deploy, Declare, SetSigners, SetThreshold] export const inspectionCommands = [...Inspection] diff --git a/packages-ts/starknet-gauntlet-ocr2/README.md b/packages-ts/starknet-gauntlet-ocr2/README.md index f6723f5f1..5c822de85 100644 --- a/packages-ts/starknet-gauntlet-ocr2/README.md +++ b/packages-ts/starknet-gauntlet-ocr2/README.md @@ -13,6 +13,21 @@ LINK=0x... Note: The [token contract](https://github.com/smartcontractkit/chainlink-starknet/tree/develop/packages-ts/starknet-gauntlet-token) should only be deployed once and the same contract should be used for very aggregator + +## Deploying Contracts via Class Hash + +If you already know the class hash for a declared contract, all of the deploy commands in this module (ocr2, access_controller, proxy, Example) all have an optional --classHash flag which can be passed in to deploy a contract via the class hash rather than the local contract source code. + +e.g +```bash +yarn gauntlet access_controller:deploy --classHash= --network= +``` + +```bash +yarn gauntlet ocr2:deploy --network= --billingAccessController= --minSubmissionValue= --maxSubmissionValue= --decimals= --name= --link= --classHash= +``` + + ## Deploy an Access Controller Contract Run the following command: @@ -41,7 +56,7 @@ This command will generate a new OCR2 address and will give the details during t Run the following command substituting with the OCR2 contract address you received in the deploy step: ``` -yarn gauntlet ocr2:set_billing --observationPaymentGjuels= --transmissionPaymentGjuels= +yarn gauntlet ocr2:set_billing --observationPaymentGjuels= --transmissionPaymentGjuels= --gasBase= --gasPerSignature= ``` This Should set the billing details for this feed on contract address @@ -55,3 +70,20 @@ yarn gauntlet ocr2:set_config --network= --address=
--f= --classHash= `, +``` + +or + +```bash +yarn gautnlet ocr2:upgrade --network= --classHash= `, +``` diff --git a/packages-ts/starknet-gauntlet-ocr2/src/commands/accessController/declare.ts b/packages-ts/starknet-gauntlet-ocr2/src/commands/accessController/declare.ts new file mode 100644 index 000000000..75792da3d --- /dev/null +++ b/packages-ts/starknet-gauntlet-ocr2/src/commands/accessController/declare.ts @@ -0,0 +1,11 @@ +import { makeExecuteCommand, declareCommandConfig } from '@chainlink/starknet-gauntlet' +import { CATEGORIES } from '../../lib/categories' +import { accessControllerContractLoader } from '../../lib/contracts' + +export default makeExecuteCommand( + declareCommandConfig( + CATEGORIES.ACCESS_CONTROLLER, + CATEGORIES.ACCESS_CONTROLLER, + accessControllerContractLoader, + ), +) diff --git a/packages-ts/starknet-gauntlet-ocr2/src/commands/accessController/deploy.ts b/packages-ts/starknet-gauntlet-ocr2/src/commands/accessController/deploy.ts index 89cf650f2..5fba2b54c 100644 --- a/packages-ts/starknet-gauntlet-ocr2/src/commands/accessController/deploy.ts +++ b/packages-ts/starknet-gauntlet-ocr2/src/commands/accessController/deploy.ts @@ -1,9 +1,11 @@ import { ExecuteCommandConfig, makeExecuteCommand } from '@chainlink/starknet-gauntlet' import { CATEGORIES } from '../../lib/categories' import { accessControllerContractLoader, CONTRACT_LIST } from '../../lib/contracts' +import { validateClassHash } from '../../lib/utils' type UserInput = { owner: string + classHash?: string } type ContractInput = [owner: string] @@ -12,6 +14,7 @@ const makeUserInput = async (flags, args, env): Promise => { if (flags.input) return flags.input as UserInput return { owner: flags.owner || env.account, + classHash: flags.classHash, } } @@ -25,11 +28,13 @@ const commandConfig: ExecuteCommandConfig = { action: 'deploy', ux: { description: 'Deploys an Access Controller Contract', - examples: [`${CATEGORIES.ACCESS_CONTROLLER}:deploy --network=`], + examples: [ + `${CATEGORIES.ACCESS_CONTROLLER}:deploy --network= --classHash=`, + ], }, makeUserInput, makeContractInput, - validations: [], + validations: [validateClassHash], loadContract: accessControllerContractLoader, } diff --git a/packages-ts/starknet-gauntlet-ocr2/src/commands/accessController/index.ts b/packages-ts/starknet-gauntlet-ocr2/src/commands/accessController/index.ts index e2b8fe49e..5c880b292 100644 --- a/packages-ts/starknet-gauntlet-ocr2/src/commands/accessController/index.ts +++ b/packages-ts/starknet-gauntlet-ocr2/src/commands/accessController/index.ts @@ -1,3 +1,5 @@ import Deploy from './deploy' +import Declare from './declare' +import Upgrade from './upgrade' -export const executeCommands = [Deploy] +export const executeCommands = [Declare, Deploy, Upgrade] diff --git a/packages-ts/starknet-gauntlet-ocr2/src/commands/accessController/upgrade.ts b/packages-ts/starknet-gauntlet-ocr2/src/commands/accessController/upgrade.ts new file mode 100644 index 000000000..8c86a6a9c --- /dev/null +++ b/packages-ts/starknet-gauntlet-ocr2/src/commands/accessController/upgrade.ts @@ -0,0 +1,11 @@ +import { makeExecuteCommand, upgradeCommandConfig } from '@chainlink/starknet-gauntlet' +import { CATEGORIES } from '../../lib/categories' +import { accessControllerContractLoader } from '../../lib/contracts' + +export default makeExecuteCommand( + upgradeCommandConfig( + CATEGORIES.ACCESS_CONTROLLER, + CATEGORIES.ACCESS_CONTROLLER, + accessControllerContractLoader, + ), +) diff --git a/packages-ts/starknet-gauntlet-ocr2/src/commands/example/declare.ts b/packages-ts/starknet-gauntlet-ocr2/src/commands/example/declare.ts new file mode 100644 index 000000000..df507cd57 --- /dev/null +++ b/packages-ts/starknet-gauntlet-ocr2/src/commands/example/declare.ts @@ -0,0 +1,11 @@ +import { makeExecuteCommand, declareCommandConfig } from '@chainlink/starknet-gauntlet' +import { CATEGORIES } from '../../lib/categories' +import { CONTRACT_LIST, aggregatorConsumerLoader } from '../../lib/contracts' + +export default makeExecuteCommand( + declareCommandConfig( + CONTRACT_LIST.AGGREGATOR_CONSUMER, + CATEGORIES.OCR2, + aggregatorConsumerLoader, + ), +) diff --git a/packages-ts/starknet-gauntlet-ocr2/src/commands/example/deploy.ts b/packages-ts/starknet-gauntlet-ocr2/src/commands/example/deploy.ts index 70e691d71..3a8f84315 100644 --- a/packages-ts/starknet-gauntlet-ocr2/src/commands/example/deploy.ts +++ b/packages-ts/starknet-gauntlet-ocr2/src/commands/example/deploy.ts @@ -2,9 +2,11 @@ import { ExecuteCommandConfig, makeExecuteCommand } from '@chainlink/starknet-ga import { isValidAddress } from '@chainlink/starknet-gauntlet' import { CATEGORIES } from '../../lib/categories' import { CONTRACT_LIST, aggregatorConsumerLoader } from '../../lib/contracts' +import { validateClassHash } from '../../lib/utils' export interface UserInput { address: string + classHash?: string } type ContractInput = [address: string] @@ -14,6 +16,7 @@ const makeUserInput = async (flags, args): Promise => { return { address: flags.address, + classHash: flags.classHash, } } @@ -37,12 +40,12 @@ const commandConfig: ExecuteCommandConfig = { ux: { description: 'Deploys an example Aggregator consumer', examples: [ - `${CATEGORIES.OCR2}:consumer:deploy --network= --address=[AGGREGATOR_ADDRESS]`, + `${CATEGORIES.OCR2}:consumer:deploy --network= --address= --classHash=`, ], }, makeUserInput, makeContractInput, - validations: [validateInput], + validations: [validateInput, validateClassHash], loadContract: aggregatorConsumerLoader, } diff --git a/packages-ts/starknet-gauntlet-ocr2/src/commands/example/index.ts b/packages-ts/starknet-gauntlet-ocr2/src/commands/example/index.ts index dd4d01335..8362de175 100644 --- a/packages-ts/starknet-gauntlet-ocr2/src/commands/example/index.ts +++ b/packages-ts/starknet-gauntlet-ocr2/src/commands/example/index.ts @@ -1,5 +1,6 @@ import Deploy from './deploy' +import Declare from './declare' import Inspect from './inspect' -export const executeCommands = [Deploy] +export const executeCommands = [Deploy, Declare] export const inspectionCommands = [Inspect] diff --git a/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/declare.ts b/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/declare.ts new file mode 100644 index 000000000..cc3d52dcd --- /dev/null +++ b/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/declare.ts @@ -0,0 +1,7 @@ +import { makeExecuteCommand, declareCommandConfig } from '@chainlink/starknet-gauntlet' +import { CATEGORIES } from '../../lib/categories' +import { ocr2ContractLoader } from '../../lib/contracts' + +export default makeExecuteCommand( + declareCommandConfig(CATEGORIES.OCR2, CATEGORIES.OCR2, ocr2ContractLoader), +) diff --git a/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/deploy.ts b/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/deploy.ts index ff63d2757..1e86e8da6 100644 --- a/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/deploy.ts +++ b/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/deploy.ts @@ -1,11 +1,18 @@ -import { ExecuteCommandConfig, makeExecuteCommand } from '@chainlink/starknet-gauntlet' -import { BN } from '@chainlink/gauntlet-core/dist/utils' +import { + CONTRACT_TYPES, + ExecuteCommandConfig, + makeExecuteCommand, + ExecutionContext, + getRDD, +} from '@chainlink/starknet-gauntlet' import { ocr2ContractLoader } from '../../lib/contracts' -import { shortString, number } from 'starknet' +import { shortString } from 'starknet' import { DeployOCR2, DeployOCR2Input } from '@chainlink/gauntlet-contracts-ocr2' +import { validateClassHash } from '../../lib/utils' export interface UserInput extends DeployOCR2Input { owner: string + classHash?: string } type ContractInput = [ @@ -20,26 +27,63 @@ type ContractInput = [ const makeUserInput = async (flags, args, env): Promise => { if (flags.input) return flags.input as UserInput - return { + + if (flags.rdd) { + const rdd = getRDD(flags.rdd) + const contractAddr = args[0] + const aggregator = rdd[CONTRACT_TYPES.AGGREGATOR][contractAddr] + return { + maxAnswer: aggregator.maxSubmissionValue, + minAnswer: aggregator.minSubmissionValue, + decimals: aggregator.decimals, + description: aggregator.name, + billingAccessController: flags.billingAccessController || env.BILLING_ACCESS_CONTROLLER || '', + linkToken: flags.link || env.LINK || '', + owner: flags.owner || env.ACCOUNT, + } + } + + flags.min_answer = parseInt(flags.min_answer) + flags.max_answer = parseInt(flags.max_answer) + flags.decimals = parseInt(flags.decimals) + + const classHash = flags.classHash + const input = { ...DeployOCR2.makeUserInput(flags, args, env), owner: flags.owner || env.account, } as UserInput + // DeployOCR2.validations does not allow input keys to be "false-y" so we only add classHash key if it is !== undefined + if (classHash !== undefined) { + input['classHash'] = classHash + } + return input } -const makeContractInput = async (input: UserInput): Promise => { +const makeContractInput = async ( + input: UserInput, + ctx: ExecutionContext, +): Promise => { return [ input.owner, input.linkToken, input.minAnswer, input.maxAnswer, input.billingAccessController, - new BN(input.decimals).toNumber(), + input.decimals, shortString.encodeShortString(input.description), ] } const commandConfig: ExecuteCommandConfig = { ...DeployOCR2, + validations: [...DeployOCR2.validations, validateClassHash], + ux: { + description: 'Deploys OCR2 contract', + examples: [ + `yarn gauntlet ocr2:deploy --network= --billingAccessController= --minSubmissionValue= --maxSubmissionValue= --decimals= --name= --link= --owner=`, + `yarn gauntlet ocr2:deploy --network= --rdd= --billingAccessController= --link= --owner= `, + ], + }, makeUserInput: makeUserInput, makeContractInput: makeContractInput, loadContract: ocr2ContractLoader, diff --git a/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/index.ts b/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/index.ts index d1b70cad4..72253b9df 100644 --- a/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/index.ts +++ b/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/index.ts @@ -1,9 +1,21 @@ import Deploy from './deploy' +import Declare from './declare' +import Upgrade from './upgrade' import inspect from './inspection/inspect' import SetBilling from './setBilling' import SetConfig from './setConfig' +import SetPayees from './setPayees' import AddAccess from './addAccess' import DisableAccessCheck from './disableAccessCheck' -export const executeCommands = [Deploy, AddAccess, DisableAccessCheck, SetBilling, SetConfig] +export const executeCommands = [ + Deploy, + Declare, + Upgrade, + AddAccess, + DisableAccessCheck, + SetBilling, + SetConfig, + SetPayees, +] export const inspectionCommands = [inspect] diff --git a/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/inspection/configEvent.ts b/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/inspection/configEvent.ts new file mode 100644 index 000000000..ccacf1618 --- /dev/null +++ b/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/inspection/configEvent.ts @@ -0,0 +1,45 @@ +import { IStarknetProvider } from '@chainlink/starknet-gauntlet' +import { hash } from 'starknet' + +export const getLatestOCRConfigEvent = async ( + provider: IStarknetProvider, + contractAddress: string, +) => { + // get block number in which the latest config was set + const res = ( + await provider.provider.callContract({ + contractAddress, + entrypoint: 'latest_config_details', + calldata: [], + }) + ).result + const latestConfigDetails = { + configCount: parseInt(res[0]), + blockNumber: parseInt(res[1]), + configDigest: res[2], + } + // if no config has been set yet, return empty config + if (latestConfigDetails.configCount === 0) return [] + + // retrieve all block traces in the block in which the latest config was set + const blockTraces = await provider.provider.getBlockTraces(latestConfigDetails.blockNumber) + + // retrieve array of all events across all internal calls for each tx in the + // block, for which the contract address = aggregator contract and the first + // event key matches 'ConfigSet' + const configSetEvents = blockTraces.traces.flatMap((trace) => { + return trace.function_invocation.internal_calls + .filter((call) => call.contract_address === contractAddress) + .flatMap((call) => call.events) + .filter((event) => event.keys[0] === hash.getSelectorFromName('ConfigSet')) + }) + + // if no config set events found in the given block, throw error + // this should not happen if block number in latestConfigDetails is set correctly + if (configSetEvents.length === 0) + throw new Error(`No ConfigSet events found in block number ${latestConfigDetails.blockNumber}`) + + // assume last event found is the latest config, in the event that multiple + // set_config transactions ended up in the same block + return configSetEvents[configSetEvents.length - 1].data +} diff --git a/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/inspection/inspect.ts b/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/inspection/inspect.ts index 95bdcdfa4..7d5344650 100644 --- a/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/inspection/inspect.ts +++ b/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/inspection/inspect.ts @@ -3,11 +3,35 @@ import { IStarknetProvider, makeInspectionCommand, } from '@chainlink/starknet-gauntlet' -import { InvokeTransactionReceiptResponse } from 'starknet' +import { shortString, validateAndParseAddress } from 'starknet' import { CATEGORIES } from '../../../lib/categories' import { ocr2ContractLoader } from '../../../lib/contracts' -type QueryResult = {} +type QueryResult = { + typeAndVersion: string + description: string + owner: string + decimals: number + latestConfigDetails: { + configCount: number + blockNumber: number + configDigest: string + } + transmitterInfo: { + transmitter: string + owedPayment: string + }[] + billing: { + observationPaymentGjuels: string + transmissionPaymentGjuels: string + gasBase: string + gasPerSignature: string + } + linkAvailableForPayment: { + isNegative: boolean + absoluteDifference: string + } +} const makeComparisionData = (provider: IStarknetProvider) => async ( results: any[], @@ -17,13 +41,50 @@ const makeComparisionData = (provider: IStarknetProvider) => async ( toCompare: null result: QueryResult }> => { - const tx = (await provider.provider.getTransactionReceipt( - '0x475c15d6836972234c0542044fce7784cc61e8c5654d050aacadb918d8f3021', - )) as InvokeTransactionReceiptResponse - console.log(tx.events) + const typeAndVersion = shortString.decodeShortString(results[0]) + const description = shortString.decodeShortString(results[1]) + const owner = validateAndParseAddress(results[2]) + const decimals = parseInt(results[3]) + const latestConfigDetails = { + configCount: parseInt(results[4][0]), + blockNumber: parseInt(results[4][1]), + configDigest: '0x' + results[4][2].toString(16), + } + const transmitters = results[5].map((address) => validateAndParseAddress(address)) + let transmitterInfo = [] + for (const transmitter of transmitters) { + const owedPayment = await provider.provider.callContract({ + contractAddress, + entrypoint: 'owed_payment', + calldata: [transmitter], + }) + transmitterInfo.push({ + transmitter, + owedPayment: parseInt(owedPayment.result[0]).toString(), + }) + } + const billing = { + observationPaymentGjuels: parseInt(results[6].observation_payment_gjuels).toString(), + transmissionPaymentGjuels: parseInt(results[6].transmission_payment_gjuels).toString(), + gasBase: parseInt(results[6].gas_base).toString(), + gasPerSignature: parseInt(results[6].gas_per_signature).toString(), + } + const linkAvailableForPayment = { + isNegative: results[7][0], + absoluteDifference: parseInt(results[7][1]).toString(), + } return { toCompare: null, - result: {}, + result: { + typeAndVersion, + description, + owner, + decimals, + latestConfigDetails, + transmitterInfo, + billing, + linkAvailableForPayment, + }, } } @@ -31,9 +92,18 @@ const commandConfig: InspectCommandConfig = { ux: { category: CATEGORIES.OCR2, function: 'inspect', - examples: ['yarn gauntlet ocr2:inspect --network='], + examples: ['yarn gauntlet ocr2:inspect --network= '], }, - queries: [], + queries: [ + 'type_and_version', + 'description', + 'owner', + 'decimals', + 'latest_config_details', + 'transmitters', + 'billing', + 'link_available_for_payment', + ], makeComparisionData, loadContract: ocr2ContractLoader, } diff --git a/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/setBilling.ts b/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/setBilling.ts index 0f6d4c33f..7e2eacd36 100644 --- a/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/setBilling.ts +++ b/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/setBilling.ts @@ -1,5 +1,9 @@ -import { ExecuteCommandConfig, makeExecuteCommand } from '@chainlink/starknet-gauntlet' -import { BN } from '@chainlink/gauntlet-core/dist/utils' +import { + CONTRACT_TYPES, + ExecuteCommandConfig, + ExecutionContext, + makeExecuteCommand, +} from '@chainlink/starknet-gauntlet' import { ocr2ContractLoader } from '../../lib/contracts' import { SetBilling, SetBillingInput } from '@chainlink/gauntlet-contracts-ocr2' @@ -14,13 +18,21 @@ type ContractInput = [ }, ] -const makeContractInput = async (input: StarknetSetBillingInput): Promise => { +const makeContractInput = async ( + input: StarknetSetBillingInput, + ctx: ExecutionContext, +): Promise => { + if (ctx.rdd) { + const contract = ctx.rdd[CONTRACT_TYPES.AGGREGATOR][ctx.contractAddress] + input = contract.billing + } + return [ { - observation_payment_gjuels: new BN(input.observationPaymentGjuels).toNumber(), - transmission_payment_gjuels: new BN(input.transmissionPaymentGjuels).toNumber(), - gas_base: new BN(input.gasBase).toNumber(), - gas_per_signature: new BN(input.gasPerSignature).toNumber(), + observation_payment_gjuels: input.observationPaymentGjuels, + transmission_payment_gjuels: input.transmissionPaymentGjuels, + gas_base: input.gasBase || 0, + gas_per_signature: input.gasPerSignature || 0, }, ] } @@ -30,10 +42,10 @@ const commandConfig: ExecuteCommandConfig { if (flags.input) return flags.input as StarknetSetBillingInput return { - observationPaymentGjuels: flags.observationPaymentGjuels, - transmissionPaymentGjuels: flags.transmissionPaymentGjuels, - gasBase: flags.gasBase, - gasPerSignature: flags.gasPerSignature, + observationPaymentGjuels: parseInt(flags.observationPaymentGjuels), + transmissionPaymentGjuels: parseInt(flags.transmissionPaymentGjuels), + gasBase: parseInt(flags.gasBase || '0'), // optional + gasPerSignature: parseInt(flags.gasPerSignature || '0'), //optional } }, makeContractInput: makeContractInput, diff --git a/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/setConfig.ts b/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/setConfig.ts index 869f6f324..be9befc4e 100644 --- a/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/setConfig.ts +++ b/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/setConfig.ts @@ -1,15 +1,20 @@ import { + CONTRACT_TYPES, AfterExecute, ExecuteCommandConfig, + ExecutionContext, makeExecuteCommand, + bytesToFelts, + BeforeExecute, + getRDD, } from '@chainlink/starknet-gauntlet' -import { BN } from '@chainlink/gauntlet-core/dist/utils' +import { time, diff } from '@chainlink/gauntlet-core/dist/utils' import { ocr2ContractLoader } from '../../lib/contracts' import { SetConfig, encoding, SetConfigInput } from '@chainlink/gauntlet-contracts-ocr2' -import { bytesToFelts } from '@chainlink/starknet-gauntlet' import { decodeOffchainConfigFromEventData } from '../../lib/encoding' import assert from 'assert' import { InvokeTransactionReceiptResponse } from 'starknet' +import { getLatestOCRConfigEvent } from './inspection/configEvent' type Oracle = { signer: string @@ -24,7 +29,76 @@ type ContractInput = [ offchain_config: string[], ] -const makeContractInput = async (input: SetConfigInput): Promise => { +const makeUserInput = async (flags, args, env): Promise => { + if (flags.input) return flags.input as SetConfigInput + if (flags.rdd) { + const rdd = getRDD(flags.rdd) + const contractAddr = args[0] + const contract = rdd[CONTRACT_TYPES.AGGREGATOR][contractAddr] + const config = contract.config + const operators = contract.oracles.map((oracle) => rdd.operators[oracle.operator]) + const peerIds = operators.map((o) => o.peerId[0]) + const offchainConfig: encoding.OffchainConfig = { + deltaProgressNanoseconds: time.durationToNanoseconds(config.deltaProgress).toNumber(), + deltaResendNanoseconds: time.durationToNanoseconds(config.deltaResend).toNumber(), + deltaRoundNanoseconds: time.durationToNanoseconds(config.deltaRound).toNumber(), + deltaGraceNanoseconds: time.durationToNanoseconds(config.deltaGrace).toNumber(), + deltaStageNanoseconds: time.durationToNanoseconds(config.deltaStage).toNumber(), + rMax: config.rMax, + s: config.s, + offchainPublicKeys: operators.map((o) => o.ocr2OffchainPublicKey[0]), + peerIds: peerIds, + reportingPluginConfig: { + alphaReportInfinite: config.reportingPluginConfig.alphaReportInfinite, + alphaReportPpb: Number(config.reportingPluginConfig.alphaReportPpb), + alphaAcceptInfinite: config.reportingPluginConfig.alphaAcceptInfinite, + alphaAcceptPpb: Number(config.reportingPluginConfig.alphaAcceptPpb), + deltaCNanoseconds: time + .durationToNanoseconds(config.reportingPluginConfig.deltaC) + .toNumber(), + }, + maxDurationQueryNanoseconds: time.durationToNanoseconds(config.maxDurationQuery).toNumber(), + maxDurationObservationNanoseconds: time + .durationToNanoseconds(config.maxDurationObservation) + .toNumber(), + maxDurationReportNanoseconds: time.durationToNanoseconds(config.maxDurationReport).toNumber(), + maxDurationShouldAcceptFinalizedReportNanoseconds: time + .durationToNanoseconds(config.maxDurationShouldAcceptFinalizedReport) + .toNumber(), + maxDurationShouldTransmitAcceptedReportNanoseconds: time + .durationToNanoseconds(config.maxDurationShouldTransmitAcceptedReport) + .toNumber(), + configPublicKeys: operators.map((o) => o.ocr2ConfigPublicKey[0]), + } + + return { + f: config.f, + signers: operators.map((o) => o.ocr2OnchainPublicKey[0]), + transmitters: operators.map((o) => o.ocrNodeAddress[0]), + onchainConfig: [], + offchainConfig, + offchainConfigVersion: 2, + secret: flags.secret || env.secret, + randomSecret: flags.randomSecret || undefined, + } + } + + return { + f: parseInt(flags.f), + signers: flags.signers, + transmitters: flags.transmitters, + onchainConfig: flags.onchainConfig, + offchainConfig: flags.offchainConfig, + offchainConfigVersion: parseInt(flags.offchainConfigVersion), + secret: flags.secret || env.secret, + randomSecret: flags.randomSecret || undefined, + } +} + +const makeContractInput = async ( + input: SetConfigInput, + ctx: ExecutionContext, +): Promise => { const oracles: Oracle[] = input.signers.map((o, i) => { // standard format from chainlink node ocr2on_starknet_ (no 0x prefix) let signer = input.signers[i].replace('ocr2on_starknet_', '') // replace prefix if present @@ -49,7 +123,34 @@ const makeContractInput = async (input: SetConfigInput): Promise input.secret, ) let onchainConfig = [] // onchain config should be empty array for input (generate onchain) - return [oracles, new BN(input.f).toNumber(), onchainConfig, 2, bytesToFelts(offchainConfig)] + return [oracles, input.f, onchainConfig, 2, bytesToFelts(offchainConfig)] +} + +const beforeExecute: BeforeExecute = ( + context, + input, + deps, +) => async () => { + deps.logger.loading(`Executing ${context.id} from contract ${context.contractAddress}`) + + const { offchainConfig } = await encoding.serializeOffchainConfig( + input.user.offchainConfig, + input.user.secret, + ) + const newOffchainConfig = encoding.deserializeConfig(offchainConfig) + + const eventData = await getLatestOCRConfigEvent(context.provider, context.contractAddress) + if (eventData.length === 0) { + deps.logger.info('No previous config found, review the offchain config below:') + deps.logger.log(newOffchainConfig) + return + } + const currOffchainConfig = decodeOffchainConfigFromEventData(eventData) + + deps.logger.info( + 'Review the proposed offchain config changes below: green - added, red - deleted.', + ) + diff.printDiff(currOffchainConfig, newOffchainConfig) } const afterExecute: AfterExecute = (context, input, deps) => async ( @@ -80,9 +181,11 @@ const afterExecute: AfterExecute = (context, inpu const commandConfig: ExecuteCommandConfig = { ...SetConfig, + makeUserInput: makeUserInput, makeContractInput: makeContractInput, loadContract: ocr2ContractLoader, hooks: { + beforeExecute, afterExecute, }, } diff --git a/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/setPayees.ts b/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/setPayees.ts new file mode 100644 index 000000000..479c0eebd --- /dev/null +++ b/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/setPayees.ts @@ -0,0 +1,68 @@ +import { + CONTRACT_TYPES, + ExecuteCommandConfig, + ExecutionContext, + makeExecuteCommand, + getRDD, +} from '@chainlink/starknet-gauntlet' +import { CATEGORIES } from '../../lib/categories' +import { CONTRACT_LIST, ocr2ContractLoader } from '../../lib/contracts' + +type PayeeConfig = { + transmitter: string + payee: string +} + +type UserInput = PayeeConfig[] + +type ContractInput = [payees: PayeeConfig[]] + +const makeUserInput = async (flags, args): Promise => { + if (flags.input) return flags.input as UserInput + if (flags.rdd) { + const rdd = await getRDD(flags.rdd) + const contractAddress = args[0] + return rdd[CONTRACT_TYPES.AGGREGATOR][contractAddress].payees + } + + const transmitters = flags.transmitters.split(',') + const payees = flags.payees.split(',') + if (transmitters.length != payees.length) + throw new Error('Invalid input for payee config: number of transmitters and payees must match') + + return transmitters.map((transmitter, i) => ({ + transmitter, + payee: payees[i], + })) as UserInput +} + +const makeContractInput = async ( + input: UserInput, + ctx: ExecutionContext, +): Promise => { + return input.map((payeeConfig) => [ + { + transmitter: payeeConfig.transmitter, + payee: payeeConfig.payee, + }, + ]) as ContractInput +} + +const commandConfig: ExecuteCommandConfig = { + contractId: CONTRACT_LIST.OCR2, + action: 'set_payees', + category: CATEGORIES.OCR2, + ux: { + description: 'Set payees of OCR2 contract', + examples: [ + `yarn gauntlet ocr2:set_payees --network= --transmitters=[] --payees=[] `, + `yarn gauntlet ocr2:set_payees --network= --rdd= `, + ], + }, + validations: [], + makeUserInput: makeUserInput, + makeContractInput: makeContractInput, + loadContract: ocr2ContractLoader, +} + +export default makeExecuteCommand(commandConfig) diff --git a/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/upgrade.ts b/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/upgrade.ts new file mode 100644 index 000000000..9fb915cba --- /dev/null +++ b/packages-ts/starknet-gauntlet-ocr2/src/commands/ocr2/upgrade.ts @@ -0,0 +1,7 @@ +import { makeExecuteCommand, upgradeCommandConfig } from '@chainlink/starknet-gauntlet' +import { CATEGORIES } from '../../lib/categories' +import { ocr2ContractLoader } from '../../lib/contracts' + +export default makeExecuteCommand( + upgradeCommandConfig(CATEGORIES.OCR2, CATEGORIES.OCR2, ocr2ContractLoader), +) diff --git a/packages-ts/starknet-gauntlet-ocr2/src/commands/proxy/declare.ts b/packages-ts/starknet-gauntlet-ocr2/src/commands/proxy/declare.ts new file mode 100644 index 000000000..2cefd282e --- /dev/null +++ b/packages-ts/starknet-gauntlet-ocr2/src/commands/proxy/declare.ts @@ -0,0 +1,7 @@ +import { makeExecuteCommand, declareCommandConfig } from '@chainlink/starknet-gauntlet' +import { CATEGORIES } from '../../lib/categories' +import { ocr2ProxyLoader } from '../../lib/contracts' + +export default makeExecuteCommand( + declareCommandConfig(CATEGORIES.PROXY, CATEGORIES.PROXY, ocr2ProxyLoader), +) diff --git a/packages-ts/starknet-gauntlet-ocr2/src/commands/proxy/deploy.ts b/packages-ts/starknet-gauntlet-ocr2/src/commands/proxy/deploy.ts index 676c59798..0dc911030 100644 --- a/packages-ts/starknet-gauntlet-ocr2/src/commands/proxy/deploy.ts +++ b/packages-ts/starknet-gauntlet-ocr2/src/commands/proxy/deploy.ts @@ -6,10 +6,12 @@ import { } from '@chainlink/starknet-gauntlet' import { CATEGORIES } from '../../lib/categories' import { ocr2ProxyLoader, CONTRACT_LIST } from '../../lib/contracts' +import { validateClassHash } from '../../lib/utils' type UserInput = { owner: string address: string + classHash?: string } type ContractInput = [owner: string, address: string] @@ -19,6 +21,7 @@ const makeUserInput = async (flags, args, env): Promise => { return { owner: flags.owner || env.account, address: flags.address, + classHash: flags.classHash, } } @@ -51,11 +54,13 @@ const commandConfig: ExecuteCommandConfig = { action: 'deploy', ux: { description: 'Deploys an OCR2 aggregator proxy', - examples: [`${CATEGORIES.PROXY}:deploy --network= --address=`], + examples: [ + `${CATEGORIES.PROXY}:deploy --network= --address= --classHash=`, + ], }, makeUserInput, makeContractInput, - validations: [validateAddresses], + validations: [validateAddresses, validateClassHash], loadContract: ocr2ProxyLoader, hooks: { beforeExecute, diff --git a/packages-ts/starknet-gauntlet-ocr2/src/commands/proxy/index.ts b/packages-ts/starknet-gauntlet-ocr2/src/commands/proxy/index.ts index 5930b6fcd..6852e3a89 100644 --- a/packages-ts/starknet-gauntlet-ocr2/src/commands/proxy/index.ts +++ b/packages-ts/starknet-gauntlet-ocr2/src/commands/proxy/index.ts @@ -1,7 +1,9 @@ import Deploy from './deploy' +import Declare from './declare' +import Upgrade from './upgrade' import Inspect from './inspection/inspect' import ProposeAggregator from './proposeAggregator' import ConfirmAggregator from './confirmAggregator' -export const executeCommands = [Deploy, ProposeAggregator, ConfirmAggregator] +export const executeCommands = [Deploy, Declare, Upgrade, ProposeAggregator, ConfirmAggregator] export const inspectionCommands = [Inspect] diff --git a/packages-ts/starknet-gauntlet-ocr2/src/commands/proxy/upgrade.ts b/packages-ts/starknet-gauntlet-ocr2/src/commands/proxy/upgrade.ts new file mode 100644 index 000000000..046c4ac2c --- /dev/null +++ b/packages-ts/starknet-gauntlet-ocr2/src/commands/proxy/upgrade.ts @@ -0,0 +1,7 @@ +import { makeExecuteCommand, upgradeCommandConfig } from '@chainlink/starknet-gauntlet' +import { CATEGORIES } from '../../lib/categories' +import { ocr2ProxyLoader } from '../../lib/contracts' + +export default makeExecuteCommand( + upgradeCommandConfig(CATEGORIES.PROXY, CATEGORIES.PROXY, ocr2ProxyLoader), +) diff --git a/packages-ts/starknet-gauntlet-ocr2/src/lib/utils.ts b/packages-ts/starknet-gauntlet-ocr2/src/lib/utils.ts new file mode 100644 index 000000000..855ad12c6 --- /dev/null +++ b/packages-ts/starknet-gauntlet-ocr2/src/lib/utils.ts @@ -0,0 +1,12 @@ +import { + ExecuteCommandConfig, + makeExecuteCommand, + isValidAddress, +} from '@chainlink/starknet-gauntlet' + +export const validateClassHash = async (input) => { + if (isValidAddress(input.classHash) || input.classHash === undefined) { + return true + } + throw new Error(`Invalid Class Hash: ${input.classHash}`) +} diff --git a/packages-ts/starknet-gauntlet-ocr2/test/commands/ocr2.test.ts b/packages-ts/starknet-gauntlet-ocr2/test/commands/ocr2.test.ts index 38ad0999d..3860b5641 100644 --- a/packages-ts/starknet-gauntlet-ocr2/test/commands/ocr2.test.ts +++ b/packages-ts/starknet-gauntlet-ocr2/test/commands/ocr2.test.ts @@ -14,7 +14,6 @@ import { import { loadContract } from '@chainlink/starknet-gauntlet' import { CONTRACT_LIST } from '../../src/lib/contracts' import { Contract, InvokeTransactionReceiptResponse } from 'starknet' -import { BN } from '@chainlink/gauntlet-core/dist/utils' let account = devnetAccount0Address @@ -59,7 +58,7 @@ const validInput = { alphaAcceptPpb: 0, deltaCNanoseconds: 0, }, - maxDurationQueryNanoseconds: 0, + maxDurationQueryNanoseconds: 2000000000, maxDurationObservationNanoseconds: 1000000000, maxDurationReportNanoseconds: 200000000, maxDurationShouldAcceptFinalizedReportNanoseconds: 200000000, @@ -182,14 +181,15 @@ describe('OCR2 Contract', () => { // TODO: use StarknetContract decodeEvents from starknet-hardhat-plugin instead const eventData = receipt.events[0].data // reconstruct signers array from event - let eventSigners = [] + let eventSigners: bigint[] = [] for (let i = 0; i < signers.length; i++) { - const signer = new BN(eventData[4 + 2 * i].replace('0x', ''), 16) // split according to event structure + const signer = BigInt(eventData[4 + 2 * i]) // split according to event structure eventSigners.push(signer) } expect(eventSigners).toEqual( - signers.map((s) => new BN(s.replace('ocr2on_starknet_', '').replace('0x', ''), 16)), + // eaiser to remove prefix and 0x and then add 0x back + signers.map((s) => BigInt(`0x${s.replace('ocr2on_starknet_', '').replace('0x', '')}`)), ) // remove all prefixes expect(resultTransmitters).toEqual(transmitters.map((transmitter) => BigInt(transmitter))) }, diff --git a/packages-ts/starknet-gauntlet-oz/README.md b/packages-ts/starknet-gauntlet-oz/README.md index 0c71b97a0..7daa7e64c 100644 --- a/packages-ts/starknet-gauntlet-oz/README.md +++ b/packages-ts/starknet-gauntlet-oz/README.md @@ -14,6 +14,12 @@ This command will generate a new Keypair and will give the details during the ex yarn gauntlet account:deploy --network= --publicKey= ``` +Additionally, if the contract has already been declared, you can deploy by just referencing the class hash. + +```bash +yarn gauntlet account:deploy --classHash= --network= --publicKey= +``` + After the execution is finished, you will want to include the account contract and the private key to your `.env` configuration file. ```bash diff --git a/packages-ts/starknet-gauntlet-oz/package.json b/packages-ts/starknet-gauntlet-oz/package.json index 3fb695a94..278319e6b 100644 --- a/packages-ts/starknet-gauntlet-oz/package.json +++ b/packages-ts/starknet-gauntlet-oz/package.json @@ -25,7 +25,7 @@ "bundle": "yarn build && pkg ." }, "dependencies": { - "@chainlink-dev/starkgate-open-zeppelin": "^0.5.0", + "@chainlink-dev/starkgate-open-zeppelin": "^0.6.1", "@chainlink/gauntlet-core": "0.3.1", "@chainlink/starknet-gauntlet": "*" } diff --git a/packages-ts/starknet-gauntlet-oz/src/commands/account/declare.ts b/packages-ts/starknet-gauntlet-oz/src/commands/account/declare.ts new file mode 100644 index 000000000..64c1d2bb9 --- /dev/null +++ b/packages-ts/starknet-gauntlet-oz/src/commands/account/declare.ts @@ -0,0 +1,7 @@ +import { makeExecuteCommand, declareCommandConfig } from '@chainlink/starknet-gauntlet' +import { CATEGORIES } from '../../lib/categories' +import { CONTRACT_LIST, accountContractLoader } from '../../lib/contracts' + +export default makeExecuteCommand( + declareCommandConfig(CONTRACT_LIST.ACCOUNT, CATEGORIES.ACCOUNT, accountContractLoader), +) diff --git a/packages-ts/starknet-gauntlet-oz/src/commands/account/deploy.ts b/packages-ts/starknet-gauntlet-oz/src/commands/account/deploy.ts index 433876894..7f7cf4475 100644 --- a/packages-ts/starknet-gauntlet-oz/src/commands/account/deploy.ts +++ b/packages-ts/starknet-gauntlet-oz/src/commands/account/deploy.ts @@ -3,15 +3,17 @@ import { BeforeExecute, ExecuteCommandConfig, makeExecuteCommand, + isValidAddress, } from '@chainlink/starknet-gauntlet' import { ec } from 'starknet' import { CATEGORIES } from '../../lib/categories' -import { accountContractLoader, CONTRACT_LIST, equalAddress } from '../../lib/contracts' +import { accountContractLoader, CONTRACT_LIST } from '../../lib/contracts' type UserInput = { publicKey: string privateKey?: string salt?: number + classHash?: string } type ContractInput = [publicKey: string] @@ -28,9 +30,17 @@ const makeUserInput = async (flags, _, env): Promise => { publicKey: pubkey, privateKey: (!flags.publicKey || !env.account) && generatedPK, salt, + classHash: flags.classHash, } } +const validateClassHash = async (input) => { + if (isValidAddress(input.classHash) || input.classHash === undefined) { + return true + } + throw new Error(`Invalid Class Hash: ${input.classHash}`) +} + const makeContractInput = async (input: UserInput): Promise => { return [input.publicKey] } @@ -75,12 +85,12 @@ const commandConfig: ExecuteCommandConfig = { ux: { description: 'Deploys an OpenZeppelin Account contract', examples: [ - `${CATEGORIES.ACCOUNT}:deploy --network= --address=
`, + `${CATEGORIES.ACCOUNT}:deploy --network= --address=
--classHash= `, ], }, makeUserInput, makeContractInput, - validations: [], + validations: [validateClassHash], loadContract: accountContractLoader, hooks: { beforeExecute, diff --git a/packages-ts/starknet-gauntlet-oz/src/commands/account/index.ts b/packages-ts/starknet-gauntlet-oz/src/commands/account/index.ts index 2a9000aab..d0388d365 100644 --- a/packages-ts/starknet-gauntlet-oz/src/commands/account/index.ts +++ b/packages-ts/starknet-gauntlet-oz/src/commands/account/index.ts @@ -1,2 +1,3 @@ import Deploy from './deploy' -export default [Deploy] +import Declare from './declare' +export default [Deploy, Declare] diff --git a/packages-ts/starknet-gauntlet-oz/src/lib/contracts.ts b/packages-ts/starknet-gauntlet-oz/src/lib/contracts.ts index 448860258..acf1aa938 100644 --- a/packages-ts/starknet-gauntlet-oz/src/lib/contracts.ts +++ b/packages-ts/starknet-gauntlet-oz/src/lib/contracts.ts @@ -1,6 +1,5 @@ import fs from 'fs' import { json } from 'starknet' -import BN from 'bn.js' export enum CONTRACT_LIST { ACCOUNT = 'Account', @@ -10,22 +9,9 @@ export const accountContractLoader = () => { return { contract: json.parse( fs.readFileSync( - `${__dirname}/../../../../node_modules/@chainlink-dev/starkgate-open-zeppelin/artifacts/0.5.0/Account.cairo/Account.json`, + `${__dirname}/../../../../node_modules/@chainlink-dev/starkgate-open-zeppelin/artifacts/0.6.1/Account.cairo/Account.json`, 'utf8', ), ), } } - -// use bignumber libraries to assert addresses are equal -// handles prepending 0s -export const equalAddress = (addr0: string, addr1: string): boolean => { - let a0 = new BN(removePrefix(addr0), 16) - let a1 = new BN(removePrefix(addr1), 16) - - return a0.cmp(a1) == 0 -} - -const removePrefix = (addr: string): string => { - return addr.replace(/^(0x)/, '') -} diff --git a/packages-ts/starknet-gauntlet-oz/test/commands/account.test.ts b/packages-ts/starknet-gauntlet-oz/test/commands/account.test.ts index 4289e1a37..b350759be 100644 --- a/packages-ts/starknet-gauntlet-oz/test/commands/account.test.ts +++ b/packages-ts/starknet-gauntlet-oz/test/commands/account.test.ts @@ -7,7 +7,7 @@ import { startNetwork, IntegratedDevnet, } from '@chainlink/starknet-gauntlet/test/utils' -import { accountContractLoader, CONTRACT_LIST, equalAddress } from '../../src/lib/contracts' +import { accountContractLoader, CONTRACT_LIST } from '../../src/lib/contracts' import { Contract } from 'starknet' describe('OZ Account Contract', () => { diff --git a/packages-ts/starknet-gauntlet-token/README.md b/packages-ts/starknet-gauntlet-token/README.md index e34fe6521..a62b270dc 100644 --- a/packages-ts/starknet-gauntlet-token/README.md +++ b/packages-ts/starknet-gauntlet-token/README.md @@ -2,6 +2,14 @@ ## Token +### Declare + +To delcare the class hash of a contract: + +```bash +yarn gauntlet token:declare --network= +``` + ### Deploy The contract is pre-configured to be the LINK token contract. @@ -10,6 +18,13 @@ The contract is pre-configured to be the LINK token contract. yarn gauntlet token:deploy --network= --owner= ``` +To deploy by referencing an existing class hash: + +```bash +yarn gauntlet token:deploy --classHash= --network= --owner= +``` + + IMPORTANT: For the token contract to be used in L1<>L2 bridging the `owner` must be the L2 Bridge address. ### Mint @@ -29,3 +44,10 @@ yarn gauntlet token:transfer --network= --recipient= ```bash yarn gauntlet token:balance_of --network= --address= ``` + +### Upgrade + +```bash +yarn gauntlet token:upgrade --network= --classHash= +``` + diff --git a/packages-ts/starknet-gauntlet-token/src/commands/token/declare.ts b/packages-ts/starknet-gauntlet-token/src/commands/token/declare.ts new file mode 100644 index 000000000..f43f5d6a6 --- /dev/null +++ b/packages-ts/starknet-gauntlet-token/src/commands/token/declare.ts @@ -0,0 +1,29 @@ +import { ExecuteCommandConfig, makeExecuteCommand } from '@chainlink/starknet-gauntlet' +import { tokenContractLoader } from '../../lib/contracts' +import { CATEGORIES } from '../../lib/categories' + +type UserInput = {} + +type ContractInput = [] + +const makeContractInput = async (input: UserInput): Promise => { + return [] +} + +const makeUserInput = async (flags, args): Promise => ({}) + +const commandConfig: ExecuteCommandConfig = { + contractId: CATEGORIES.TOKEN, + category: CATEGORIES.TOKEN, + action: 'declare', + ux: { + description: `Declares an ${CATEGORIES.TOKEN} contract`, + examples: [`${CATEGORIES.TOKEN}:declare --network=`], + }, + makeUserInput, + makeContractInput, + validations: [], + loadContract: tokenContractLoader, +} + +export default makeExecuteCommand(commandConfig) diff --git a/packages-ts/starknet-gauntlet-token/src/commands/token/deploy.ts b/packages-ts/starknet-gauntlet-token/src/commands/token/deploy.ts index 5379587a7..7f1b49c31 100644 --- a/packages-ts/starknet-gauntlet-token/src/commands/token/deploy.ts +++ b/packages-ts/starknet-gauntlet-token/src/commands/token/deploy.ts @@ -3,6 +3,7 @@ import { ExecuteCommandConfig, ExecutionContext, makeExecuteCommand, + isValidAddress, } from '@chainlink/starknet-gauntlet' import { CATEGORIES } from '../../lib/categories' import { tokenContractLoader, CONTRACT_LIST } from '../../lib/contracts' @@ -10,6 +11,7 @@ import { tokenContractLoader, CONTRACT_LIST } from '../../lib/contracts' type UserInput = { minter?: string owner?: string + classHash?: string } type ContractInput = [minter: string, owner: string] @@ -20,9 +22,17 @@ const makeUserInput = async (flags, args): Promise => { return { minter: flags.minter, owner: flags.owner, + classHash: flags.classHash, } } +const validateClassHash = async (input) => { + if (isValidAddress(input.classHash) || input.classHash === undefined) { + return true + } + throw new Error(`Invalid Class Hash: ${input.classHash}`) +} + const makeContractInput = async ( input: UserInput, context: ExecutionContext, @@ -50,11 +60,12 @@ const commandConfig: ExecuteCommandConfig = { examples: [ `${CATEGORIES.TOKEN}:deploy --network=`, `${CATEGORIES.TOKEN}:deploy --network= --owner=`, + `${CATEGORIES.TOKEN}:deploy --network= --owner= --classHash=`, ], }, makeUserInput, makeContractInput, - validations: [], + validations: [validateClassHash], loadContract: tokenContractLoader, hooks: { beforeExecute, diff --git a/packages-ts/starknet-gauntlet-token/src/commands/token/index.ts b/packages-ts/starknet-gauntlet-token/src/commands/token/index.ts index 96b3b592e..62fc370f5 100644 --- a/packages-ts/starknet-gauntlet-token/src/commands/token/index.ts +++ b/packages-ts/starknet-gauntlet-token/src/commands/token/index.ts @@ -1,5 +1,7 @@ import Deploy from './deploy' +import Declare from './declare' +import Upgrade from './upgrade' import Mint from './mint' import Transfer from './transfer' -export default [Deploy, Mint, Transfer] +export default [Deploy, Declare, Mint, Transfer, Upgrade] diff --git a/packages-ts/starknet-gauntlet-token/src/commands/token/upgrade.ts b/packages-ts/starknet-gauntlet-token/src/commands/token/upgrade.ts new file mode 100644 index 000000000..728e14096 --- /dev/null +++ b/packages-ts/starknet-gauntlet-token/src/commands/token/upgrade.ts @@ -0,0 +1,7 @@ +import { makeExecuteCommand, upgradeCommandConfig } from '@chainlink/starknet-gauntlet' +import { CATEGORIES } from '../../lib/categories' +import { tokenContractLoader } from '../../lib/contracts' + +export default makeExecuteCommand( + upgradeCommandConfig(CATEGORIES.TOKEN, CATEGORIES.TOKEN, tokenContractLoader), +) diff --git a/packages-ts/starknet-gauntlet/src/commands/base/declareCommandConfig.ts b/packages-ts/starknet-gauntlet/src/commands/base/declareCommandConfig.ts new file mode 100644 index 000000000..148bd8054 --- /dev/null +++ b/packages-ts/starknet-gauntlet/src/commands/base/declareCommandConfig.ts @@ -0,0 +1,29 @@ +import { ExecuteCommandConfig } from '.' + +type UserInput = {} + +type ContractInput = [] + +const makeContractInput = async (input: UserInput): Promise => { + return [] +} + +const makeUserInput = async (flags, args): Promise => ({}) + +export const declareCommandConfig = ( + contractId: string, + category: string, + contractLoader: any, +): ExecuteCommandConfig => ({ + contractId, + category, + action: 'declare', + ux: { + description: 'Declares the contract', + examples: [`${contractId}:declare --network=`], + }, + makeUserInput, + makeContractInput, + validations: [], + loadContract: contractLoader, +}) diff --git a/packages-ts/starknet-gauntlet/src/commands/base/executeCommand.ts b/packages-ts/starknet-gauntlet/src/commands/base/executeCommand.ts index 38623726a..b94597ae9 100644 --- a/packages-ts/starknet-gauntlet/src/commands/base/executeCommand.ts +++ b/packages-ts/starknet-gauntlet/src/commands/base/executeCommand.ts @@ -1,8 +1,16 @@ import { Result, WriteCommand, BaseConfig } from '@chainlink/gauntlet-core' -import { CompiledContract, CompiledSierraCasm, Contract, Call, hash } from 'starknet' +import { + CompiledContract, + CompiledSierraCasm, + Contract, + Call, + hash, + DeclareContractResponse, +} from 'starknet' import { CommandCtor } from '.' -import { Dependencies, Env } from '../../dependencies' -import { IStarknetProvider, wrapResponse } from '../../provider' +import { Dependencies } from '../../dependencies' +import { IStarknetProvider } from '../../provider' +import { getRDD } from '../../rdd' import { TransactionResponse } from '../../transaction' import { IStarknetWallet } from '../../wallet' import { makeCommandId, Validation, Input } from './command' @@ -14,6 +22,7 @@ export interface ExecutionContext { provider: IStarknetProvider flags: any contract: Contract + rdd?: any } export type BeforeExecute = ( @@ -111,6 +120,12 @@ export const makeExecuteCommand = (config: ExecuteCommandConfig) contract: new Contract(c.contract.abi, c.contractAddress ?? '', c.provider.provider), } + const rdd = flags.rdd || process.env.RDD + if (rdd) { + deps.logger.info(`Using RDD from ${rdd}`) + c.executionContext.rdd = getRDD(rdd) + } + c.input = await c.buildCommandInput(flags, args, env) c.beforeExecute = config.hooks?.beforeExecute @@ -183,13 +198,28 @@ export const makeExecuteCommand = (config: ExecuteCommandConfig) await deps.prompt('Continue?') deps.logger.loading(`Sending transaction...`) - const tx = await this.provider.deployContract( - this.contract, - this.compiledContractHash, - this.input.contract, - false, - this.input?.user?.['salt'], - ) + // if "--classHash" is not included, declare before deploying + const classHash: string | undefined = this.input?.user?.['classHash'] + + let tx: TransactionResponse + + if (classHash === undefined) { + tx = await this.provider.declareAndDeployContract( + this.contract, + this.compiledContractHash, + this.input.contract, + false, + this.input?.user?.['salt'], + ) + } else { + tx = await this.provider.deployContract( + classHash, + this.input.contract, + false, + this.input?.user?.['salt'], + ) + } + if (tx.hash === undefined) { deps.logger.error(`No tx hash found:\n${JSON.stringify(tx, null, 2)}`) return tx @@ -202,6 +232,32 @@ export const makeExecuteCommand = (config: ExecuteCommandConfig) return tx } deps.logger.success(`Contract deployed on ${tx.hash} with address ${tx.address}`) + deps.logger.info( + `If using RDD, change the RDD ID with the new contract address: ${tx.address}`, + ) + return tx + } + + declareContract = async (): Promise => { + deps.logger.info(`Declaring contract ${config.category}`) + await deps.prompt('Continue?') + deps.logger.loading(`Sending transaction...`) + + const tx = await this.provider.declareContract( + this.contract, + this.compiledContractHash, + false, + ) + + deps.logger.loading(`Waiting for tx confirmation at ${tx.hash}...`) + const response = await tx.wait() + + if (!response.success) { + deps.logger.error(`Contract was not declared: ${tx.errorMessage}`) + return tx + } + + deps.logger.success(`Contract declared at ${tx.tx.class_hash}`) return tx } @@ -229,6 +285,8 @@ export const makeExecuteCommand = (config: ExecuteCommandConfig) if (config.action === 'deploy') { tx = await this.deployContract() + } else if (config.action === 'declare') { + tx = await this.declareContract() } else { tx = await this.executeWithSigner() } diff --git a/packages-ts/starknet-gauntlet/src/commands/base/index.ts b/packages-ts/starknet-gauntlet/src/commands/base/index.ts index cfccbce32..025ff2452 100644 --- a/packages-ts/starknet-gauntlet/src/commands/base/index.ts +++ b/packages-ts/starknet-gauntlet/src/commands/base/index.ts @@ -1,3 +1,5 @@ export * from './command' export * from './executeCommand' export * from './inspectionCommand' +export * from './upgradeCommandConfig' +export * from './declareCommandConfig' diff --git a/packages-ts/starknet-gauntlet/src/commands/base/upgradeCommandConfig.ts b/packages-ts/starknet-gauntlet/src/commands/base/upgradeCommandConfig.ts new file mode 100644 index 000000000..f0a0d2b2e --- /dev/null +++ b/packages-ts/starknet-gauntlet/src/commands/base/upgradeCommandConfig.ts @@ -0,0 +1,46 @@ +import { isValidAddress } from '../../utils' +import { ExecuteCommandConfig } from '.' + +type ContractInput = [classHash: string] + +export interface UserInput { + classHash: string +} + +const validateClassHash = async (input) => { + if (isValidAddress(input.classHash)) { + return true + } + throw new Error(`Invalid Class Hash: ${input.classHash}`) +} + +const makeUserInput = async (flags): Promise => { + if (flags.input) return flags.input as UserInput + return { + classHash: flags.classHash, + } +} + +const makeContractInput = async (input: UserInput): Promise => { + return [input.classHash] +} + +export const upgradeCommandConfig = ( + contractId: string, + category: string, + contractLoader: any, +): ExecuteCommandConfig => ({ + contractId, + category: contractId, + action: 'upgrade', + ux: { + description: 'Upgrades contract to new class hash', + examples: [ + `${contractId}:upgrade --network= --classHash= `, + ], + }, + makeUserInput, + makeContractInput, + validations: [validateClassHash], + loadContract: contractLoader, +}) diff --git a/packages-ts/starknet-gauntlet/src/index.ts b/packages-ts/starknet-gauntlet/src/index.ts index 971d2e2a2..7a6081683 100644 --- a/packages-ts/starknet-gauntlet/src/index.ts +++ b/packages-ts/starknet-gauntlet/src/index.ts @@ -13,3 +13,4 @@ export * from './events' export * from './utils' export * from './encoding' export * from './contract' +export * from './rdd' diff --git a/packages-ts/starknet-gauntlet/src/provider/index.ts b/packages-ts/starknet-gauntlet/src/provider/index.ts index 06fb4b00b..d6937380d 100644 --- a/packages-ts/starknet-gauntlet/src/provider/index.ts +++ b/packages-ts/starknet-gauntlet/src/provider/index.ts @@ -13,13 +13,24 @@ import { IStarknetWallet } from '../wallet' interface IProvider

{ provider: P send: () => Promise - deployContract: ( + declareAndDeployContract: ( contract: CompiledContract, compiledClassHash: string, input: any, wait?: boolean, salt?: number, ) => Promise + deployContract: ( + classHash: string, + input: any, + wait?: boolean, + salt?: number, + ) => Promise + declareContract: ( + contract: CompiledContract, + compiledClassHash?: string, + wait?: boolean, + ) => Promise signAndSend: (calls: Call[], wait?: boolean) => Promise } @@ -82,7 +93,12 @@ class Provider implements IStarknetProvider { return {} as TransactionResponse } - deployContract = async ( + /** + * Compiles the contract and declares it using the generated ABI. + * Then deploys an instance of the declared contract. + * If contract has already been declared it will only be deployed. + */ + declareAndDeployContract = async ( contract: CompiledContract, compiledClassHash?: string, input: any = [], @@ -104,6 +120,38 @@ class Provider implements IStarknetProvider { return response } + /** + * Compiles the contract and declares it using the generated ABI. + */ + declareContract = async (contract: CompiledContract, compiledClassHash?: string, wait = true) => { + const tx = await this.account.declare({ + contract, + compiledClassHash, + }) + + const response = wrapResponse(this, tx, 'not applicable for declares') + + if (!wait) return response + await response.wait() + return response + } + + /** + * Deploys a contract given a class hash + */ + deployContract = async (classHash: string, input: any = [], wait = true, salt = undefined) => { + const tx = await this.account.deployContract({ + classHash: classHash, + salt: salt ? '0x' + salt.toString(16) : salt, + ...(!!input && input.length > 0 && { constructorCalldata: input }), + }) + const response = wrapResponse(this, tx) + + if (!wait) return response + await response.wait() + return response + } + signAndSend = async (calls: Call[], wait = false) => { const tx = await this.account.execute(calls) const response = wrapResponse(this, tx) diff --git a/packages-ts/starknet-gauntlet/src/rdd.ts b/packages-ts/starknet-gauntlet/src/rdd.ts new file mode 100644 index 000000000..dc1868eb9 --- /dev/null +++ b/packages-ts/starknet-gauntlet/src/rdd.ts @@ -0,0 +1,21 @@ +import { existsSync, readFileSync } from 'fs' + +export enum CONTRACT_TYPES { + PROXY = 'proxies', + ACCESS_CONTROLLER = 'accessControllers', + AGGREGATOR = 'contracts', + VALIDATOR = 'validators', +} + +export const getRDD = (path: string): any => { + // test whether the file exists as a relative path or an absolute path + if (!existsSync(path)) { + throw new Error(`Could not find the RDD. Make sure you provided a valid $path`) + } + + try { + return JSON.parse(readFileSync(path, 'utf8')) + } catch (e) { + throw new Error(`An error ocurred while parsing the RDD. Make sure you provided a valid path`) + } +} diff --git a/packages-ts/starknet-gauntlet/test/encoding/encoding.test.ts b/packages-ts/starknet-gauntlet/test/encoding/encoding.test.ts index e9079b3e0..cd2730edc 100644 --- a/packages-ts/starknet-gauntlet/test/encoding/encoding.test.ts +++ b/packages-ts/starknet-gauntlet/test/encoding/encoding.test.ts @@ -1,4 +1,3 @@ -import BN from 'bn.js' import { num } from 'starknet' import { bytesToFelts, feltsToBytes } from '../../src/encoding' @@ -12,12 +11,19 @@ export function bytesToFeltsDeprecated(data: Uint8Array): string[] { // chunk every 31 bytes for (let i = 0; i < data.length; i += CHUNK_SIZE) { const chunk = data.slice(i, i + CHUNK_SIZE) - // cast to int - felts.push(new BN(chunk, 'be').toString()) + // convert big int to int (decimal) string + felts.push(bytesToBigInt(chunk).toString()) } return felts } +function bytesToBigInt(data: Uint8Array): bigint { + // convert byte array to hexadecimal string (pad by 2 so each byte is represented by 2 hex characters) + const feltHex = `0x${Array.from(data, (byte) => byte.toString(16).padStart(2, '0')).join('')}` + // convert hexadecimal string to bigint + return BigInt(feltHex) +} + function createUint8Array(len: number): Uint8Array { const ret: Uint8Array = new Uint8Array(len) for (let i = 1; i <= len; i++) { diff --git a/packages-ts/starknet/src/utils.ts b/packages-ts/starknet/src/utils.ts index d5a28673f..6bf736f85 100644 --- a/packages-ts/starknet/src/utils.ts +++ b/packages-ts/starknet/src/utils.ts @@ -1,4 +1,3 @@ -import { constants, encode, num } from 'starknet' import { expect } from 'chai' import { artifacts, network } from 'hardhat' diff --git a/relayer/go.mod b/relayer/go.mod index a81c0ca59..8c1996359 100644 --- a/relayer/go.mod +++ b/relayer/go.mod @@ -4,58 +4,79 @@ go 1.20 require ( github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 + github.com/ethereum/go-ethereum v1.11.5 github.com/pkg/errors v0.9.1 - github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230531014621-9c303da4c086 - github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3 - github.com/stretchr/testify v1.8.2 + github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230801204930-f46c3ccc7815 + github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1 + github.com/stretchr/testify v1.8.4 go.uber.org/zap v1.24.0 golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 ) require ( github.com/benbjohnson/clock v1.3.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/deckarep/golang-set/v2 v2.1.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect - github.com/ethereum/go-ethereum v1.11.5 // indirect - github.com/fatih/color v1.7.0 // indirect + github.com/fatih/color v1.13.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-stack/stack v1.8.1 // indirect github.com/gogo/protobuf v1.3.3 // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 // indirect github.com/hashicorp/go-hclog v0.14.1 // indirect - github.com/hashicorp/go-plugin v1.4.9 // indirect + github.com/hashicorp/go-plugin v1.4.10 // indirect github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb // indirect - github.com/holiman/uint256 v1.2.0 // indirect + github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.16 // indirect - github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/oklog/run v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/prometheus/client_golang v1.15.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.42.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/stretchr/objx v0.5.0 // indirect github.com/tklauser/go-sysconf v0.3.10 // indirect github.com/tklauser/numcpus v0.5.0 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 // indirect + go.opentelemetry.io/otel v1.16.0 // indirect + go.opentelemetry.io/otel/metric v1.16.0 // indirect + go.opentelemetry.io/otel/sdk v1.16.0 // indirect + go.opentelemetry.io/otel/trace v1.16.0 // indirect go.uber.org/atomic v1.10.0 // indirect - go.uber.org/multierr v1.9.0 // indirect - golang.org/x/crypto v0.7.0 // indirect - golang.org/x/net v0.8.0 // indirect - golang.org/x/sys v0.7.0 // indirect - golang.org/x/text v0.8.0 // indirect - google.golang.org/genproto v0.0.0-20230223222841-637eb2293923 // indirect - google.golang.org/grpc v1.53.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + golang.org/x/crypto v0.9.0 // indirect + golang.org/x/net v0.10.0 // indirect + golang.org/x/sys v0.8.0 // indirect + golang.org/x/text v0.9.0 // indirect + google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect + google.golang.org/grpc v1.55.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) -replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 +replace ( + github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 + + // until merged upstream: https://github.com/hashicorp/go-plugin/pull/257 + github.com/hashicorp/go-plugin => github.com/jmank88/go-plugin v0.0.0-20230604120638-7bb12ec27e75 +) diff --git a/relayer/go.sum b/relayer/go.sum index 544788b24..31b1bfc28 100644 --- a/relayer/go.sum +++ b/relayer/go.sum @@ -1,10 +1,47 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/btcsuite/btcd/btcec/v2 v2.2.1 h1:xP60mv8fvp+0khmrN0zTdPC3cNm24rfeE6lh2R/Yv3E= github.com/btcsuite/btcd/btcec/v2 v2.2.1/go.mod h1:9/CSmJxmuvqzX9Wh2fXMWToLOHhPd11lSPuIupwTkI8= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= @@ -12,8 +49,13 @@ github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtyd github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 h1:ytcWPaNPhNoGMWEhDvS3zToKcDpRsLuRolQJBVGdozk= @@ -30,72 +72,138 @@ github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ethereum/go-ethereum v1.11.5 h1:3M1uan+LAUvdn+7wCEFrcMM4LJTeuxDrPTg/f31a5QQ= github.com/ethereum/go-ethereum v1.11.5/go.mod h1:it7x0DWnTDMfVFdXcU6Ti4KEFQynLHVRarcSlPr0HBo= -github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0 h1:mdLirNAJBxnGgyB6pjZLcs6ue/6eZGBui6gXspfq4ks= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0/go.mod h1:kdXbOySqcQeTxiqglW7aahTmWZy3Pgi6SYL36yvKeyA= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 h1:o95KDiV/b1xdkumY5YbLR0/n2+wBxUpgf3HgfKgTyLI= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3/go.mod h1:hTxjzRcX49ogbTGVJ1sM5mz5s+SSgiGIyL3jjPxl32E= github.com/hashicorp/go-hclog v0.14.1 h1:nQcJDQwIAGnmoUWp8ubocEX40cCml/17YkF6csQLReU= github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-plugin v1.4.9 h1:ESiK220/qE0aGxWdzKIvRH69iLiuN/PjoLTm69RoWtU= -github.com/hashicorp/go-plugin v1.4.9/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= -github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM= -github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8= +github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= +github.com/jmank88/go-plugin v0.0.0-20230604120638-7bb12ec27e75 h1:KYTOmcwuezD27O7vNF15lj8H7imCBMXCq1RzCdj4e3A= +github.com/jmank88/go-plugin v0.0.0-20230604120638-7bb12ec27e75/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 h1:7GoSOOW2jpsfkntVKaS2rAr1TJqfcxotyaUcuxoZSzg= -github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249 h1:NHrXEjTNQY7P0Zfx1aMrNhpgxHmow66XQtm0aQLY0AE= @@ -107,32 +215,40 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= +github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e h1:XY8DncHICYQ1WDVpoXM7Tv3tztNHa1/DctDlSmqgU10= -github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230531014621-9c303da4c086 h1:d2WiCTnsCtA16KVabnX3E9SZH1irp2/d0MLT0/UI3XY= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230531014621-9c303da4c086/go.mod h1:zfUba6Okm7zTBxap24I78Vq9z+twHmjXSMBAl2C2Qgc= -github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3 h1:/Gel/U5eIZ/BGGr25OrHaXiVDTAJ5DYX5+UlXp3q7Gg= -github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3/go.mod h1:5JnCHuYgmIP9ZyXzgAfI5Iwu0WxBtBKp+ApeT5o1Cjw= +github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumvbfM1u/etVq42Afwq/jtNSBSOA8n5jntnNPo= +github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230801204930-f46c3ccc7815 h1:X8RMerGDjQKoEv7/jfh27egjye6yKmXBIf3iqwBLxsI= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230801204930-f46c3ccc7815/go.mod h1:MfZBUifutkv3aK7abyw5YmTJbqt8iFwcQDFikrxC/uI= +github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1 h1:caG9BWjnCxN/HPBA5ltDGadDraZAsjGIct4S8lh8D5c= +github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= @@ -140,103 +256,320 @@ github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hM github.com/tklauser/numcpus v0.5.0 h1:ooe7gN0fg6myJ0EKoTAf5hebTZrH52px3New/D9iJ+A= github.com/tklauser/numcpus v0.5.0/go.mod h1:OGzpTxpcIMNGYQdit2BYL1pvk/dSOaJWjKoflh+RQjo= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 h1:ZOLJc06r4CB42laIXg/7udr0pbZyuAihN10A/XuiQRY= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0/go.mod h1:5z+/ZWJQKXa9YT34fQNx5K8Hd1EoIhvtUygUQPqEOgQ= +go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= +go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= +go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= +go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= +go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= +go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= +go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= +go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= -go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= -go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= +go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o= golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20230223222841-637eb2293923 h1:znp6mq/drrY+6khTAlJUDNFFcDGV2ENLYKpMq8SyCds= -google.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc/examples v0.0.0-20210424002626-9572fd6faeae/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/relayer/pkg/chainlink/ocr2/client.go b/relayer/pkg/chainlink/ocr2/client.go index 8cc6bbad8..6548aa0af 100644 --- a/relayer/pkg/chainlink/ocr2/client.go +++ b/relayer/pkg/chainlink/ocr2/client.go @@ -2,14 +2,13 @@ package ocr2 import ( "context" - "encoding/json" "fmt" "math/big" "time" "github.com/pkg/errors" - caigogw "github.com/smartcontractkit/caigo/gateway" + caigorpc "github.com/smartcontractkit/caigo/rpcv02" caigotypes "github.com/smartcontractkit/caigo/types" "github.com/smartcontractkit/libocr/offchainreporting2/types" @@ -21,13 +20,13 @@ import ( //go:generate mockery --name OCR2Reader --output ./mocks/ type OCR2Reader interface { - LatestConfigDetails(context.Context, caigotypes.Hash) (ContractConfigDetails, error) - LatestTransmissionDetails(context.Context, caigotypes.Hash) (TransmissionDetails, error) - LatestRoundData(context.Context, caigotypes.Hash) (RoundData, error) - LinkAvailableForPayment(context.Context, caigotypes.Hash) (*big.Int, error) - ConfigFromEventAt(context.Context, caigotypes.Hash, uint64) (ContractConfig, error) - NewTransmissionsFromEventsAt(context.Context, caigotypes.Hash, uint64) ([]NewTransmissionEvent, error) - BillingDetails(context.Context, caigotypes.Hash) (BillingDetails, error) + LatestConfigDetails(context.Context, caigotypes.Felt) (ContractConfigDetails, error) + LatestTransmissionDetails(context.Context, caigotypes.Felt) (TransmissionDetails, error) + LatestRoundData(context.Context, caigotypes.Felt) (RoundData, error) + LinkAvailableForPayment(context.Context, caigotypes.Felt) (*big.Int, error) + ConfigFromEventAt(context.Context, caigotypes.Felt, uint64) (ContractConfig, error) + NewTransmissionsFromEventsAt(context.Context, caigotypes.Felt, uint64) ([]NewTransmissionEvent, error) + BillingDetails(context.Context, caigotypes.Felt) (BillingDetails, error) BaseReader() starknet.Reader } @@ -50,7 +49,7 @@ func (c *Client) BaseReader() starknet.Reader { return c.r } -func (c *Client) BillingDetails(ctx context.Context, address caigotypes.Hash) (bd BillingDetails, err error) { +func (c *Client) BillingDetails(ctx context.Context, address caigotypes.Felt) (bd BillingDetails, err error) { ops := starknet.CallOps{ ContractAddress: address, Selector: "billing", @@ -77,7 +76,7 @@ func (c *Client) BillingDetails(ctx context.Context, address caigotypes.Hash) (b return } -func (c *Client) LatestConfigDetails(ctx context.Context, address caigotypes.Hash) (ccd ContractConfigDetails, err error) { +func (c *Client) LatestConfigDetails(ctx context.Context, address caigotypes.Felt) (ccd ContractConfigDetails, err error) { ops := starknet.CallOps{ ContractAddress: address, Selector: "latest_config_details", @@ -104,7 +103,7 @@ func (c *Client) LatestConfigDetails(ctx context.Context, address caigotypes.Has return } -func (c *Client) LatestTransmissionDetails(ctx context.Context, address caigotypes.Hash) (td TransmissionDetails, err error) { +func (c *Client) LatestTransmissionDetails(ctx context.Context, address caigotypes.Felt) (td TransmissionDetails, err error) { ops := starknet.CallOps{ ContractAddress: address, Selector: "latest_transmission_details", @@ -126,7 +125,10 @@ func (c *Client) LatestTransmissionDetails(ctx context.Context, address caigotyp epoch, round := parseEpochAndRound(caigotypes.StrToFelt(res[1]).Big()) - latestAnswer := starknet.HexToSignedBig(res[2]) + latestAnswer, err := starknet.HexToUnsignedBig(res[2]) + if err != nil { + return td, errors.Wrap(err, "latestAnswer invalid") + } timestampFelt := caigotypes.StrToFelt(res[3]) // TODO: Int64() can return invalid data if int is too big @@ -144,7 +146,7 @@ func (c *Client) LatestTransmissionDetails(ctx context.Context, address caigotyp return td, nil } -func (c *Client) LatestRoundData(ctx context.Context, address caigotypes.Hash) (round RoundData, err error) { +func (c *Client) LatestRoundData(ctx context.Context, address caigotypes.Felt) (round RoundData, err error) { ops := starknet.CallOps{ ContractAddress: address, Selector: "latest_round_data", @@ -154,7 +156,7 @@ func (c *Client) LatestRoundData(ctx context.Context, address caigotypes.Hash) ( if err != nil { return round, errors.Wrap(err, "couldn't call the contract with selector latest_round_data") } - felts := []*caigotypes.Felt{} + felts := []caigotypes.Felt{} for _, result := range results { felts = append(felts, caigotypes.StrToFelt(result)) } @@ -166,7 +168,7 @@ func (c *Client) LatestRoundData(ctx context.Context, address caigotypes.Hash) ( return round, nil } -func (c *Client) LinkAvailableForPayment(ctx context.Context, address caigotypes.Hash) (*big.Int, error) { +func (c *Client) LinkAvailableForPayment(ctx context.Context, address caigotypes.Felt) (*big.Int, error) { results, err := c.r.CallContract(ctx, starknet.CallOps{ ContractAddress: address, Selector: "link_available_for_payment", @@ -177,33 +179,43 @@ func (c *Client) LinkAvailableForPayment(ctx context.Context, address caigotypes if len(results) != 1 { return nil, errors.Wrap(err, "insufficient data from selector 'link_available_for_payment'") } - return caigotypes.StrToFelt(results[0]).Big(), nil + return caigotypes.HexToBN(results[0]), nil } -func (c *Client) fetchEventsFromBlock(ctx context.Context, address caigotypes.Hash, eventType string, blockNum uint64) (eventsAsFeltArrs [][]*caigotypes.Felt, err error) { - block, err := c.r.BlockByNumberGateway(ctx, blockNum) - if err != nil { - return eventsAsFeltArrs, errors.Wrap(err, "couldn't fetch block by number") +func (c *Client) fetchEventsFromBlock(ctx context.Context, address caigotypes.Felt, eventType string, blockNum uint64) (eventsAsFeltArrs [][]caigotypes.Felt, err error) { + block := caigorpc.WithBlockNumber(blockNum) + + eventKey := caigotypes.BigToHex(caigotypes.GetSelectorFromName(eventType)) + + input := caigorpc.EventsInput{ + EventFilter: caigorpc.EventFilter{ + FromBlock: block, + ToBlock: block, + Address: address, + Keys: [][]string{{eventKey}}, // skip other event types + // PageSize: 0, + // PageNumber: 0, + }, + ResultPageRequest: caigorpc.ResultPageRequest{ + // ContinuationToken: , + ChunkSize: 10, + }, } + events, err := c.r.Events(ctx, input) - for _, txReceipt := range block.TransactionReceipts { - for _, event := range txReceipt.Events { - var decodedEvent caigogw.Event + // TODO: check events.isLastPage, query more if needed - m, err := json.Marshal(event) - if err != nil { - return eventsAsFeltArrs, errors.Wrap(err, "couldn't marshal event") - } - - err = json.Unmarshal(m, &decodedEvent) - if err != nil { - return eventsAsFeltArrs, errors.Wrap(err, "couldn't unmarshal event") - } + if err != nil { + return eventsAsFeltArrs, errors.Wrap(err, "couldn't fetch events for block") + } - if starknet.IsEventFromContract(&decodedEvent, address, eventType) { - eventsAsFeltArrs = append(eventsAsFeltArrs, decodedEvent.Data) - } + for _, event := range events.Events { + // convert to felts + felts := []caigotypes.Felt{} + for _, felt := range event.Data { + felts = append(felts, caigotypes.StrToFelt(felt)) } + eventsAsFeltArrs = append(eventsAsFeltArrs, felts) } if len(eventsAsFeltArrs) == 0 { return nil, errors.New("events not found in the block") @@ -211,7 +223,7 @@ func (c *Client) fetchEventsFromBlock(ctx context.Context, address caigotypes.Ha return eventsAsFeltArrs, nil } -func (c *Client) ConfigFromEventAt(ctx context.Context, address caigotypes.Hash, blockNum uint64) (cc ContractConfig, err error) { +func (c *Client) ConfigFromEventAt(ctx context.Context, address caigotypes.Felt, blockNum uint64) (cc ContractConfig, err error) { eventsAsFeltArrs, err := c.fetchEventsFromBlock(ctx, address, "ConfigSet", blockNum) if err != nil { return cc, errors.Wrap(err, "failed to fetch config_set events") @@ -231,7 +243,7 @@ func (c *Client) ConfigFromEventAt(ctx context.Context, address caigotypes.Hash, } // NewTransmissionsFromEventsAt finds events of type new_transmission emitted by the contract address in a given block number. -func (c *Client) NewTransmissionsFromEventsAt(ctx context.Context, address caigotypes.Hash, blockNum uint64) (events []NewTransmissionEvent, err error) { +func (c *Client) NewTransmissionsFromEventsAt(ctx context.Context, address caigotypes.Felt, blockNum uint64) (events []NewTransmissionEvent, err error) { eventsAsFeltArrs, err := c.fetchEventsFromBlock(ctx, address, "NewTransmission", blockNum) if err != nil { return nil, errors.Wrap(err, "failed to fetch new_transmission events") diff --git a/relayer/pkg/chainlink/ocr2/client_test.go b/relayer/pkg/chainlink/ocr2/client_test.go index ca2ff14a5..5e4c9aeb7 100644 --- a/relayer/pkg/chainlink/ocr2/client_test.go +++ b/relayer/pkg/chainlink/ocr2/client_test.go @@ -21,7 +21,7 @@ import ( "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/starknet" ) -const BLOCK_OUTPUT = `{"block_hash": "0x2", "block_number": 2, "parent_block_hash": "0x1", "sequencer_address": "0x4bbfb0d1aab5bf33eec5ada3a1040c41ed902a1eeb38c78a753d6f6359f1666", "transactions": [{"entry_point_type": "EXTERNAL", "transaction_hash": "0x2bb11daf4649bbadd51eb33a6890abb869e55c9d65f424e7ef74d34b543b914", "max_fee": "0x1713081b1e9400", "signature": ["0x2dd6147385d73e6a1b278863aa8be6b3c545a81810406807862c15aaae459b8", "0x1d072fdd6280d74c1e0788af5cc0f0169323167f04162a15660afe2e32425a6"], "calldata": ["0x1", "0xd43963a4e875a361f5d164b2e70953598eb4f45fde86924082d51b4d78e489", "0x2f09d463867ebc70075969cdd4d3c0643f9b69dbc84bf9bf96923a52dc3c8d8", "0x0", "0x22", "0x22", "0x4", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603730", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603734", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603731", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603735", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603732", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603736", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603733", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603737", "0x1", "0x0", "0x2", "0x15", "0x263", "0x880a0d9e61d1080d88ee16f1880bcc1960b2080cab5ee01288090dfc04a30", "0x53a0201024220af400004fa5d02cd5170b5261032e71f2847ead36159cf8d", "0xee68affc3c8520904220af400004fa5d02cd5170b5261032e71f2847ead361", "0x59cf8dee68affc3c8520914220af400004fa5d02cd5170b5261032e71f2847", "0xead36159cf8dee68affc3c8520924220af400004fa5d02cd5170b5261032e7", "0x1f2847ead36159cf8dee68affc3c8520934a42307830346363316266613939", "0x65323832653433346165663238313563613137333337613932336364326336", "0x31636630633764653562333236643761383630333733304a42307830346363", "0x31626661393965323832653433346165663238313563613137333337613932", "0x33636432633631636630633764653562333236643761383630333733314a42", "0x30783034636331626661393965323832653433346165663238313563613137", "0x33333761393233636432633631636630633764653562333236643761383630", "0x333733324a4230783034636331626661393965323832653433346165663238", "0x31356361313733333761393233636432633631636630633764653562333236", "0x643761383630333733335200608094ebdc03688084af5f708084af5f788084", "0xaf5f82018c010a202ac49e648a1f84da5a143eeab68c8402c65a1567e63971", "0x7f5732d5e6310c2c761220a6c1ae85186dc981dc61cd14d7511ee5ab70258a", "0x10ac4e03e4d4991761b2c0a61a1090696dc7afed7f61a26887e78e683a1c1a", "0x10a29e5fa535f2edea7afa9acb4fd349b31a10d1b88713982955d79fa0e422", "0x685a748b1a10a07e0118cc38a71d2a9d60bf52938b4a", "0x0"], "contract_address": "0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a", "entry_point_selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", "type": "INVOKE_FUNCTION"}], "starknet_version": "0.9.1", "transaction_receipts": [{"transaction_hash": "0x2bb11daf4649bbadd51eb33a6890abb869e55c9d65f424e7ef74d34b543b914", "actual_fee": "0xf62056769b800", "transaction_index": 0, "l2_to_l1_messages": [], "execution_resources": {"builtin_instance_counter": {"pedersen_builtin": 69, "range_check_builtin": 97, "ecdsa_builtin": 1, "bitwise_builtin": 1, "output_builtin": 0}, "n_steps": 3432, "n_memory_holes": 326}, "events": [{"from_address": "0xd43963a4e875a361f5d164b2e70953598eb4f45fde86924082d51b4d78e489", "keys": ["0x9a144bf4a6a8fd083c93211e163e59221578efcc86b93f8c97c620e7b9608a"], "data": ["0x0", "0x4b791b801cf0d7b6a2f9e59daf15ec2dd7d9cdc3bc5e037bada9c86e4821c", "0x1", "0x4", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603730", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603734", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603731", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603735", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603732", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603736", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603733", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603737", "0x1", "0x3", "0x1", "0x0", "0xf4240", "0x2", "0x15", "0x263", "0x880a0d9e61d1080d88ee16f1880bcc1960b2080cab5ee01288090dfc04a30", "0x53a0201024220af400004fa5d02cd5170b5261032e71f2847ead36159cf8d", "0xee68affc3c8520904220af400004fa5d02cd5170b5261032e71f2847ead361", "0x59cf8dee68affc3c8520914220af400004fa5d02cd5170b5261032e71f2847", "0xead36159cf8dee68affc3c8520924220af400004fa5d02cd5170b5261032e7", "0x1f2847ead36159cf8dee68affc3c8520934a42307830346363316266613939", "0x65323832653433346165663238313563613137333337613932336364326336", "0x31636630633764653562333236643761383630333733304a42307830346363", "0x31626661393965323832653433346165663238313563613137333337613932", "0x33636432633631636630633764653562333236643761383630333733314a42", "0x30783034636331626661393965323832653433346165663238313563613137", "0x33333761393233636432633631636630633764653562333236643761383630", "0x333733324a4230783034636331626661393965323832653433346165663238", "0x31356361313733333761393233636432633631636630633764653562333236", "0x643761383630333733335200608094ebdc03688084af5f708084af5f788084", "0xaf5f82018c010a202ac49e648a1f84da5a143eeab68c8402c65a1567e63971", "0x7f5732d5e6310c2c761220a6c1ae85186dc981dc61cd14d7511ee5ab70258a", "0x10ac4e03e4d4991761b2c0a61a1090696dc7afed7f61a26887e78e683a1c1a", "0x10a29e5fa535f2edea7afa9acb4fd349b31a10d1b88713982955d79fa0e422", "0x685a748b1a10a07e0118cc38a71d2a9d60bf52938b4a"]}]}], "gas_price": "0x174876e800", "state_root": "0000000000000000000000000000000000000000000000000000000000000000", "status": "ACCEPTED_ON_L2", "timestamp": 1664483024}` +const BLOCK_OUTPUT = `{"result": {"events": [ {"from_address": "0xd43963a4e875a361f5d164b2e70953598eb4f45fde86924082d51b4d78e489", "keys": ["0x9a144bf4a6a8fd083c93211e163e59221578efcc86b93f8c97c620e7b9608a"], "data": ["0x0", "0x4b791b801cf0d7b6a2f9e59daf15ec2dd7d9cdc3bc5e037bada9c86e4821c", "0x1", "0x4", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603730", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603734", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603731", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603735", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603732", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603736", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603733", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603737", "0x1", "0x3", "0x1", "0x0", "0xf4240", "0x2", "0x15", "0x263", "0x880a0d9e61d1080d88ee16f1880bcc1960b2080cab5ee01288090dfc04a30", "0x53a0201024220af400004fa5d02cd5170b5261032e71f2847ead36159cf8d", "0xee68affc3c8520904220af400004fa5d02cd5170b5261032e71f2847ead361", "0x59cf8dee68affc3c8520914220af400004fa5d02cd5170b5261032e71f2847", "0xead36159cf8dee68affc3c8520924220af400004fa5d02cd5170b5261032e7", "0x1f2847ead36159cf8dee68affc3c8520934a42307830346363316266613939", "0x65323832653433346165663238313563613137333337613932336364326336", "0x31636630633764653562333236643761383630333733304a42307830346363", "0x31626661393965323832653433346165663238313563613137333337613932", "0x33636432633631636630633764653562333236643761383630333733314a42", "0x30783034636331626661393965323832653433346165663238313563613137", "0x33333761393233636432633631636630633764653562333236643761383630", "0x333733324a4230783034636331626661393965323832653433346165663238", "0x31356361313733333761393233636432633631636630633764653562333236", "0x643761383630333733335200608094ebdc03688084af5f708084af5f788084", "0xaf5f82018c010a202ac49e648a1f84da5a143eeab68c8402c65a1567e63971", "0x7f5732d5e6310c2c761220a6c1ae85186dc981dc61cd14d7511ee5ab70258a", "0x10ac4e03e4d4991761b2c0a61a1090696dc7afed7f61a26887e78e683a1c1a", "0x10a29e5fa535f2edea7afa9acb4fd349b31a10d1b88713982955d79fa0e422", "0x685a748b1a10a07e0118cc38a71d2a9d60bf52938b4a"]}]}}` const ocr2ContractAddress = "0xd43963a4e875a361f5d164b2e70953598eb4f45fde86924082d51b4d78e489" // matches BLOCK_OUTPUT event func TestOCR2Client(t *testing.T) { @@ -35,32 +35,50 @@ func TestOCR2Client(t *testing.T) { var out []byte switch { - case r.RequestURI == "/feeder_gateway/call_contract?blockNumber=pending": + case r.RequestURI == "/": type Request struct { Selector string `json:"entry_point_selector"` } + type Call struct { + Method string `json:"method"` + Params []json.RawMessage `json:"params"` + } - reqdata := Request{} - require.NoError(t, json.Unmarshal(req, &reqdata)) - - switch { - case caigotypes.BigToHex(caigotypes.GetSelectorFromName("billing")) == reqdata.Selector: - // billing response - out = []byte(`{"result":["0x0","0x0","0x0","0x0"]}`) - case caigotypes.BigToHex(caigotypes.GetSelectorFromName("latest_config_details")) == reqdata.Selector: - // latest config details response - out = []byte(`{"result":["0x1","0x2","0x4b791b801cf0d7b6a2f9e59daf15ec2dd7d9cdc3bc5e037bada9c86e4821c"]}`) - case caigotypes.BigToHex(caigotypes.GetSelectorFromName("latest_transmission_details")) == reqdata.Selector: - // latest transmission details response - out = []byte(`{"result":["0x4cfc96325fa7d72e4854420e2d7b0abda72de17d45e4c3c0d9f626016d669","0x0","0x0","0x0"]}`) - case caigotypes.BigToHex(caigotypes.GetSelectorFromName("latest_round_data")) == reqdata.Selector: - // latest transmission details response - out = []byte(`{"result":["0x0","0x0","0x0","0x0","0x0"]}`) - case caigotypes.BigToHex(caigotypes.GetSelectorFromName("link_available_for_payment")) == reqdata.Selector: - // latest transmission details response - out = []byte(`{"result":["0x0"]}`) + call := Call{} + require.NoError(t, json.Unmarshal(req, &call)) + + switch call.Method { + case "starknet_chainId": + out = []byte(`{"result":"0x534e5f4d41494e"}`) + case "starknet_call": + raw := call.Params[0] + reqdata := Request{} + err := json.Unmarshal([]byte(raw), &reqdata) + require.NoError(t, err) + + switch { + case caigotypes.BigToHex(caigotypes.GetSelectorFromName("billing")) == reqdata.Selector: + // billing response + out = []byte(`{"result":["0x0","0x0","0x0","0x0"]}`) + case caigotypes.BigToHex(caigotypes.GetSelectorFromName("latest_config_details")) == reqdata.Selector: + // latest config details response + out = []byte(`{"result":["0x1","0x2","0x4b791b801cf0d7b6a2f9e59daf15ec2dd7d9cdc3bc5e037bada9c86e4821c"]}`) + case caigotypes.BigToHex(caigotypes.GetSelectorFromName("latest_transmission_details")) == reqdata.Selector: + // latest transmission details response + out = []byte(`{"result":["0x4cfc96325fa7d72e4854420e2d7b0abda72de17d45e4c3c0d9f626016d669","0x0","0x0","0x0"]}`) + case caigotypes.BigToHex(caigotypes.GetSelectorFromName("latest_round_data")) == reqdata.Selector: + // latest transmission details response + out = []byte(`{"result":["0x0","0x0","0x0","0x0","0x0"]}`) + case caigotypes.BigToHex(caigotypes.GetSelectorFromName("link_available_for_payment")) == reqdata.Selector: + // latest transmission details response + out = []byte(`{"result":["0x0"]}`) + default: + require.False(t, true, "unsupported contract method") + } + case "starknet_getEvents": + out = []byte(BLOCK_OUTPUT) default: - require.False(t, true, "unsupported contract method") + require.False(t, true, "unsupported RPC method") } case strings.Contains(r.RequestURI, "/feeder_gateway/get_block"): out = []byte(BLOCK_OUTPUT) @@ -80,7 +98,7 @@ func TestOCR2Client(t *testing.T) { client, err := NewClient(reader, lggr) assert.NoError(t, err) - contractAddress := caigotypes.HexToHash(ocr2ContractAddress) + contractAddress := caigotypes.StrToFelt(ocr2ContractAddress) t.Run("get billing details", func(t *testing.T) { billing, err := client.BillingDetails(context.Background(), contractAddress) diff --git a/relayer/pkg/chainlink/ocr2/config_digester_test.go b/relayer/pkg/chainlink/ocr2/config_digester_test.go index 3cab6f0ed..4ebdef320 100644 --- a/relayer/pkg/chainlink/ocr2/config_digester_test.go +++ b/relayer/pkg/chainlink/ocr2/config_digester_test.go @@ -29,7 +29,7 @@ var testConfig = types.ContractConfig{ F: 1, OnchainConfig: []byte{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // version - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 246, // min (-1) + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // min (1) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 154, 202, 0, // max (1000000000) }, OffchainConfigVersion: 2, @@ -44,7 +44,7 @@ func TestConfigDigester(t *testing.T) { digest, err := d.ConfigDigest(testConfig) assert.NoError(t, err) - assert.Equal(t, "0004d46ed94aa1a4bfa938170a3df74f5b286498a411f59fe5be4d00b6eef12d", digest.Hex()) + assert.Equal(t, "00047843e1622a4462e1209c9f8559ba43cbf43bf238da490f3b9c8e33f3419e", digest.Hex()) } func TestConfigDigester_InvalidChainID(t *testing.T) { diff --git a/relayer/pkg/chainlink/ocr2/contract_reader.go b/relayer/pkg/chainlink/ocr2/contract_reader.go index 3adcab9f0..0a433bdf4 100644 --- a/relayer/pkg/chainlink/ocr2/contract_reader.go +++ b/relayer/pkg/chainlink/ocr2/contract_reader.go @@ -21,14 +21,14 @@ type Reader interface { var _ Reader = (*contractReader)(nil) type contractReader struct { - address caigotypes.Hash + address caigotypes.Felt reader OCR2Reader lggr logger.Logger } func NewContractReader(address string, reader OCR2Reader, lggr logger.Logger) Reader { return &contractReader{ - address: caigotypes.HexToHash(address), // TODO: propagate type everywhere + address: caigotypes.StrToFelt(address), // TODO: propagate type everywhere reader: reader, lggr: lggr, } diff --git a/relayer/pkg/chainlink/ocr2/contract_transmitter.go b/relayer/pkg/chainlink/ocr2/contract_transmitter.go index 10976cfbb..88c50d96a 100644 --- a/relayer/pkg/chainlink/ocr2/contract_transmitter.go +++ b/relayer/pkg/chainlink/ocr2/contract_transmitter.go @@ -20,9 +20,9 @@ var _ types.ContractTransmitter = (*contractTransmitter)(nil) type contractTransmitter struct { reader *transmissionsCache - contractAddress caigotypes.Hash - senderAddress caigotypes.Hash - accountAddress caigotypes.Hash + contractAddress caigotypes.Felt + senderAddress caigotypes.Felt + accountAddress caigotypes.Felt txm txm.TxManager } @@ -36,9 +36,9 @@ func NewContractTransmitter( ) *contractTransmitter { return &contractTransmitter{ reader: reader, - contractAddress: caigotypes.HexToHash(contractAddress), - senderAddress: caigotypes.HexToHash(senderAddress), - accountAddress: caigotypes.HexToHash(accountAddress), + contractAddress: caigotypes.StrToFelt(contractAddress), + senderAddress: caigotypes.StrToFelt(senderAddress), + accountAddress: caigotypes.StrToFelt(accountAddress), txm: txm, } } diff --git a/relayer/pkg/chainlink/ocr2/events.go b/relayer/pkg/chainlink/ocr2/events.go index 38c04624a..1be0c6660 100644 --- a/relayer/pkg/chainlink/ocr2/events.go +++ b/relayer/pkg/chainlink/ocr2/events.go @@ -1,7 +1,6 @@ package ocr2 import ( - "encoding/hex" "math/big" "time" @@ -27,7 +26,7 @@ var ( type NewTransmissionEvent struct { RoundId uint32 LatestAnswer *big.Int - Transmitter *caigotypes.Felt + Transmitter caigotypes.Felt LatestTimestamp time.Time Observers []uint8 ObservationsLen uint32 @@ -41,7 +40,7 @@ type NewTransmissionEvent struct { } // ParseNewTransmissionEvent is decoding binary felt data as the NewTransmissionEvent type -func ParseNewTransmissionEvent(eventData []*caigotypes.Felt) (NewTransmissionEvent, error) { +func ParseNewTransmissionEvent(eventData []caigotypes.Felt) (NewTransmissionEvent, error) { { const observationsLenIndex = 5 const constNumOfElements = 11 @@ -50,7 +49,7 @@ func ParseNewTransmissionEvent(eventData []*caigotypes.Felt) (NewTransmissionEve return NewTransmissionEvent{}, errors.New("invalid: event data") } - observationsLen := eventData[observationsLenIndex].Uint64() + observationsLen := eventData[observationsLenIndex].Big().Uint64() if len(eventData) != constNumOfElements+int(observationsLen) { return NewTransmissionEvent{}, errors.New("invalid: event data") } @@ -58,11 +57,14 @@ func ParseNewTransmissionEvent(eventData []*caigotypes.Felt) (NewTransmissionEve // round_id index := 0 - roundId := uint32(eventData[index].Uint64()) + roundId := uint32(eventData[index].Big().Uint64()) // answer index++ - latestAnswer := starknet.HexToSignedBig(eventData[index].String()) + latestAnswer, err := starknet.HexToUnsignedBig(eventData[index].String()) + if err != nil { + return NewTransmissionEvent{}, errors.Wrap(err, "latestAnswer invalid") + } // transmitter index++ @@ -70,7 +72,7 @@ func ParseNewTransmissionEvent(eventData []*caigotypes.Felt) (NewTransmissionEve // observation_timestamp index++ - unixTime := eventData[index].Int64() + unixTime := eventData[index].Big().Int64() latestTimestamp := time.Unix(unixTime, 0) // observers (raw) max 31 @@ -79,7 +81,7 @@ func ParseNewTransmissionEvent(eventData []*caigotypes.Felt) (NewTransmissionEve // observation_len index++ - observationsLen := uint32(eventData[index].Uint64()) + observationsLen := uint32(eventData[index].Big().Uint64()) // observers (based on observationsLen) var observers []uint8 @@ -134,28 +136,28 @@ func ParseNewTransmissionEvent(eventData []*caigotypes.Felt) (NewTransmissionEve } // ParseConfigSetEvent is decoding binary felt data as the libocr ContractConfig type -func ParseConfigSetEvent(eventData []*caigotypes.Felt) (types.ContractConfig, error) { +func ParseConfigSetEvent(eventData []caigotypes.Felt) (types.ContractConfig, error) { { const oraclesLenIdx = 3 if len(eventData) < oraclesLenIdx { return types.ContractConfig{}, errors.New("invalid: event data") } - oraclesLen := eventData[oraclesLenIdx].Uint64() + oraclesLen := eventData[oraclesLenIdx].Big().Uint64() onchainConfigLenIdx := oraclesLenIdx + 2*oraclesLen + 2 if uint64(len(eventData)) < onchainConfigLenIdx { return types.ContractConfig{}, errors.New("invalid: event data") } - onchainConfigLen := eventData[onchainConfigLenIdx].Uint64() + onchainConfigLen := eventData[onchainConfigLenIdx].Big().Uint64() offchainConfigLenIdx := onchainConfigLenIdx + onchainConfigLen + 2 if uint64(len(eventData)) < offchainConfigLenIdx { return types.ContractConfig{}, errors.New("invalid: event data") } - offchainConfigLen := eventData[offchainConfigLenIdx].Uint64() + offchainConfigLen := eventData[offchainConfigLenIdx].Big().Uint64() if uint64(len(eventData)) != offchainConfigLenIdx+offchainConfigLen+1 { return types.ContractConfig{}, errors.New("invalid: event data") } @@ -173,11 +175,11 @@ func ParseConfigSetEvent(eventData []*caigotypes.Felt) (types.ContractConfig, er // config_count index++ - configCount := eventData[index].Uint64() + configCount := eventData[index].Big().Uint64() // oracles_len index++ - oraclesLen := eventData[index].Uint64() + oraclesLen := eventData[index].Big().Uint64() // oracles index++ @@ -188,17 +190,17 @@ func ParseConfigSetEvent(eventData []*caigotypes.Felt) (types.ContractConfig, er if i%2 == 0 { signers = append(signers, starknet.PadBytes(member.Bytes(), 32)) // pad to 32 bytes } else { - transmitters = append(transmitters, types.Account("0x"+hex.EncodeToString(starknet.PadBytes(member.Bytes(), 32)))) // pad to 32 byte length then re-encode + transmitters = append(transmitters, types.Account(member.String())) } } // f index = index + int(oraclesLen)*2 - f := eventData[index].Uint64() + f := eventData[index].Big().Uint64() // onchain_config length index++ - onchainConfigLen := eventData[index].Uint64() + onchainConfigLen := eventData[index].Big().Uint64() // onchain_config (version=1, min, max) index++ @@ -214,16 +216,15 @@ func ParseConfigSetEvent(eventData []*caigotypes.Felt) (types.ContractConfig, er // offchain_config_version index += int(onchainConfigLen) - offchainConfigVersion := eventData[index].Uint64() + offchainConfigVersion := eventData[index].Big().Uint64() // offchain_config_len index++ - offchainConfigLen := eventData[index].Uint64() + offchainConfigLen := eventData[index].Big().Uint64() // offchain_config index++ offchainConfigFelts := eventData[index:(index + int(offchainConfigLen))] - // todo: get rid of caigoToJuno workaround offchainConfig, err := starknet.DecodeFelts(starknet.FeltsToBig(offchainConfigFelts)) if err != nil { return types.ContractConfig{}, errors.Wrap(err, "couldn't decode offchain config") diff --git a/relayer/pkg/chainlink/ocr2/events_test.go b/relayer/pkg/chainlink/ocr2/events_test.go index 521e2d031..52f53590f 100644 --- a/relayer/pkg/chainlink/ocr2/events_test.go +++ b/relayer/pkg/chainlink/ocr2/events_test.go @@ -33,7 +33,7 @@ var ( "0x1", "0x485341c18461d70eac6ded4b8b17147f173308ddd56216a86f9ec4d994453", "0x1", - "0x0", + "0x1", } configSetEventRaw = []string{ "0x0", @@ -51,7 +51,7 @@ var ( "0x1", "0x3", "0x1", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffff7", + "0xa", "0x3b9aca00", "0x2", "0x2", @@ -73,14 +73,16 @@ func TestNewTransmissionEvent_Parse(t *testing.T) { require.Equal(t, e.LatestTimestamp, time.Unix(1, 0)) require.Equal(t, e.Epoch, uint32(0)) require.Equal(t, e.Round, uint8(1)) - require.Equal(t, e.Reimbursement, big.NewInt(0)) + require.Equal(t, e.Reimbursement, big.NewInt(1)) require.Equal(t, e.JuelsPerFeeCoin, big.NewInt(1)) require.Equal(t, e.GasPrice, big.NewInt(1)) transmitterHex := "0x2c0dd77ce74b1667dc6fa782bbafaef5becbe2d04b052726ab236daeb52ac5d" require.Equal(t, len(transmitterHex), int(2+31.5*2)) // len('0x') + len(max_felt_len) - require.Equal(t, e.Transmitter, caigotypes.StrToFelt(transmitterHex)) + + expectedTransmitter := caigotypes.StrToFelt(transmitterHex) + require.Equal(t, e.Transmitter, expectedTransmitter) require.Equal(t, e.Observers, []uint8{0, 1, 2, 3}) require.Equal(t, e.ObservationsLen, uint32(4)) @@ -115,19 +117,19 @@ func TestConfigSetEvent_Parse(t *testing.T) { require.Equal(t, e.Signers, signersExpected) transmittersExpected := []types.Account{ - "0x02c0dd77ce74b1667dc6fa782bbafaef5becbe2d04b052726ab236daeb52ac5d", - "0x02de61335d8f1caa7e9df54486f016ded83d0e02fde4c12280f4b898720b0e2b", - "0x02f14e18cc198dd5133c8a9aa92992fc1a462f703401716f402d0ee383b54faa", - "0x05c35686f78db31d9d896bb425b3fd99be19019f8aeaf0f7a8767867903341d4", + "0x2c0dd77ce74b1667dc6fa782bbafaef5becbe2d04b052726ab236daeb52ac5d", + "0x2de61335d8f1caa7e9df54486f016ded83d0e02fde4c12280f4b898720b0e2b", + "0x2f14e18cc198dd5133c8a9aa92992fc1a462f703401716f402d0ee383b54faa", + "0x5c35686f78db31d9d896bb425b3fd99be19019f8aeaf0f7a8767867903341d4", } require.Equal(t, e.Transmitters, transmittersExpected) require.Equal(t, len(e.Transmitters), oraclesLen) require.Equal(t, e.F, uint8(1)) - onchainConfig, err := medianreport.OnchainConfigCodec{}.EncodeFromBigInt( + onchainConfig, err := medianreport.OnchainConfigCodec{}.EncodeFromFelt( big.NewInt(medianreport.OnchainConfigVersion), // version - big.NewInt(-10), // min + big.NewInt(10), // min big.NewInt(1000000000), // max ) assert.NoError(t, err) diff --git a/relayer/pkg/chainlink/ocr2/medianreport/onchainconfig.go b/relayer/pkg/chainlink/ocr2/medianreport/onchainconfig.go index 45126bd24..4ea4a9f67 100644 --- a/relayer/pkg/chainlink/ocr2/medianreport/onchainconfig.go +++ b/relayer/pkg/chainlink/ocr2/medianreport/onchainconfig.go @@ -4,10 +4,10 @@ import ( "fmt" "math/big" + "github.com/pkg/errors" "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/starknet" caigotypes "github.com/smartcontractkit/caigo/types" - "github.com/smartcontractkit/libocr/bigbigendian" "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" ) @@ -32,31 +32,20 @@ func (codec OnchainConfigCodec) DecodeToFelts(b []byte) ([]*big.Int, error) { return []*big.Int{}, fmt.Errorf("unexpected length of OnchainConfig, expected %v, got %v", length, len(b)) } - configVersion, err := bigbigendian.DeserializeSigned(byteWidth, b[:32]) - if err != nil { - return []*big.Int{}, fmt.Errorf("unable to decode version: %s", err) - } + // convert from bytes to *big.Int + configVersion := new(big.Int).SetBytes(b[:32]) + if OnchainConfigVersion != configVersion.Int64() { return []*big.Int{}, fmt.Errorf("unexpected version of OnchainConfig, expected %v, got %v", OnchainConfigVersion, configVersion.Int64()) } - min, err := bigbigendian.DeserializeSigned(byteWidth, b[byteWidth:2*byteWidth]) - if err != nil { - return []*big.Int{}, err - } - max, err := bigbigendian.DeserializeSigned(byteWidth, b[2*byteWidth:]) - if err != nil { - return []*big.Int{}, err - } - - // ensure felts (used in config digester) - min = starknet.SignedBigToFelt(min) - max = starknet.SignedBigToFelt(max) + min := new(big.Int).SetBytes(b[byteWidth : 2*byteWidth]) + max := new(big.Int).SetBytes(b[2*byteWidth:]) return []*big.Int{configVersion, min, max}, nil } -// Decode converts the onchainconfig via the outputs of DecodeToFelts into signed big.Ints that libocr expects +// Decode converts the onchainconfig via the outputs of DecodeToFelts into unsigned big.Ints that libocr expects func (codec OnchainConfigCodec) Decode(b []byte) (median.OnchainConfig, error) { felts, err := codec.DecodeToFelts(b) if err != nil { @@ -64,8 +53,16 @@ func (codec OnchainConfigCodec) Decode(b []byte) (median.OnchainConfig, error) { } // convert felts to big.Ints - min := starknet.FeltToSignedBig(&caigotypes.Felt{Int: felts[1]}) - max := starknet.FeltToSignedBig(&caigotypes.Felt{Int: felts[2]}) + + min, err := starknet.FeltToUnsignedBig(caigotypes.BigToFelt(felts[1])) + if err != nil { + return median.OnchainConfig{}, errors.Wrap(err, "min invalid") + } + + max, err := starknet.FeltToUnsignedBig(caigotypes.BigToFelt(felts[2])) + if err != nil { + return median.OnchainConfig{}, errors.Wrap(err, "max invalid") + } if !(min.Cmp(max) <= 0) { return median.OnchainConfig{}, fmt.Errorf("OnchainConfig min (%v) should not be greater than max(%v)", min, max) @@ -74,42 +71,29 @@ func (codec OnchainConfigCodec) Decode(b []byte) (median.OnchainConfig, error) { return median.OnchainConfig{Min: min, Max: max}, nil } -// TODO: both 'EncodeFromBigInt' and 'EncodeFromFelt' have the same signature - we need a custom type to represent Felts -// EncodeFromBigInt encodes the config where min & max are big Ints with positive or negative values -func (codec OnchainConfigCodec) EncodeFromBigInt(version, min, max *big.Int) ([]byte, error) { - return codec.EncodeFromFelt(version, starknet.SignedBigToFelt(min), starknet.SignedBigToFelt(max)) -} - // EncodeFromFelt encodes the config where min & max are big.Int representations of a felt -// Cairo has no notion of signed values: negative values have to be wrapped into the upper half of PRIME (so 0 to PRIME/2 is positive, PRIME/2 to PRIME is negative) +// Cairo has no notion of signed values: min and max values will be non-negative func (codec OnchainConfigCodec) EncodeFromFelt(version, min, max *big.Int) ([]byte, error) { if version.Uint64() != OnchainConfigVersion { return nil, fmt.Errorf("unexpected version of OnchainConfig, expected %v, got %v", OnchainConfigVersion, version.Int64()) } - versionBytes, err := bigbigendian.SerializeSigned(byteWidth, version) - if err != nil { - return nil, err + if min.Sign() == -1 || max.Sign() == -1 { + return nil, fmt.Errorf("starknet does not support negative values: min = (%v) and max = (%v)", min, max) } - minBytes, err := bigbigendian.SerializeSigned(byteWidth, min) - if err != nil { - return nil, err - } - - maxBytes, err := bigbigendian.SerializeSigned(byteWidth, max) - if err != nil { - return nil, err - } result := []byte{} - result = append(result, versionBytes...) - result = append(result, minBytes...) - result = append(result, maxBytes...) + versionBytes := make([]byte, byteWidth) + minBytes := make([]byte, byteWidth) + maxBytes := make([]byte, byteWidth) + result = append(result, version.FillBytes(versionBytes)...) + result = append(result, min.FillBytes(minBytes)...) + result = append(result, max.FillBytes(maxBytes)...) return result, nil } -// Encode takes the interface that libocr uses (+/- big.Ints) and serializes it into 3 felts +// Encode takes the interface that libocr uses (big.Ints) and serializes it into 3 felts func (codec OnchainConfigCodec) Encode(c median.OnchainConfig) ([]byte, error) { - return codec.EncodeFromBigInt(big.NewInt(OnchainConfigVersion), c.Min, c.Max) + return codec.EncodeFromFelt(big.NewInt(OnchainConfigVersion), c.Min, c.Max) } diff --git a/relayer/pkg/chainlink/ocr2/medianreport/onchainconfig_test.go b/relayer/pkg/chainlink/ocr2/medianreport/onchainconfig_test.go index 37d2d7fef..9591c1c21 100644 --- a/relayer/pkg/chainlink/ocr2/medianreport/onchainconfig_test.go +++ b/relayer/pkg/chainlink/ocr2/medianreport/onchainconfig_test.go @@ -21,30 +21,20 @@ func TestOnchainConfigCodec(t *testing.T) { expectErr: false, }, { - name: "negative min < positive max", - val: []*big.Int{big.NewInt(-1000), big.NewInt(1000)}, + name: "0 < positive max", + val: []*big.Int{big.NewInt(0), big.NewInt(1000)}, expectErr: false, }, { - name: "negative min < negative max", - val: []*big.Int{big.NewInt(-1000), big.NewInt(-1)}, - expectErr: false, + name: "positive max < 0", + val: []*big.Int{big.NewInt(1000), big.NewInt(0)}, + expectErr: true, }, { name: "positive min > positive max", val: []*big.Int{big.NewInt(1000), big.NewInt(1)}, expectErr: true, }, - { - name: "negative min > negative max", - val: []*big.Int{big.NewInt(-1), big.NewInt(-1000)}, - expectErr: true, - }, - { - name: "positive min > negative max", - val: []*big.Int{big.NewInt(1), big.NewInt(-1000)}, - expectErr: true, - }, { name: "min = max", val: []*big.Int{big.NewInt(0), big.NewInt(0)}, diff --git a/relayer/pkg/chainlink/ocr2/medianreport/report.go b/relayer/pkg/chainlink/ocr2/medianreport/report.go index 9df7ee4b5..7049d8a6a 100644 --- a/relayer/pkg/chainlink/ocr2/medianreport/report.go +++ b/relayer/pkg/chainlink/ocr2/medianreport/report.go @@ -1,6 +1,7 @@ package medianreport import ( + "fmt" "math" "math/big" "sort" @@ -34,6 +35,12 @@ func (c ReportCodec) BuildReport(oo []median.ParsedAttributedObservation) (types return nil, errors.New("couldn't build report from empty attributed observations") } + for _, o := range oo { + if o.Value.Sign() == -1 || o.JuelsPerFeeCoin.Sign() == -1 { + return nil, fmt.Errorf("starknet does not support negative values: value = (%v), fee = (%v)", o.Value, o.JuelsPerFeeCoin) + } + } + // preserve original array oo = append([]median.ParsedAttributedObservation{}, oo...) numFelt := caigotypes.BigToFelt(big.NewInt(int64(num))) @@ -50,7 +57,6 @@ func (c ReportCodec) BuildReport(oo []median.ParsedAttributedObservation) (types return oo[i].JuelsPerFeeCoin.Cmp(oo[j].JuelsPerFeeCoin) < 0 }) juelsPerFeeCoin := oo[num/2].JuelsPerFeeCoin - juelsPerFeeCoin = starknet.SignedBigToFelt(juelsPerFeeCoin) // converts negative bigInts to corresponding felt in bigInt form juelsPerFeeCoinFelt := caigotypes.BigToFelt(juelsPerFeeCoin) // TODO: source from observations @@ -63,11 +69,10 @@ func (c ReportCodec) BuildReport(oo []median.ParsedAttributedObservation) (types }) var observers = make([]byte, starknet.FeltLength) - var observations []*caigotypes.Felt + var observations []caigotypes.Felt for i, o := range oo { observers[i] = byte(o.Observer) - obs := starknet.SignedBigToFelt(o.Value) // converts negative bigInts to corresponding felt in bigInt form - observations = append(observations, caigotypes.BigToFelt(obs)) + observations = append(observations, caigotypes.BigToFelt(o.Value)) } var report []byte @@ -114,7 +119,11 @@ func (c ReportCodec) MedianFromReport(report types.Report) (*big.Int, error) { for i := 0; i < n; i++ { start := prefixSizeBytes + observationSizeBytes*i end := start + observationSizeBytes - o := starknet.FeltToSignedBig(caigotypes.BytesToFelt(report[start:end])) + obv := caigotypes.BytesToFelt(report[start:end]) + o, err := starknet.FeltToUnsignedBig(obv) + if err != nil { + return nil, errors.Wrap(err, "observation invalid") + } oo = append(oo, o) } diff --git a/relayer/pkg/chainlink/ocr2/medianreport/report_test.go b/relayer/pkg/chainlink/ocr2/medianreport/report_test.go index 2a94cc9d1..c74355dd3 100644 --- a/relayer/pkg/chainlink/ocr2/medianreport/report_test.go +++ b/relayer/pkg/chainlink/ocr2/medianreport/report_test.go @@ -14,6 +14,33 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" ) +func TestBuildReportWithNegativeValues(t *testing.T) { + c := ReportCodec{} + oo := []median.ParsedAttributedObservation{} + + oo = append(oo, median.ParsedAttributedObservation{ + Timestamp: uint32(time.Now().Unix()), + Value: big.NewInt(-10), + JuelsPerFeeCoin: big.NewInt(10), + Observer: commontypes.OracleID(1), + }) + + _, err := c.BuildReport(oo) + assert.ErrorContains(t, err, "starknet does not support negative values: value = (-10), fee = (10)") + + oo = []median.ParsedAttributedObservation{} + oo = append(oo, median.ParsedAttributedObservation{ + Timestamp: uint32(time.Now().Unix()), + Value: big.NewInt(10), + JuelsPerFeeCoin: big.NewInt(-10), + Observer: commontypes.OracleID(1), + }) + + _, err = c.BuildReport(oo) + assert.ErrorContains(t, err, "starknet does not support negative values: value = (10), fee = (-10)") + +} + func TestBuildReport(t *testing.T) { c := ReportCodec{} oo := []median.ParsedAttributedObservation{} @@ -99,24 +126,6 @@ func TestMedianFromReport(t *testing.T) { obs: []*big.Int{big.NewInt(1), big.NewInt(1)}, expectedMedian: big.NewInt(1), }, - { - name: "one negative one positive", - obs: []*big.Int{big.NewInt(-1), big.NewInt(1)}, - // sorts to -1, 1 - expectedMedian: big.NewInt(1), - }, - { - name: "two negative", - obs: []*big.Int{big.NewInt(-2), big.NewInt(-1)}, - // will sort to -2, -1 - expectedMedian: big.NewInt(-1), - }, - { - name: "three negative", - obs: []*big.Int{big.NewInt(-5), big.NewInt(-3), big.NewInt(-1)}, - // will sort to -5, -3, -1 - expectedMedian: big.NewInt(-3), - }, } // add cases for observation number from [1..31] diff --git a/relayer/pkg/chainlink/ocr2/mocks/OCR2Reader.go b/relayer/pkg/chainlink/ocr2/mocks/OCR2Reader.go index 4414d3306..3da7aa9ce 100644 --- a/relayer/pkg/chainlink/ocr2/mocks/OCR2Reader.go +++ b/relayer/pkg/chainlink/ocr2/mocks/OCR2Reader.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.28.1. DO NOT EDIT. +// Code generated by mockery v2.29.0. DO NOT EDIT. package mocks @@ -37,21 +37,21 @@ func (_m *OCR2Reader) BaseReader() starknet.Reader { } // BillingDetails provides a mock function with given fields: _a0, _a1 -func (_m *OCR2Reader) BillingDetails(_a0 context.Context, _a1 types.Hash) (ocr2.BillingDetails, error) { +func (_m *OCR2Reader) BillingDetails(_a0 context.Context, _a1 types.Felt) (ocr2.BillingDetails, error) { ret := _m.Called(_a0, _a1) var r0 ocr2.BillingDetails var r1 error - if rf, ok := ret.Get(0).(func(context.Context, types.Hash) (ocr2.BillingDetails, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.Felt) (ocr2.BillingDetails, error)); ok { return rf(_a0, _a1) } - if rf, ok := ret.Get(0).(func(context.Context, types.Hash) ocr2.BillingDetails); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.Felt) ocr2.BillingDetails); ok { r0 = rf(_a0, _a1) } else { r0 = ret.Get(0).(ocr2.BillingDetails) } - if rf, ok := ret.Get(1).(func(context.Context, types.Hash) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, types.Felt) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -61,21 +61,21 @@ func (_m *OCR2Reader) BillingDetails(_a0 context.Context, _a1 types.Hash) (ocr2. } // ConfigFromEventAt provides a mock function with given fields: _a0, _a1, _a2 -func (_m *OCR2Reader) ConfigFromEventAt(_a0 context.Context, _a1 types.Hash, _a2 uint64) (ocr2.ContractConfig, error) { +func (_m *OCR2Reader) ConfigFromEventAt(_a0 context.Context, _a1 types.Felt, _a2 uint64) (ocr2.ContractConfig, error) { ret := _m.Called(_a0, _a1, _a2) var r0 ocr2.ContractConfig var r1 error - if rf, ok := ret.Get(0).(func(context.Context, types.Hash, uint64) (ocr2.ContractConfig, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.Felt, uint64) (ocr2.ContractConfig, error)); ok { return rf(_a0, _a1, _a2) } - if rf, ok := ret.Get(0).(func(context.Context, types.Hash, uint64) ocr2.ContractConfig); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.Felt, uint64) ocr2.ContractConfig); ok { r0 = rf(_a0, _a1, _a2) } else { r0 = ret.Get(0).(ocr2.ContractConfig) } - if rf, ok := ret.Get(1).(func(context.Context, types.Hash, uint64) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, types.Felt, uint64) error); ok { r1 = rf(_a0, _a1, _a2) } else { r1 = ret.Error(1) @@ -85,21 +85,21 @@ func (_m *OCR2Reader) ConfigFromEventAt(_a0 context.Context, _a1 types.Hash, _a2 } // LatestConfigDetails provides a mock function with given fields: _a0, _a1 -func (_m *OCR2Reader) LatestConfigDetails(_a0 context.Context, _a1 types.Hash) (ocr2.ContractConfigDetails, error) { +func (_m *OCR2Reader) LatestConfigDetails(_a0 context.Context, _a1 types.Felt) (ocr2.ContractConfigDetails, error) { ret := _m.Called(_a0, _a1) var r0 ocr2.ContractConfigDetails var r1 error - if rf, ok := ret.Get(0).(func(context.Context, types.Hash) (ocr2.ContractConfigDetails, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.Felt) (ocr2.ContractConfigDetails, error)); ok { return rf(_a0, _a1) } - if rf, ok := ret.Get(0).(func(context.Context, types.Hash) ocr2.ContractConfigDetails); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.Felt) ocr2.ContractConfigDetails); ok { r0 = rf(_a0, _a1) } else { r0 = ret.Get(0).(ocr2.ContractConfigDetails) } - if rf, ok := ret.Get(1).(func(context.Context, types.Hash) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, types.Felt) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -109,21 +109,21 @@ func (_m *OCR2Reader) LatestConfigDetails(_a0 context.Context, _a1 types.Hash) ( } // LatestRoundData provides a mock function with given fields: _a0, _a1 -func (_m *OCR2Reader) LatestRoundData(_a0 context.Context, _a1 types.Hash) (ocr2.RoundData, error) { +func (_m *OCR2Reader) LatestRoundData(_a0 context.Context, _a1 types.Felt) (ocr2.RoundData, error) { ret := _m.Called(_a0, _a1) var r0 ocr2.RoundData var r1 error - if rf, ok := ret.Get(0).(func(context.Context, types.Hash) (ocr2.RoundData, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.Felt) (ocr2.RoundData, error)); ok { return rf(_a0, _a1) } - if rf, ok := ret.Get(0).(func(context.Context, types.Hash) ocr2.RoundData); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.Felt) ocr2.RoundData); ok { r0 = rf(_a0, _a1) } else { r0 = ret.Get(0).(ocr2.RoundData) } - if rf, ok := ret.Get(1).(func(context.Context, types.Hash) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, types.Felt) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -133,21 +133,21 @@ func (_m *OCR2Reader) LatestRoundData(_a0 context.Context, _a1 types.Hash) (ocr2 } // LatestTransmissionDetails provides a mock function with given fields: _a0, _a1 -func (_m *OCR2Reader) LatestTransmissionDetails(_a0 context.Context, _a1 types.Hash) (ocr2.TransmissionDetails, error) { +func (_m *OCR2Reader) LatestTransmissionDetails(_a0 context.Context, _a1 types.Felt) (ocr2.TransmissionDetails, error) { ret := _m.Called(_a0, _a1) var r0 ocr2.TransmissionDetails var r1 error - if rf, ok := ret.Get(0).(func(context.Context, types.Hash) (ocr2.TransmissionDetails, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.Felt) (ocr2.TransmissionDetails, error)); ok { return rf(_a0, _a1) } - if rf, ok := ret.Get(0).(func(context.Context, types.Hash) ocr2.TransmissionDetails); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.Felt) ocr2.TransmissionDetails); ok { r0 = rf(_a0, _a1) } else { r0 = ret.Get(0).(ocr2.TransmissionDetails) } - if rf, ok := ret.Get(1).(func(context.Context, types.Hash) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, types.Felt) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -157,15 +157,15 @@ func (_m *OCR2Reader) LatestTransmissionDetails(_a0 context.Context, _a1 types.H } // LinkAvailableForPayment provides a mock function with given fields: _a0, _a1 -func (_m *OCR2Reader) LinkAvailableForPayment(_a0 context.Context, _a1 types.Hash) (*big.Int, error) { +func (_m *OCR2Reader) LinkAvailableForPayment(_a0 context.Context, _a1 types.Felt) (*big.Int, error) { ret := _m.Called(_a0, _a1) var r0 *big.Int var r1 error - if rf, ok := ret.Get(0).(func(context.Context, types.Hash) (*big.Int, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.Felt) (*big.Int, error)); ok { return rf(_a0, _a1) } - if rf, ok := ret.Get(0).(func(context.Context, types.Hash) *big.Int); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.Felt) *big.Int); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -173,7 +173,7 @@ func (_m *OCR2Reader) LinkAvailableForPayment(_a0 context.Context, _a1 types.Has } } - if rf, ok := ret.Get(1).(func(context.Context, types.Hash) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, types.Felt) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -183,15 +183,15 @@ func (_m *OCR2Reader) LinkAvailableForPayment(_a0 context.Context, _a1 types.Has } // NewTransmissionsFromEventsAt provides a mock function with given fields: _a0, _a1, _a2 -func (_m *OCR2Reader) NewTransmissionsFromEventsAt(_a0 context.Context, _a1 types.Hash, _a2 uint64) ([]ocr2.NewTransmissionEvent, error) { +func (_m *OCR2Reader) NewTransmissionsFromEventsAt(_a0 context.Context, _a1 types.Felt, _a2 uint64) ([]ocr2.NewTransmissionEvent, error) { ret := _m.Called(_a0, _a1, _a2) var r0 []ocr2.NewTransmissionEvent var r1 error - if rf, ok := ret.Get(0).(func(context.Context, types.Hash, uint64) ([]ocr2.NewTransmissionEvent, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.Felt, uint64) ([]ocr2.NewTransmissionEvent, error)); ok { return rf(_a0, _a1, _a2) } - if rf, ok := ret.Get(0).(func(context.Context, types.Hash, uint64) []ocr2.NewTransmissionEvent); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.Felt, uint64) []ocr2.NewTransmissionEvent); ok { r0 = rf(_a0, _a1, _a2) } else { if ret.Get(0) != nil { @@ -199,7 +199,7 @@ func (_m *OCR2Reader) NewTransmissionsFromEventsAt(_a0 context.Context, _a1 type } } - if rf, ok := ret.Get(1).(func(context.Context, types.Hash, uint64) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, types.Felt, uint64) error); ok { r1 = rf(_a0, _a1, _a2) } else { r1 = ret.Error(1) diff --git a/relayer/pkg/chainlink/ocr2/types.go b/relayer/pkg/chainlink/ocr2/types.go index c1099766c..d81cf4f40 100644 --- a/relayer/pkg/chainlink/ocr2/types.go +++ b/relayer/pkg/chainlink/ocr2/types.go @@ -62,7 +62,7 @@ type RoundData struct { UpdatedAt time.Time } -func NewRoundData(felts []*caigotypes.Felt) (data RoundData, err error) { +func NewRoundData(felts []caigotypes.Felt) (data RoundData, err error) { if len(felts) != 5 { return data, fmt.Errorf("expected number of felts to be 5 but got %d", len(felts)) } diff --git a/relayer/pkg/chainlink/ocr2/types_test.go b/relayer/pkg/chainlink/ocr2/types_test.go index 4f3bdbf19..8d339f56c 100644 --- a/relayer/pkg/chainlink/ocr2/types_test.go +++ b/relayer/pkg/chainlink/ocr2/types_test.go @@ -9,8 +9,8 @@ import ( "github.com/stretchr/testify/require" ) -func StringsToCaigoFelts(in []string) []*caigotypes.Felt { - out := make([]*caigotypes.Felt, len(in)) +func StringsToCaigoFelts(in []string) []caigotypes.Felt { + out := make([]caigotypes.Felt, len(in)) for i := 0; i < len(in); i++ { out[i] = caigotypes.StrToFelt(in[i]) } diff --git a/relayer/pkg/chainlink/relay.go b/relayer/pkg/chainlink/relay.go index f7635f8b7..061649cc7 100644 --- a/relayer/pkg/chainlink/relay.go +++ b/relayer/pkg/chainlink/relay.go @@ -115,3 +115,7 @@ func (r *relayer) NewMedianProvider(rargs relaytypes.RelayArgs, pargs relaytypes func (r *relayer) NewMercuryProvider(rargs relaytypes.RelayArgs, pargs relaytypes.PluginArgs) (relaytypes.MercuryProvider, error) { return nil, errors.New("mercury is not supported for starknet") } + +func (r *relayer) NewFunctionsProvider(rargs relaytypes.RelayArgs, pargs relaytypes.PluginArgs) (relaytypes.FunctionsProvider, error) { + return nil, errors.New("functions are not supported for solana") +} diff --git a/relayer/pkg/chainlink/txm/mocks/config.go b/relayer/pkg/chainlink/txm/mocks/config.go index 71c812269..2b4e616f0 100644 --- a/relayer/pkg/chainlink/txm/mocks/config.go +++ b/relayer/pkg/chainlink/txm/mocks/config.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.28.1. DO NOT EDIT. +// Code generated by mockery v2.29.0. DO NOT EDIT. package mocks diff --git a/relayer/pkg/chainlink/txm/mocks/nonce_manager_client.go b/relayer/pkg/chainlink/txm/mocks/nonce_manager_client.go index e49c10388..8e49300a0 100644 --- a/relayer/pkg/chainlink/txm/mocks/nonce_manager_client.go +++ b/relayer/pkg/chainlink/txm/mocks/nonce_manager_client.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.28.1. DO NOT EDIT. +// Code generated by mockery v2.29.0. DO NOT EDIT. package mocks @@ -17,15 +17,15 @@ type NonceManagerClient struct { } // AccountNonce provides a mock function with given fields: _a0, _a1 -func (_m *NonceManagerClient) AccountNonce(_a0 context.Context, _a1 types.Hash) (*big.Int, error) { +func (_m *NonceManagerClient) AccountNonce(_a0 context.Context, _a1 types.Felt) (*big.Int, error) { ret := _m.Called(_a0, _a1) var r0 *big.Int var r1 error - if rf, ok := ret.Get(0).(func(context.Context, types.Hash) (*big.Int, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.Felt) (*big.Int, error)); ok { return rf(_a0, _a1) } - if rf, ok := ret.Get(0).(func(context.Context, types.Hash) *big.Int); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.Felt) *big.Int); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -33,7 +33,7 @@ func (_m *NonceManagerClient) AccountNonce(_a0 context.Context, _a1 types.Hash) } } - if rf, ok := ret.Get(1).(func(context.Context, types.Hash) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, types.Felt) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) diff --git a/relayer/pkg/chainlink/txm/nonce.go b/relayer/pkg/chainlink/txm/nonce.go index cac095dbd..c2626664c 100644 --- a/relayer/pkg/chainlink/txm/nonce.go +++ b/relayer/pkg/chainlink/txm/nonce.go @@ -16,16 +16,16 @@ import ( //go:generate mockery --name NonceManagerClient --output ./mocks/ --case=underscore --filename nonce_manager_client.go type NonceManagerClient interface { - AccountNonce(context.Context, caigotypes.Hash) (*big.Int, error) + AccountNonce(context.Context, caigotypes.Felt) (*big.Int, error) } type NonceManager interface { types.Service - Register(ctx context.Context, address caigotypes.Hash, chainId string, client NonceManagerClient) error + Register(ctx context.Context, address caigotypes.Felt, chainId string, client NonceManagerClient) error - NextSequence(address caigotypes.Hash, chainID string) (*big.Int, error) - IncrementNextSequence(address caigotypes.Hash, chainID string, currentNonce *big.Int) error + NextSequence(address caigotypes.Felt, chainID string) (*big.Int, error) + IncrementNextSequence(address caigotypes.Felt, chainID string, currentNonce *big.Int) error } var _ NonceManager = (*nonceManager)(nil) @@ -66,7 +66,7 @@ func (nm *nonceManager) HealthReport() map[string]error { } // Register is used because we cannot pre-fetch nonces. the pubkey is known before hand, but the account address is not known until a job is started and sends a tx -func (nm *nonceManager) Register(ctx context.Context, addr caigotypes.Hash, chainId string, client NonceManagerClient) error { +func (nm *nonceManager) Register(ctx context.Context, addr caigotypes.Felt, chainId string, client NonceManagerClient) error { nm.lock.Lock() defer nm.lock.Unlock() addressNonces, exists := nm.n[addr.String()] @@ -85,7 +85,7 @@ func (nm *nonceManager) Register(ctx context.Context, addr caigotypes.Hash, chai return nil } -func (nm *nonceManager) NextSequence(addr caigotypes.Hash, chainId string) (*big.Int, error) { +func (nm *nonceManager) NextSequence(addr caigotypes.Felt, chainId string) (*big.Int, error) { if err := nm.validate(addr, chainId); err != nil { return nil, err } @@ -95,7 +95,7 @@ func (nm *nonceManager) NextSequence(addr caigotypes.Hash, chainId string) (*big return nm.n[addr.String()][chainId], nil } -func (nm *nonceManager) IncrementNextSequence(addr caigotypes.Hash, chainId string, currentNonce *big.Int) error { +func (nm *nonceManager) IncrementNextSequence(addr caigotypes.Felt, chainId string, currentNonce *big.Int) error { if err := nm.validate(addr, chainId); err != nil { return err } @@ -110,7 +110,7 @@ func (nm *nonceManager) IncrementNextSequence(addr caigotypes.Hash, chainId stri return nil } -func (nm *nonceManager) validate(addr caigotypes.Hash, id string) error { +func (nm *nonceManager) validate(addr caigotypes.Felt, id string) error { nm.lock.RLock() defer nm.lock.RUnlock() if _, exists := nm.n[addr.String()]; !exists { diff --git a/relayer/pkg/chainlink/txm/nonce_test.go b/relayer/pkg/chainlink/txm/nonce_test.go index 124719434..7dc2dde7c 100644 --- a/relayer/pkg/chainlink/txm/nonce_test.go +++ b/relayer/pkg/chainlink/txm/nonce_test.go @@ -18,14 +18,14 @@ import ( "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/txm/mocks" ) -func newTestNonceManager(t *testing.T, chainID string, initNonce *big.Int) (txm.NonceManager, caigotypes.Hash, func()) { +func newTestNonceManager(t *testing.T, chainID string, initNonce *big.Int) (txm.NonceManager, caigotypes.Felt, func()) { // setup c := mocks.NewNonceManagerClient(t) lggr := logger.Test(t) nm := txm.NewNonceManager(lggr) // mock returns - keyHash := caigotypes.HexToHash("test-key-id") + keyHash := caigotypes.StrToFelt("test-key-id") c.On("AccountNonce", mock.Anything, mock.Anything).Return(initNonce, nil).Once() require.NoError(t, nm.Start(utils.Context(t))) @@ -53,7 +53,7 @@ func TestNonceManager_NextSequence(t *testing.T) { assert.Contains(t, err.Error(), fmt.Sprintf("nonce does not exist for key: %s and chain: %s", k.String(), "invalid_chainId")) // should fail with invalid address - randAddr1 := caigotypes.Hash{1} + randAddr1 := caigotypes.BigToFelt(big.NewInt(1)) _, err = nm.NextSequence(randAddr1, chainId) require.Error(t, err) assert.Contains(t, err.Error(), fmt.Sprintf("nonce tracking does not exist for key: %s", randAddr1.String())) @@ -88,7 +88,7 @@ func TestNonceManager_IncrementNextSequence(t *testing.T) { assert.Contains(t, err.Error(), fmt.Sprintf("nonce does not exist for key: %s and chain: %s", k.String(), "invalid_chainId")) // should fail with invalid address - randAddr1 := caigotypes.Hash{1} + randAddr1 := caigotypes.BigToFelt(big.NewInt(1)) err = nm.IncrementNextSequence(randAddr1, chainId, initPlusOne) require.Error(t, err) assert.Contains(t, err.Error(), fmt.Sprintf("nonce tracking does not exist for key: %s", randAddr1.String())) diff --git a/relayer/pkg/chainlink/txm/test_helpers.go b/relayer/pkg/chainlink/txm/test_helpers.go index 661dcf1d8..3c9d5fa02 100644 --- a/relayer/pkg/chainlink/txm/test_helpers.go +++ b/relayer/pkg/chainlink/txm/test_helpers.go @@ -77,7 +77,7 @@ func TestKeys(t *testing.T, count int) (rawkeys [][]byte) { break } - keyBytes := caigotypes.HexToHash(k).Bytes() + keyBytes := caigotypes.StrToFelt(k).Bytes() rawkeys = append(rawkeys, keyBytes) } return rawkeys diff --git a/relayer/pkg/chainlink/txm/txm.go b/relayer/pkg/chainlink/txm/txm.go index 572971baf..c1bab0c18 100644 --- a/relayer/pkg/chainlink/txm/txm.go +++ b/relayer/pkg/chainlink/txm/txm.go @@ -5,11 +5,12 @@ import ( "errors" "fmt" "math/big" + "reflect" "sync" "time" "github.com/smartcontractkit/caigo" - "github.com/smartcontractkit/caigo/gateway" + caigorpc "github.com/smartcontractkit/caigo/rpcv02" caigotypes "github.com/smartcontractkit/caigo/types" "golang.org/x/exp/maps" @@ -25,13 +26,13 @@ const ( ) type TxManager interface { - Enqueue(senderAddress caigotypes.Hash, accountAddress caigotypes.Hash, txFn caigotypes.FunctionCall) error + Enqueue(senderAddress caigotypes.Felt, accountAddress caigotypes.Felt, txFn caigotypes.FunctionCall) error InflightCount() (int, int) } type Tx struct { - senderAddress caigotypes.Hash - accountAddress caigotypes.Hash + senderAddress caigotypes.Felt + accountAddress caigotypes.Felt call caigotypes.FunctionCall } @@ -124,7 +125,7 @@ func (txm *starktxm) broadcastLoop() { const FEE_MARGIN uint64 = 115 -func (txm *starktxm) broadcast(ctx context.Context, senderAddress caigotypes.Hash, accountAddress caigotypes.Hash, tx caigotypes.FunctionCall) (txhash string, err error) { +func (txm *starktxm) broadcast(ctx context.Context, senderAddress caigotypes.Felt, accountAddress caigotypes.Felt, tx caigotypes.FunctionCall) (txhash string, err error) { txs := []caigotypes.FunctionCall{tx} client, err := txm.client.Get() if err != nil { @@ -132,12 +133,17 @@ func (txm *starktxm) broadcast(ctx context.Context, senderAddress caigotypes.Has return txhash, fmt.Errorf("broadcast: failed to fetch client: %+w", err) } // create new account - account, err := caigo.NewGatewayAccount(senderAddress.String(), accountAddress.String(), txm.ks, client.Gw, caigo.AccountVersion1) + account, err := caigo.NewRPCAccount(senderAddress, accountAddress, txm.ks, client.Provider, caigo.AccountVersion1) if err != nil { return txhash, fmt.Errorf("failed to create new account: %+w", err) } - nonce, err := txm.nonce.NextSequence(accountAddress, client.Gw.ChainId) + chainID, err := client.Provider.ChainID(ctx) + if err != nil { + return txhash, fmt.Errorf("failed to get chainID: %+w", err) + } + + nonce, err := txm.nonce.NextSequence(accountAddress, chainID) if err != nil { return txhash, fmt.Errorf("failed to get nonce: %+w", err) } @@ -174,7 +180,7 @@ func (txm *starktxm) broadcast(ctx context.Context, senderAddress caigotypes.Has // update nonce if transaction is successful err = errors.Join( - txm.nonce.IncrementNextSequence(accountAddress, client.Gw.ChainId, nonce), + txm.nonce.IncrementNextSequence(accountAddress, chainID, nonce), txm.txStore.Save(accountAddress, nonce, res.TransactionHash), ) return res.TransactionHash, err @@ -204,21 +210,21 @@ func (txm *starktxm) confirmLoop() { for addr := range hashes { for i := range hashes[addr] { hash := hashes[addr][i] - status, err := client.Gw.TransactionStatus(ctx, gateway.TransactionStatusOptions{ - TransactionHash: hashes[addr][i], - }) + response, err := client.Provider.TransactionReceipt(ctx, caigotypes.StrToFelt(hashes[addr][i])) if err != nil { txm.lggr.Errorw("failed to fetch transaction status", "hash", hash, "error", err) continue } - - if status == nil { - txm.lggr.Errorw("status was nil", "hash", hash) + receipt, ok := response.(caigorpc.InvokeTransactionReceipt) + if !ok { + txm.lggr.Errorw("wrong receipt type", "type", reflect.TypeOf(response)) continue } - if status.TxStatus == "ACCEPTED_ON_L1" || status.TxStatus == "ACCEPTED_ON_L2" || status.TxStatus == "REJECTED" { - txm.lggr.Debugw(fmt.Sprintf("tx confirmed: %s", status.TxStatus), "hash", hash, "status", status) + status := receipt.Status + + if status == caigotypes.TransactionAcceptedOnL1 || status == caigotypes.TransactionAcceptedOnL2 || status == caigotypes.TransactionRejected { + txm.lggr.Debugw(fmt.Sprintf("tx confirmed: %s", status), "hash", hash, "status", status) if err := txm.txStore.Confirm(addr, hash); err != nil { txm.lggr.Errorw("failed to confirm tx in TxStore", "hash", hash, "sender", addr, "error", err) } @@ -254,7 +260,7 @@ func (txm *starktxm) HealthReport() map[string]error { return map[string]error{txm.Name(): txm.Healthy()} } -func (txm *starktxm) Enqueue(senderAddress, accountAddress caigotypes.Hash, tx caigotypes.FunctionCall) error { +func (txm *starktxm) Enqueue(senderAddress, accountAddress caigotypes.Felt, tx caigotypes.FunctionCall) error { // validate key exists for sender // use the embedded Loopp Keystore to do this; the spec and design // encourage passing nil data to the loop.Keystore.Sign as way to test @@ -269,8 +275,13 @@ func (txm *starktxm) Enqueue(senderAddress, accountAddress caigotypes.Hash, tx c return fmt.Errorf("broadcast: failed to fetch client: %+w", err) } + chainID, err := client.Provider.ChainID(context.TODO()) + if err != nil { + return fmt.Errorf("failed to get chainID: %+w", err) + } + // register account for nonce manager - if err := txm.nonce.Register(context.TODO(), accountAddress, client.Gw.ChainId, client); err != nil { + if err := txm.nonce.Register(context.TODO(), accountAddress, chainID, client); err != nil { return err } diff --git a/relayer/pkg/chainlink/txm/txm_test.go b/relayer/pkg/chainlink/txm/txm_test.go index c4f26317e..c74e88c49 100644 --- a/relayer/pkg/chainlink/txm/txm_test.go +++ b/relayer/pkg/chainlink/txm/txm_test.go @@ -37,7 +37,7 @@ func TestIntegration_Txm(t *testing.T) { for i := range accounts { privKey, err := caigotypes.HexToBytes(accounts[i].PrivateKey) require.NoError(t, err) - senderAddress := caigotypes.HexToHash(accounts[i].PublicKey).String() + senderAddress := caigotypes.StrToFelt(accounts[i].PublicKey).String() localKeys[senderAddress] = caigotypes.BytesToBig(privKey) localAccounts[senderAddress] = accounts[i].Address } @@ -53,7 +53,7 @@ func TestIntegration_Txm(t *testing.T) { ksAdapter := NewKeystoreAdapter(looppKs) lggr, observer := logger.TestObserved(t, zapcore.DebugLevel) timeout := 10 * time.Second - client, err := starknet.NewClient(caigogw.GOERLI_ID, url, lggr, &timeout) + client, err := starknet.NewClient(caigogw.GOERLI_ID, url+"/rpc", lggr, &timeout) require.NoError(t, err) getClient := func() (*starknet.Client, error) { @@ -76,10 +76,10 @@ func TestIntegration_Txm(t *testing.T) { require.NoError(t, txm.Ready()) for senderAddressStr := range localKeys { - senderAddress := caigotypes.HexToHash(senderAddressStr) + senderAddress := caigotypes.StrToFelt(senderAddressStr) for i := 0; i < n; i++ { - require.NoError(t, txm.Enqueue(senderAddress, caigotypes.HexToHash(localAccounts[senderAddressStr]), caigotypes.FunctionCall{ - ContractAddress: caigotypes.HexToHash("0x49D36570D4E46F48E99674BD3FCC84644DDD6B96F7C741B1562B82F9E004DC7"), // send to ETH token contract + require.NoError(t, txm.Enqueue(senderAddress, caigotypes.StrToFelt(localAccounts[senderAddressStr]), caigotypes.FunctionCall{ + ContractAddress: caigotypes.StrToFelt("0x49D36570D4E46F48E99674BD3FCC84644DDD6B96F7C741B1562B82F9E004DC7"), // send to ETH token contract EntryPointSelector: "totalSupply", })) } diff --git a/relayer/pkg/chainlink/txm/txstore.go b/relayer/pkg/chainlink/txm/txstore.go index 875c2a2d9..4c2c2b5f6 100644 --- a/relayer/pkg/chainlink/txm/txstore.go +++ b/relayer/pkg/chainlink/txm/txstore.go @@ -77,17 +77,17 @@ func (s *TxStore) InflightCount() int { } type ChainTxStore struct { - store map[caigotypes.Hash]*TxStore + store map[caigotypes.Felt]*TxStore lock sync.RWMutex } func NewChainTxStore() *ChainTxStore { return &ChainTxStore{ - store: map[caigotypes.Hash]*TxStore{}, + store: map[caigotypes.Felt]*TxStore{}, } } -func (c *ChainTxStore) Save(from caigotypes.Hash, nonce *big.Int, hash string) error { +func (c *ChainTxStore) Save(from caigotypes.Felt, nonce *big.Int, hash string) error { // use write lock for methods that modify underlying data c.lock.Lock() defer c.lock.Unlock() @@ -98,7 +98,7 @@ func (c *ChainTxStore) Save(from caigotypes.Hash, nonce *big.Int, hash string) e return c.store[from].Save(nonce, hash) } -func (c *ChainTxStore) Confirm(from caigotypes.Hash, hash string) error { +func (c *ChainTxStore) Confirm(from caigotypes.Felt, hash string) error { // use write lock for methods that modify underlying data c.lock.Lock() defer c.lock.Unlock() @@ -109,12 +109,12 @@ func (c *ChainTxStore) Confirm(from caigotypes.Hash, hash string) error { return c.store[from].Confirm(hash) } -func (c *ChainTxStore) GetAllInflightCount() map[caigotypes.Hash]int { +func (c *ChainTxStore) GetAllInflightCount() map[caigotypes.Felt]int { // use read lock for methods that read underlying data c.lock.RLock() defer c.lock.RUnlock() - list := map[caigotypes.Hash]int{} + list := map[caigotypes.Felt]int{} for i := range c.store { list[i] = c.store[i].InflightCount() @@ -123,12 +123,12 @@ func (c *ChainTxStore) GetAllInflightCount() map[caigotypes.Hash]int { return list } -func (c *ChainTxStore) GetAllUnconfirmed() map[caigotypes.Hash][]string { +func (c *ChainTxStore) GetAllUnconfirmed() map[caigotypes.Felt][]string { // use read lock for methods that read underlying data c.lock.RLock() defer c.lock.RUnlock() - list := map[caigotypes.Hash][]string{} + list := map[caigotypes.Felt][]string{} for i := range c.store { list[i] = c.store[i].GetUnconfirmed() @@ -136,9 +136,9 @@ func (c *ChainTxStore) GetAllUnconfirmed() map[caigotypes.Hash][]string { return list } -func (c *ChainTxStore) validate(from caigotypes.Hash) error { +func (c *ChainTxStore) validate(from caigotypes.Felt) error { if _, exists := c.store[from]; !exists { return fmt.Errorf("from address does not exist: %s", from) } return nil -} \ No newline at end of file +} diff --git a/relayer/pkg/chainlink/txm/txstore_test.go b/relayer/pkg/chainlink/txm/txstore_test.go index 2c935ebc9..dd415952f 100644 --- a/relayer/pkg/chainlink/txm/txstore_test.go +++ b/relayer/pkg/chainlink/txm/txstore_test.go @@ -132,35 +132,35 @@ func TestChainTxStore(t *testing.T) { c := NewChainTxStore() // automatically save the from address - require.NoError(t, c.Save(caigotypes.Hash{}, big.NewInt(0), "0x0")) + require.NoError(t, c.Save(caigotypes.Felt{}, big.NewInt(0), "0x0")) // reject saving for existing address and reused hash & nonce // error messages are tested within TestTxStore - assert.Error(t, c.Save(caigotypes.Hash{}, big.NewInt(0), "0x1")) - assert.Error(t, c.Save(caigotypes.Hash{}, big.NewInt(1), "0x0")) + assert.Error(t, c.Save(caigotypes.Felt{}, big.NewInt(0), "0x1")) + assert.Error(t, c.Save(caigotypes.Felt{}, big.NewInt(1), "0x0")) // inflight count - count, exists := c.GetAllInflightCount()[caigotypes.Hash{}] + count, exists := c.GetAllInflightCount()[caigotypes.Felt{}] require.True(t, exists) assert.Equal(t, 1, count) - _, exists = c.GetAllInflightCount()[caigotypes.Hash{1}] + _, exists = c.GetAllInflightCount()[caigotypes.BigToFelt(big.NewInt(1))] require.False(t, exists) // get unconfirmed list := c.GetAllUnconfirmed() assert.Equal(t, 1, len(list)) - hashes, ok := list[caigotypes.Hash{}] + hashes, ok := list[caigotypes.Felt{}] assert.True(t, ok) assert.Equal(t, []string{"0x0"}, hashes) // confirm - assert.NoError(t, c.Confirm(caigotypes.Hash{}, "0x0")) - assert.ErrorContains(t, c.Confirm(caigotypes.Hash{1}, "0x0"), "from address does not exist") - assert.Error(t, c.Confirm(caigotypes.Hash{}, "0x1")) + assert.NoError(t, c.Confirm(caigotypes.Felt{}, "0x0")) + assert.ErrorContains(t, c.Confirm(caigotypes.BigToFelt(big.NewInt(1)), "0x0"), "from address does not exist") + assert.Error(t, c.Confirm(caigotypes.Felt{}, "0x1")) list = c.GetAllUnconfirmed() assert.Equal(t, 1, len(list)) - assert.Equal(t, 0, len(list[caigotypes.Hash{}])) - count, exists = c.GetAllInflightCount()[caigotypes.Hash{}] + assert.Equal(t, 0, len(list[caigotypes.Felt{}])) + count, exists = c.GetAllInflightCount()[caigotypes.Felt{}] assert.True(t, exists) assert.Equal(t, 0, count) -} \ No newline at end of file +} diff --git a/relayer/pkg/starknet/client.go b/relayer/pkg/starknet/client.go index 83d17690c..34da24102 100644 --- a/relayer/pkg/starknet/client.go +++ b/relayer/pkg/starknet/client.go @@ -7,7 +7,9 @@ import ( "github.com/pkg/errors" - caigogw "github.com/smartcontractkit/caigo/gateway" + ethrpc "github.com/ethereum/go-ethereum/rpc" + caigo "github.com/smartcontractkit/caigo" + caigorpc "github.com/smartcontractkit/caigo/rpcv02" caigotypes "github.com/smartcontractkit/caigo/types" "github.com/smartcontractkit/chainlink-relay/pkg/logger" @@ -18,21 +20,17 @@ import ( type Reader interface { CallContract(context.Context, CallOps) ([]string, error) LatestBlockHeight(context.Context) (uint64, error) - BlockByNumberGateway(context.Context, uint64) (*caigogw.Block, error) // provider interface - BlockByHash(context.Context, string, string) (*caigogw.Block, error) - BlockByNumber(context.Context, *big.Int, string) (*caigogw.Block, error) - Call(context.Context, caigotypes.FunctionCall, string) ([]string, error) - ChainID(context.Context) (string, error) + BlockWithTxHashes(ctx context.Context, blockID caigorpc.BlockID) (*caigorpc.Block, error) + Call(context.Context, caigotypes.FunctionCall, caigorpc.BlockID) ([]string, error) + Events(ctx context.Context, input caigorpc.EventsInput) (*caigorpc.EventsOutput, error) + TransactionByHash(context.Context, caigotypes.Felt) (caigorpc.Transaction, error) + TransactionReceipt(context.Context, caigotypes.Felt) (caigorpc.TransactionReceipt, error) + AccountNonce(context.Context, caigotypes.Felt) (*big.Int, error) } type Writer interface { - AccountNonce(context.Context, caigotypes.Hash) (*big.Int, error) - Invoke(context.Context, caigotypes.FunctionInvoke) (*caigotypes.AddInvokeTransactionOutput, error) - TransactionByHash(context.Context, string) (*caigogw.Transaction, error) - TransactionReceipt(context.Context, string) (*caigogw.TransactionReceipt, error) - EstimateFee(context.Context, caigotypes.FunctionInvoke, string) (*caigotypes.FeeEstimate, error) } type ReaderWriter interface { @@ -45,16 +43,22 @@ var _ ReaderWriter = (*Client)(nil) // var _ caigotypes.Provider = (*Client)(nil) type Client struct { - Gw *caigogw.GatewayProvider + Provider *caigorpc.Provider lggr logger.Logger defaultTimeout time.Duration } // pass nil or 0 to timeout to not use built in default timeout -func NewClient(chainID string, baseURL string, lggr logger.Logger, timeout *time.Duration) (*Client, error) { +func NewClient(_chainID string, baseURL string, lggr logger.Logger, timeout *time.Duration) (*Client, error) { + // TODO: chainID now unused + c, err := ethrpc.DialContext(context.Background(), baseURL) + if err != nil { + return nil, err + } + client := &Client{ - Gw: caigogw.NewProvider(caigogw.WithChain(chainID)), - lggr: lggr, + Provider: caigorpc.NewProvider(c), + lggr: lggr, } // make copy to preserve value @@ -65,23 +69,9 @@ func NewClient(chainID string, baseURL string, lggr logger.Logger, timeout *time client.defaultTimeout = *timeout } - client.set(baseURL, chainID) // hack: change the base URL & chainID (not supported in caigo) - return client, nil } -func (c *Client) set(baseURL, chainID string) { - if chainID != "" { - c.Gw.Gateway.ChainId = chainID // note: gateway API in caigo does not query endpoint, uses what is set - } - - if baseURL != "" { - c.Gw.Gateway.Base = baseURL - c.Gw.Gateway.Feeder = baseURL + "/feeder_gateway" - c.Gw.Gateway.Gateway = baseURL + "/gateway" - } -} - // -- Custom Wrapped Func -- func (c *Client) CallContract(ctx context.Context, ops CallOps) (res []string, err error) { @@ -91,7 +81,7 @@ func (c *Client) CallContract(ctx context.Context, ops CallOps) (res []string, e Calldata: ops.Calldata, } - res, err = c.Call(ctx, tx, "") + res, err = c.Call(ctx, tx, caigorpc.WithBlockTag("pending")) if err != nil { return res, errors.Wrap(err, "error in client.CallContract") } @@ -106,79 +96,38 @@ func (c *Client) LatestBlockHeight(ctx context.Context) (height uint64, err erro defer cancel() } - block, err := c.Gw.Block(ctx, &caigogw.BlockOptions{Tag: "latest"}) + blockNum, err := c.Provider.BlockNumber(ctx) if err != nil { return height, errors.Wrap(err, "error in client.LatestBlockHeight") } - return uint64(block.BlockNumber), nil -} - -func (c *Client) BlockByNumberGateway(ctx context.Context, blockNum uint64) (block *caigogw.Block, err error) { - if c.defaultTimeout != 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(ctx, c.defaultTimeout) - defer cancel() - } - - block, err = c.Gw.Block(ctx, &caigogw.BlockOptions{ - BlockNumber: &blockNum, - }) - if err != nil { - return block, errors.Wrap(err, "couldn't get block by number") - } - if block == nil { - return block, NilResultError("client.BlockByNumberGateway") - } - - return block, nil + return blockNum, nil } // -- caigo.Provider interface -- -func (c *Client) BlockByHash(ctx context.Context, hash string, _ string) (*caigogw.Block, error) { - if c.defaultTimeout != 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(ctx, c.defaultTimeout) - defer cancel() - } - - out, err := c.Gw.BlockByHash(ctx, hash, "") - if err != nil { - return out, errors.Wrap(err, "error in client.BlockByHash") - } - if out == nil { - return out, NilResultError("client.BlockByHash") - } - return out, nil -} - -func (c *Client) BlockByNumber(ctx context.Context, num *big.Int, _ string) (*caigogw.Block, error) { +func (c *Client) BlockWithTxHashes(ctx context.Context, blockID caigorpc.BlockID) (*caigorpc.Block, error) { if c.defaultTimeout != 0 { var cancel context.CancelFunc ctx, cancel = context.WithTimeout(ctx, c.defaultTimeout) defer cancel() } - out, err := c.Gw.BlockByNumber(ctx, num, "") + out, err := c.Provider.BlockWithTxHashes(ctx, blockID) if err != nil { - return out, errors.Wrap(err, "error in client.BlockByNumber") - } - if out == nil { - return out, NilResultError("client.BlockByNumber") + return out.(*caigorpc.Block), errors.Wrap(err, "error in client.BlockWithTxHashes") } - return out, nil - + return out.(*caigorpc.Block), nil } -func (c *Client) Call(ctx context.Context, calls caigotypes.FunctionCall, blockHashOrTag string) ([]string, error) { +func (c *Client) Call(ctx context.Context, calls caigotypes.FunctionCall, blockHashOrTag caigorpc.BlockID) ([]string, error) { if c.defaultTimeout != 0 { var cancel context.CancelFunc ctx, cancel = context.WithTimeout(ctx, c.defaultTimeout) defer cancel() } - out, err := c.Gw.Call(ctx, calls, blockHashOrTag) + out, err := c.Provider.Call(ctx, calls, blockHashOrTag) if err != nil { return out, errors.Wrap(err, "error in client.Call") } @@ -189,109 +138,70 @@ func (c *Client) Call(ctx context.Context, calls caigotypes.FunctionCall, blockH } -func (c *Client) ChainID(ctx context.Context) (string, error) { +func (c *Client) TransactionByHash(ctx context.Context, hash caigotypes.Felt) (caigorpc.Transaction, error) { if c.defaultTimeout != 0 { var cancel context.CancelFunc ctx, cancel = context.WithTimeout(ctx, c.defaultTimeout) defer cancel() } - out, err := c.Gw.ChainID(ctx) + out, err := c.Provider.TransactionByHash(ctx, hash) if err != nil { - return out, errors.Wrap(err, "error in client.ChainID") - } - return out, nil - -} - -func (c *Client) AccountNonce(ctx context.Context, address caigotypes.Hash) (*big.Int, error) { - if c.defaultTimeout != 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(ctx, c.defaultTimeout) - defer cancel() - } - - out, err := c.Gw.Nonce(ctx, address.String(), "") - if err != nil { - return out, errors.Wrap(err, "error in client.AccountNonce") - } - - if out == nil { - return out, NilResultError("client.AccountNonce") - } - - return out, nil - -} - -func (c *Client) Invoke(ctx context.Context, invoke caigotypes.FunctionInvoke) (*caigotypes.AddInvokeTransactionOutput, error) { - if c.defaultTimeout != 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(ctx, c.defaultTimeout) - defer cancel() - } - - out, err := c.Gw.Invoke(ctx, invoke) - if err != nil { - return out, errors.Wrap(err, "error in client.Invoke") + return out, errors.Wrap(err, "error in client.TransactionByHash") } if out == nil { - return out, NilResultError("client.Invoke") + return out, NilResultError("client.TransactionByHash") } return out, nil } -func (c *Client) TransactionByHash(ctx context.Context, hash string) (*caigogw.Transaction, error) { +func (c *Client) TransactionReceipt(ctx context.Context, hash caigotypes.Felt) (caigorpc.TransactionReceipt, error) { if c.defaultTimeout != 0 { var cancel context.CancelFunc ctx, cancel = context.WithTimeout(ctx, c.defaultTimeout) defer cancel() } - out, err := c.Gw.TransactionByHash(ctx, hash) + out, err := c.Provider.TransactionReceipt(ctx, hash) if err != nil { - return out, errors.Wrap(err, "error in client.TransactionByHash") + return out, errors.Wrap(err, "error in client.TransactionReceipt") } if out == nil { - return out, NilResultError("client.TransactionByHash") + return out, NilResultError("client.TransactionReceipt") } return out, nil } -func (c *Client) TransactionReceipt(ctx context.Context, hash string) (*caigogw.TransactionReceipt, error) { +func (c *Client) Events(ctx context.Context, input caigorpc.EventsInput) (*caigorpc.EventsOutput, error) { if c.defaultTimeout != 0 { var cancel context.CancelFunc ctx, cancel = context.WithTimeout(ctx, c.defaultTimeout) defer cancel() } - out, err := c.Gw.TransactionReceipt(ctx, hash) + out, err := c.Provider.Events(ctx, input) if err != nil { - return out, errors.Wrap(err, "error in client.TransactionReceipt") + return out, errors.Wrap(err, "error in client.Events") } if out == nil { - return out, NilResultError("client.TransactionReceipt") + return out, NilResultError("client.Events") } return out, nil } - -func (c *Client) EstimateFee(ctx context.Context, call caigotypes.FunctionInvoke, hash string) (*caigotypes.FeeEstimate, error) { +func (c *Client) AccountNonce(ctx context.Context, accountAddress caigotypes.Felt) (*big.Int, error) { if c.defaultTimeout != 0 { var cancel context.CancelFunc ctx, cancel = context.WithTimeout(ctx, c.defaultTimeout) defer cancel() } - out, err := c.Gw.EstimateFee(ctx, call, hash) + sender := caigotypes.BigToFelt(big.NewInt((0))) // not actually used in account.Nonce() + account, err := caigo.NewRPCAccount(sender, accountAddress, nil, c.Provider, caigo.AccountVersion1) if err != nil { - return out, errors.Wrap(err, "error in client.EstimateFee") + return nil, errors.Wrap(err, "error in client.AccountNonce") } - if out == nil { - return out, NilResultError("client.EstimateFee") - } - return out, nil - + return account.Nonce(ctx) } diff --git a/relayer/pkg/starknet/client_test.go b/relayer/pkg/starknet/client_test.go index 0015c5896..d79e6a62c 100644 --- a/relayer/pkg/starknet/client_test.go +++ b/relayer/pkg/starknet/client_test.go @@ -2,13 +2,16 @@ package starknet import ( "context" + "encoding/json" + "fmt" + "io" "net/http" "net/http/httptest" - "sync" "testing" "time" "github.com/smartcontractkit/caigo/gateway" + caigotypes "github.com/smartcontractkit/caigo/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -20,13 +23,32 @@ var ( timeout = 10 * time.Second ) -func TestGatewayClient(t *testing.T) { - var wg sync.WaitGroup - wg.Add(1) // mock endpoint only called once +func TestRPCClient(t *testing.T) { mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - _, err := w.Write([]byte(`{"parent_block_hash": "0x0", "status": "ACCEPTED_ON_L2", "timestamp": 1660840417, "gas_price": "0x174876e800", "sequencer_address": "0x4bbfb0d1aab5bf33eec5ada3a1040c41ed902a1eeb38c78a753d6f6359f1666", "transactions": [], "transaction_receipts": [], "state_root": "030c9b7339aabef2d6c293c40d4f0ec6ffae303cb7df5b705dce7acc00306b06", "starknet_version": "0.9.1", "block_hash": "0x0", "block_number": 0}`)) + req, _ := io.ReadAll(r.Body) + fmt.Println(r.RequestURI, r.URL, string(req)) + + var out []byte + + type Call struct { + Method string `json:"method"` + Params []json.RawMessage `json:"params"` + } + + call := Call{} + require.NoError(t, json.Unmarshal(req, &call)) + + switch call.Method { + case "starknet_chainId": + id := caigotypes.BigToHex(caigotypes.UTF8StrToBig(chainID)) + out = []byte(fmt.Sprintf(`{"result": "%s"}`, id)) + case "starknet_blockNumber": + out = []byte(`{"result": 1}`) + default: + require.False(t, true, "unsupported RPC method") + } + _, err := w.Write(out) require.NoError(t, err) - wg.Done() })) defer mockServer.Close() @@ -35,35 +57,16 @@ func TestGatewayClient(t *testing.T) { require.NoError(t, err) assert.Equal(t, timeout, client.defaultTimeout) - // does not call endpoint - chainID returned from gateway client t.Run("get chain id", func(t *testing.T) { - id, err := client.ChainID(context.Background()) - assert.NoError(t, err) - assert.Equal(t, id, chainID) + // TODO: mock the chainID query + id, err := client.Provider.ChainID(context.Background()) + require.NoError(t, err) + assert.Equal(t, chainID, id) }) t.Run("get block height", func(t *testing.T) { - _, err := client.LatestBlockHeight(context.Background()) + blockNum, err := client.LatestBlockHeight(context.Background()) assert.NoError(t, err) + assert.Equal(t, uint64(1), blockNum) }) - wg.Wait() -} - -func TestGatewayClient_DefaultTimeout(t *testing.T) { - client, err := NewClient(gateway.GOERLI_ID, "", logger.Test(t), nil) - require.NoError(t, err) - assert.Zero(t, client.defaultTimeout) -} - -func TestGatewayClient_CustomURLChainID(t *testing.T) { - client, err := NewClient("test", "test", logger.Test(t), nil) - require.NoError(t, err) - - id, err := client.ChainID(context.TODO()) - require.NoError(t, err) - assert.Equal(t, "test", id) - - assert.Equal(t, "test", client.Gw.Gateway.Base) - assert.Equal(t, "test/feeder_gateway", client.Gw.Gateway.Feeder) - assert.Equal(t, "test/gateway", client.Gw.Gateway.Gateway) } diff --git a/relayer/pkg/starknet/events.go b/relayer/pkg/starknet/events.go deleted file mode 100644 index 0b64464ff..000000000 --- a/relayer/pkg/starknet/events.go +++ /dev/null @@ -1,12 +0,0 @@ -package starknet - -import ( - caigogw "github.com/smartcontractkit/caigo/gateway" - caigotypes "github.com/smartcontractkit/caigo/types" -) - -func IsEventFromContract(event *caigogw.Event, address caigotypes.Hash, eventName string) bool { - eventKey := caigotypes.GetSelectorFromName(eventName) - // encoded event name guaranteed to be at index 0 - return CompareAddress(event.FromAddress, address.String()) && event.Keys[0].Cmp(eventKey) == 0 -} diff --git a/relayer/pkg/starknet/events_test.go b/relayer/pkg/starknet/events_test.go deleted file mode 100644 index 227a9282a..000000000 --- a/relayer/pkg/starknet/events_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package starknet - -import ( - "testing" - - caigogw "github.com/smartcontractkit/caigo/gateway" - caigotypes "github.com/smartcontractkit/caigo/types" - "github.com/stretchr/testify/assert" -) - -var ( - testEventSelector = "transfer" -) - -func TestIsEventFromContract(t *testing.T) { - event := caigogw.Event{ - Order: 0, - FromAddress: "0x00", - Keys: []*caigotypes.Felt{caigotypes.BigToFelt(caigotypes.GetSelectorFromName(testEventSelector))}, - Data: []*caigotypes.Felt{}, - } - - // test zeros - assert.True(t, IsEventFromContract(&event, caigotypes.HexToHash("0x000000"), testEventSelector)) - - // test mismatch selector - assert.False(t, IsEventFromContract(&event, caigotypes.HexToHash("0x00"), "bad_selector")) - - // test mismatch addresses - event.FromAddress = "0x00002432012bcda2bfa339c51b3be731118f2bd3bac6b63c5ca664c154bf636f" - assert.False(t, IsEventFromContract(&event, caigotypes.HexToHash("0x3002432012bcda2bfa339c51b3be731118f2bd3bac6b63c5ca664c154bf6"), testEventSelector)) - - // test different length addresses - assert.True(t, IsEventFromContract(&event, caigotypes.HexToHash("0x2432012bcda2bfa339c51b3be731118f2bd3bac6b63c5ca664c154bf636f"), testEventSelector)) -} diff --git a/relayer/pkg/starknet/mocks/Reader.go b/relayer/pkg/starknet/mocks/Reader.go index e78c9fad4..5d0bcfeb1 100644 --- a/relayer/pkg/starknet/mocks/Reader.go +++ b/relayer/pkg/starknet/mocks/Reader.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.28.1. DO NOT EDIT. +// Code generated by mockery v2.29.0. DO NOT EDIT. package mocks @@ -6,10 +6,10 @@ import ( context "context" big "math/big" - gateway "github.com/smartcontractkit/caigo/gateway" - mock "github.com/stretchr/testify/mock" + rpcv02 "github.com/smartcontractkit/caigo/rpcv02" + starknet "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/starknet" types "github.com/smartcontractkit/caigo/types" @@ -20,51 +20,25 @@ type Reader struct { mock.Mock } -// BlockByHash provides a mock function with given fields: _a0, _a1, _a2 -func (_m *Reader) BlockByHash(_a0 context.Context, _a1 string, _a2 string) (*gateway.Block, error) { - ret := _m.Called(_a0, _a1, _a2) - - var r0 *gateway.Block - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string, string) (*gateway.Block, error)); ok { - return rf(_a0, _a1, _a2) - } - if rf, ok := ret.Get(0).(func(context.Context, string, string) *gateway.Block); ok { - r0 = rf(_a0, _a1, _a2) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*gateway.Block) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok { - r1 = rf(_a0, _a1, _a2) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// BlockByNumber provides a mock function with given fields: _a0, _a1, _a2 -func (_m *Reader) BlockByNumber(_a0 context.Context, _a1 *big.Int, _a2 string) (*gateway.Block, error) { - ret := _m.Called(_a0, _a1, _a2) +// AccountNonce provides a mock function with given fields: _a0, _a1 +func (_m *Reader) AccountNonce(_a0 context.Context, _a1 types.Felt) (*big.Int, error) { + ret := _m.Called(_a0, _a1) - var r0 *gateway.Block + var r0 *big.Int var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *big.Int, string) (*gateway.Block, error)); ok { - return rf(_a0, _a1, _a2) + if rf, ok := ret.Get(0).(func(context.Context, types.Felt) (*big.Int, error)); ok { + return rf(_a0, _a1) } - if rf, ok := ret.Get(0).(func(context.Context, *big.Int, string) *gateway.Block); ok { - r0 = rf(_a0, _a1, _a2) + if rf, ok := ret.Get(0).(func(context.Context, types.Felt) *big.Int); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*gateway.Block) + r0 = ret.Get(0).(*big.Int) } } - if rf, ok := ret.Get(1).(func(context.Context, *big.Int, string) error); ok { - r1 = rf(_a0, _a1, _a2) + if rf, ok := ret.Get(1).(func(context.Context, types.Felt) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -72,25 +46,25 @@ func (_m *Reader) BlockByNumber(_a0 context.Context, _a1 *big.Int, _a2 string) ( return r0, r1 } -// BlockByNumberGateway provides a mock function with given fields: _a0, _a1 -func (_m *Reader) BlockByNumberGateway(_a0 context.Context, _a1 uint64) (*gateway.Block, error) { - ret := _m.Called(_a0, _a1) +// BlockWithTxHashes provides a mock function with given fields: ctx, blockID +func (_m *Reader) BlockWithTxHashes(ctx context.Context, blockID rpcv02.BlockID) (*rpcv02.Block, error) { + ret := _m.Called(ctx, blockID) - var r0 *gateway.Block + var r0 *rpcv02.Block var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uint64) (*gateway.Block, error)); ok { - return rf(_a0, _a1) + if rf, ok := ret.Get(0).(func(context.Context, rpcv02.BlockID) (*rpcv02.Block, error)); ok { + return rf(ctx, blockID) } - if rf, ok := ret.Get(0).(func(context.Context, uint64) *gateway.Block); ok { - r0 = rf(_a0, _a1) + if rf, ok := ret.Get(0).(func(context.Context, rpcv02.BlockID) *rpcv02.Block); ok { + r0 = rf(ctx, blockID) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*gateway.Block) + r0 = ret.Get(0).(*rpcv02.Block) } } - if rf, ok := ret.Get(1).(func(context.Context, uint64) error); ok { - r1 = rf(_a0, _a1) + if rf, ok := ret.Get(1).(func(context.Context, rpcv02.BlockID) error); ok { + r1 = rf(ctx, blockID) } else { r1 = ret.Error(1) } @@ -99,15 +73,15 @@ func (_m *Reader) BlockByNumberGateway(_a0 context.Context, _a1 uint64) (*gatewa } // Call provides a mock function with given fields: _a0, _a1, _a2 -func (_m *Reader) Call(_a0 context.Context, _a1 types.FunctionCall, _a2 string) ([]string, error) { +func (_m *Reader) Call(_a0 context.Context, _a1 types.FunctionCall, _a2 rpcv02.BlockID) ([]string, error) { ret := _m.Called(_a0, _a1, _a2) var r0 []string var r1 error - if rf, ok := ret.Get(0).(func(context.Context, types.FunctionCall, string) ([]string, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.FunctionCall, rpcv02.BlockID) ([]string, error)); ok { return rf(_a0, _a1, _a2) } - if rf, ok := ret.Get(0).(func(context.Context, types.FunctionCall, string) []string); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.FunctionCall, rpcv02.BlockID) []string); ok { r0 = rf(_a0, _a1, _a2) } else { if ret.Get(0) != nil { @@ -115,7 +89,7 @@ func (_m *Reader) Call(_a0 context.Context, _a1 types.FunctionCall, _a2 string) } } - if rf, ok := ret.Get(1).(func(context.Context, types.FunctionCall, string) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, types.FunctionCall, rpcv02.BlockID) error); ok { r1 = rf(_a0, _a1, _a2) } else { r1 = ret.Error(1) @@ -150,23 +124,25 @@ func (_m *Reader) CallContract(_a0 context.Context, _a1 starknet.CallOps) ([]str return r0, r1 } -// ChainID provides a mock function with given fields: _a0 -func (_m *Reader) ChainID(_a0 context.Context) (string, error) { - ret := _m.Called(_a0) +// Events provides a mock function with given fields: ctx, input +func (_m *Reader) Events(ctx context.Context, input rpcv02.EventsInput) (*rpcv02.EventsOutput, error) { + ret := _m.Called(ctx, input) - var r0 string + var r0 *rpcv02.EventsOutput var r1 error - if rf, ok := ret.Get(0).(func(context.Context) (string, error)); ok { - return rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, rpcv02.EventsInput) (*rpcv02.EventsOutput, error)); ok { + return rf(ctx, input) } - if rf, ok := ret.Get(0).(func(context.Context) string); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, rpcv02.EventsInput) *rpcv02.EventsOutput); ok { + r0 = rf(ctx, input) } else { - r0 = ret.Get(0).(string) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*rpcv02.EventsOutput) + } } - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, rpcv02.EventsInput) error); ok { + r1 = rf(ctx, input) } else { r1 = ret.Error(1) } @@ -198,6 +174,58 @@ func (_m *Reader) LatestBlockHeight(_a0 context.Context) (uint64, error) { return r0, r1 } +// TransactionByHash provides a mock function with given fields: _a0, _a1 +func (_m *Reader) TransactionByHash(_a0 context.Context, _a1 types.Felt) (rpcv02.Transaction, error) { + ret := _m.Called(_a0, _a1) + + var r0 rpcv02.Transaction + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, types.Felt) (rpcv02.Transaction, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, types.Felt) rpcv02.Transaction); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(rpcv02.Transaction) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, types.Felt) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// TransactionReceipt provides a mock function with given fields: _a0, _a1 +func (_m *Reader) TransactionReceipt(_a0 context.Context, _a1 types.Felt) (rpcv02.TransactionReceipt, error) { + ret := _m.Called(_a0, _a1) + + var r0 rpcv02.TransactionReceipt + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, types.Felt) (rpcv02.TransactionReceipt, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, types.Felt) rpcv02.TransactionReceipt); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(rpcv02.TransactionReceipt) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, types.Felt) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + type mockConstructorTestingTNewReader interface { mock.TestingT Cleanup(func()) diff --git a/relayer/pkg/starknet/types.go b/relayer/pkg/starknet/types.go index 087dd53d5..8c949c307 100644 --- a/relayer/pkg/starknet/types.go +++ b/relayer/pkg/starknet/types.go @@ -5,7 +5,7 @@ import ( ) type CallOps struct { - ContractAddress caigotypes.Hash + ContractAddress caigotypes.Felt Selector string Calldata []string } diff --git a/relayer/pkg/starknet/utils.go b/relayer/pkg/starknet/utils.go index 6783a644d..8cc1c2ecc 100644 --- a/relayer/pkg/starknet/utils.go +++ b/relayer/pkg/starknet/utils.go @@ -1,7 +1,6 @@ package starknet import ( - "bytes" "encoding/hex" "fmt" "math/big" @@ -89,69 +88,41 @@ func DecodeFelts(felts []*big.Int) ([]byte, error) { return data, nil } -// SignedBigToFelt wraps negative values correctly into felt -func SignedBigToFelt(num *big.Int) *big.Int { - return new(big.Int).Mod(num, caigotypes.MaxFelt.Big()) -} - -// FeltToSigned unwraps felt into negative values -func FeltToSignedBig(felt *caigotypes.Felt) (num *big.Int) { +func FeltToUnsignedBig(felt caigotypes.Felt) (num *big.Int, err error) { num = felt.Big() - prime := caigotypes.MaxFelt.Big() - half := new(big.Int).Div(prime, big.NewInt(2)) - // if num > PRIME/2, then -PRIME to convert to negative value - if num.Cmp(half) > 0 { - return new(big.Int).Sub(num, prime) + if caigotypes.MaxFelt.Big().Cmp(num) == -1 { + return nil, fmt.Errorf("felt value is too large: %s", num) } - return num + // will always return a non-negative value because it uses Bytes() behind the scenes + return num, nil } -func HexToSignedBig(str string) (num *big.Int) { +func HexToUnsignedBig(str string) (num *big.Int, err error) { felt := caigotypes.StrToFelt(str) - return FeltToSignedBig(felt) + return FeltToUnsignedBig(felt) } -func FeltsToBig(in []*caigotypes.Felt) (out []*big.Int) { +func FeltsToBig(in []caigotypes.Felt) (out []*big.Int) { for _, f := range in { - out = append(out, f.Int) + out = append(out, f.Big()) } return out } // StringsToFelt maps felts from 'string' (hex) representation to 'caigo.Felt' representation -func StringsToFelt(in []string) (out []*caigotypes.Felt, _ error) { +func StringsToFelt(in []string) (out []caigotypes.Felt, _ error) { if in == nil { return nil, errors.New("invalid: input value") } for _, f := range in { - felt := caigotypes.StrToFelt(f) - if felt == nil { - return nil, errors.New("invalid: string value") - } - - out = append(out, felt) + out = append(out, caigotypes.StrToFelt(f)) } return out, nil } -// CompareAddress compares different hex starknet addresses with potentially different 0 padding -func CompareAddress(a, b string) bool { - aBytes, err := caigotypes.HexToBytes(a) - if err != nil { - return false - } - - bBytes, err := caigotypes.HexToBytes(b) - if err != nil { - return false - } - - return bytes.Equal(PadBytes(aBytes, 32), PadBytes(bBytes, 32)) -} - /* Testing utils - do not use (XXX) outside testing context */ func XXXMustHexDecodeString(data string) []byte { diff --git a/relayer/pkg/starknet/utils_test.go b/relayer/pkg/starknet/utils_test.go index 52aa50690..15d11ff8f 100644 --- a/relayer/pkg/starknet/utils_test.go +++ b/relayer/pkg/starknet/utils_test.go @@ -7,6 +7,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + caigotypes "github.com/smartcontractkit/caigo/types" ) var ( @@ -38,14 +40,26 @@ func TestPadBytes(t *testing.T) { } } -func TestHexToSignedBig(t *testing.T) { +func TestFeltToUnsignedBig(t *testing.T) { + + negativeBig := caigotypes.BigToFelt(big.NewInt(-100)) + // negative felts are not supported + num, err := FeltToUnsignedBig(negativeBig) + assert.NoError(t, err) + assert.Equal(t, num, big.NewInt(100)) + + positiveBig := caigotypes.BigToFelt(big.NewInt(100)) + num, err = FeltToUnsignedBig(positiveBig) + assert.NoError(t, err) + assert.Equal(t, num, big.NewInt(100)) + +} + +func TestHexToUnSignedBig(t *testing.T) { // Positive value (99) - answer := HexToSignedBig("0x63") + answer, err := HexToUnsignedBig("0x63") + assert.NoError(t, err) assert.Equal(t, big.NewInt(99), answer) - - // Negative value (-10) - answer = HexToSignedBig("0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffff7") - assert.Equal(t, big.NewInt(-10), answer) } func TestDecodeFeltFails(t *testing.T) { diff --git a/vendor/cairo b/vendor/cairo index 4e32aa52e..0f77760aa 160000 --- a/vendor/cairo +++ b/vendor/cairo @@ -1 +1 @@ -Subproject commit 4e32aa52e1109ffaf92543c1c526f0fb51ec462a +Subproject commit 0f77760aa2e7750b2dda7e708403584e3040b6ad diff --git a/vendor/scarb b/vendor/scarb index 0bccfe675..532d8e349 160000 --- a/vendor/scarb +++ b/vendor/scarb @@ -1 +1 @@ -Subproject commit 0bccfe6754ee91e0365a0854a38df2e4e2f6ff77 +Subproject commit 532d8e34955e41553e35aaa1b1f7c445b7ddb844 diff --git a/yarn.lock b/yarn.lock index bc67d0b9e..ac240aa59 100644 --- a/yarn.lock +++ b/yarn.lock @@ -272,6 +272,13 @@ dependencies: regenerator-runtime "^0.13.10" +"@babel/runtime@^7.15.4": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.6.tgz#57d64b9ae3cff1d67eb067ae117dac087f5bd438" + integrity sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ== + dependencies: + regenerator-runtime "^0.13.11" + "@babel/template@^7.18.10", "@babel/template@^7.3.3": version "7.18.10" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" @@ -319,10 +326,10 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@chainlink-dev/starkgate-open-zeppelin@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@chainlink-dev/starkgate-open-zeppelin/-/starkgate-open-zeppelin-0.5.0.tgz#9fea55dfb599b4de1e4608260968ddc2ab51c330" - integrity sha512-q9xslzDu4fclArGxH29pz8/u0VVp8kexhgpMC5nLb/NFQKcaHjBcm20zbaURrTTWTUeQRW4eVgIXyduFkWVjtw== +"@chainlink-dev/starkgate-open-zeppelin@^0.6.1": + version "0.6.1" + resolved "https://registry.yarnpkg.com/@chainlink-dev/starkgate-open-zeppelin/-/starkgate-open-zeppelin-0.6.1.tgz#00ff367defcff07e4351ea0a8a7eedaaa8d657fd" + integrity sha512-Iv0ML3XquBVSJ4OISlyuCyzw44Jor0Ls8Zqoa/zq6cNL0gBXTbiGv/p53fCykTBVcjFVGwnFeXhmy1Avlwlh6w== "@chainlink/contracts@^0.4.2": version "0.4.2" @@ -1035,6 +1042,11 @@ "@ethersproject/properties" "^5.7.0" "@ethersproject/strings" "^5.7.0" +"@iarna/toml@^2.2.5": + version "2.2.5" + resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.5.tgz#b32366c89b43c6f8cefbdefac778b9c828e3ba8c" + integrity sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg== + "@isaacs/cliui@^8.0.2": version "8.0.2" resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" @@ -1400,13 +1412,6 @@ tweetnacl "^1.0.3" tweetnacl-util "^0.15.1" -"@noble/curves@^0.8.2": - version "0.8.3" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-0.8.3.tgz#ad6d48baf2599cf1d58dcb734c14d5225c8996e0" - integrity sha512-OqaOf4RWDaCRuBKJLDURrgVxjLmneGsiCXGuzYB5y95YithZMA6w4uk34DHSm0rKMrrYiaeZj48/81EvaAScLQ== - dependencies: - "@noble/hashes" "1.3.0" - "@noble/curves@~1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.0.0.tgz#e40be8c7daf088aaf291887cbc73f43464a92932" @@ -1419,11 +1424,16 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12" integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ== -"@noble/hashes@1.3.0", "@noble/hashes@~1.3.0": +"@noble/hashes@1.3.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1" integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg== +"@noble/hashes@~1.3.0": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" + integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== + "@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": version "1.7.1" resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" @@ -1829,12 +1839,14 @@ tslib "^1.9.3" "@shardlabs/starknet-hardhat-plugin@^0.8.0-alpha.2": - version "0.8.0-alpha.2" - resolved "https://registry.yarnpkg.com/@shardlabs/starknet-hardhat-plugin/-/starknet-hardhat-plugin-0.8.0-alpha.2.tgz#74eae89bd283f0419aa5577d5b872c6483a62429" - integrity sha512-985y7GON4/1UjCCiBwIyTJVTwcSFwbkMf3ect5F0rz2h0n9mnjfimvo63+hMLivuwMyLYuK0ddtoSD+EVsYywA== + version "0.8.0-alpha.3" + resolved "https://registry.yarnpkg.com/@shardlabs/starknet-hardhat-plugin/-/starknet-hardhat-plugin-0.8.0-alpha.3.tgz#dc7528d8a385d9bfec560a0d98e0ee246885a58c" + integrity sha512-rVVzR7yNe4q9Z7VBJLSbHlnTCYS6/wH/HlpIAajBsDzB1sKh4GUyPctTHMkLKCA7Ke4lf3Kryff1myxGXPsnNg== dependencies: + "@iarna/toml" "^2.2.5" "@nomiclabs/hardhat-docker" "^2.0.2" axios "^1.0.0" + axios-retry "^3.5.0" exit-hook "2.2.1" form-data "^4.0.0" glob "^10.0.0" @@ -2028,9 +2040,9 @@ integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== "@types/node@*": - version "18.15.12" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.12.tgz#833756634e78c829e1254db006468dadbb0c696b" - integrity sha512-Wha1UwsB3CYdqUm2PPzh/1gujGCNtWVUYF0mB00fJFoR4gTyWTDPjSm+zBF787Ahw8vSGgBja90MkgFwvB86Dg== + version "20.4.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.5.tgz#9dc0a5cb1ccce4f7a731660935ab70b9c00a5d69" + integrity sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg== "@types/node@>=13.7.0": version "18.11.2" @@ -2362,6 +2374,14 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== +axios-retry@^3.5.0: + version "3.5.1" + resolved "https://registry.yarnpkg.com/axios-retry/-/axios-retry-3.5.1.tgz#d902f69fe1b2a71902e29605318f887bef0981c6" + integrity sha512-mQRJ4IyAUnYig14BQ4MnnNHHuH1cNH7NW4JxEUD6mNJwK6pwOY66wKLCwZ6Y0o3POpfStalqRC+J4+Hnn6Om7w== + dependencies: + "@babel/runtime" "^7.15.4" + is-retry-allowed "^2.2.0" + axios@^0.24.0: version "0.24.0" resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6" @@ -2468,9 +2488,9 @@ better-path-resolve@1.0.0: is-windows "^1.0.0" bigint-crypto-utils@^3.0.23: - version "3.2.2" - resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.2.2.tgz#e30a49ec38357c6981cd3da5aaa6480b1f752ee4" - integrity sha512-U1RbE3aX9ayCUVcIPHuPDPKcK3SFOXf93J1UK/iHlJuQB7bhagPIX06/CLpLEsDThJ7KA4Dhrnzynl+d2weTiw== + version "3.3.0" + resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz#72ad00ae91062cf07f2b1def9594006c279c1d77" + integrity sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg== bignumber.js@^9.0.0: version "9.1.1" @@ -3958,12 +3978,13 @@ get-func-name@^2.0.0: integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig== get-intrinsic@^1.0.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" - integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== + version "1.2.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" + integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== dependencies: function-bind "^1.1.1" has "^1.0.3" + has-proto "^1.0.1" has-symbols "^1.0.3" get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: @@ -4038,15 +4059,15 @@ glob@7.2.0: path-is-absolute "^1.0.0" glob@^10.0.0: - version "10.2.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.2.2.tgz#ce2468727de7e035e8ecf684669dc74d0526ab75" - integrity sha512-Xsa0BcxIC6th9UwNjZkhrMtNo/MnyRL8jGCP+uEwhA5oFOCY1f2s1/oNKY47xQ0Bg5nkjsfAEIej1VeH62bDDQ== + version "10.3.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.3.tgz#8360a4ffdd6ed90df84aa8d52f21f452e86a123b" + integrity sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw== dependencies: foreground-child "^3.1.0" jackspeak "^2.0.3" - minimatch "^9.0.0" - minipass "^5.0.0" - path-scurry "^1.7.0" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" glob@^5.0.15: version "5.0.15" @@ -4170,9 +4191,9 @@ hard-rejection@^2.1.0: integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== hardhat@^*, hardhat@^2.10.2: - version "2.14.0" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.14.0.tgz#b60c74861494aeb1b50803cf04cc47865a42b87a" - integrity sha512-73jsInY4zZahMSVFurSK+5TNCJTXMv+vemvGia0Ac34Mm19fYp6vEPVGF3sucbumszsYxiTT2TbS8Ii2dsDSoQ== + version "2.17.0" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.17.0.tgz#574478790fa4f4a45c5ccf162e82e54f36671749" + integrity sha512-CaEGa13tkJNe2/rdaBiive4pmdNShwxvdWVhr1zfb6aVpRhQt9VNO0l/UIBt/zzajz38ZFjvhfM2bj8LDXo9gw== dependencies: "@ethersproject/abi" "^5.1.2" "@metamask/eth-sig-util" "^4.0.0" @@ -4213,7 +4234,6 @@ hardhat@^*, hardhat@^2.10.2: mnemonist "^0.38.0" mocha "^10.0.0" p-map "^4.0.0" - qs "^6.7.0" raw-body "^2.4.1" resolve "1.17.0" semver "^6.3.0" @@ -4379,9 +4399,9 @@ ignore@^5.2.0: integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== immutable@^4.0.0-rc.12: - version "4.3.0" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.0.tgz#eb1738f14ffb39fd068b1dbe1296117484dd34be" - integrity sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg== + version "4.3.1" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.1.tgz#17988b356097ab0719e2f741d56f3ec6c317f9dc" + integrity sha512-lj9cnmB/kVS0QHsJnYKD1uo3o39nrbKxszjnqS9Fr6NB7bZzW45U6WSGBPKXDL/CvDKqDNPA4r3DoDQ8GTxo2A== import-local@^3.0.2: version "3.1.0" @@ -4517,10 +4537,10 @@ is-core-module@2.9.0: dependencies: has "^1.0.3" -is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== +is-core-module@^2.11.0, is-core-module@^2.9.0: + version "2.12.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" + integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== dependencies: has "^1.0.3" @@ -4605,6 +4625,11 @@ is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-retry-allowed@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz#88f34cbd236e043e71b6932d09b0c65fb7b4d71d" + integrity sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg== + is-shared-array-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" @@ -4732,9 +4757,9 @@ istanbul-reports@^3.1.3: istanbul-lib-report "^3.0.0" jackspeak@^2.0.3: - version "2.2.0" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.2.0.tgz#497cbaedc902ec3f31d5d61be804d2364ff9ddad" - integrity sha512-r5XBrqIJfwRIjRt/Xr5fv9Wh09qyhHfKnYddDlpM+ibRR20qrYActpCAgU6U+d53EOEjzkvxPMVHSlgR7leXrQ== + version "2.2.2" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.2.2.tgz#707c62733924b8dc2a0a629dc6248577788b5385" + integrity sha512-mgNtVv4vUuaKA97yxUHoA3+FkuhtxkjdXEWOyB/N76fjy0FjezEt34oy3epBtvCvS+7DyKwqCFWx/oJLV5+kCg== dependencies: "@isaacs/cliui" "^8.0.2" optionalDependencies: @@ -5099,9 +5124,9 @@ jest@^28.1.0: jest-cli "^28.1.3" js-sdsl@^4.1.4: - version "4.4.0" - resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.0.tgz#8b437dbe642daa95760400b602378ed8ffea8430" - integrity sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg== + version "4.4.2" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.2.tgz#2e3c031b1f47d3aca8b775532e3ebb0818e7f847" + integrity sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w== js-sha3@0.8.0, js-sha3@^0.8.0: version "0.8.0" @@ -5337,9 +5362,9 @@ long@^4.0.0: integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== lossless-json@^2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/lossless-json/-/lossless-json-2.0.8.tgz#dd0e14f7d327e9e11fe89123b583c011f2ad0917" - integrity sha512-7/GaZldUc7H5oNZlSk6bF06cRbtA7oF8zWXwbfMZm8yrYC2debx0KvWTBbQIbj6fh08LsXTWg+YtHJshXgYKow== + version "2.0.11" + resolved "https://registry.yarnpkg.com/lossless-json/-/lossless-json-2.0.11.tgz#3137684c93fd99481c6f99c985efc9c9c5cc76a5" + integrity sha512-BP0vn+NGYvzDielvBZaFain/wgeJ1hTvURCqtKvhr1SCPePdaaTanmmcplrHfEJSJOUql7hk4FHwToNJjWRY3g== loupe@^2.3.1: version "2.3.6" @@ -5370,10 +5395,10 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lru-cache@^9.0.0: - version "9.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-9.1.1.tgz#c58a93de58630b688de39ad04ef02ef26f1902f1" - integrity sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A== +"lru-cache@^9.1.1 || ^10.0.0": + version "10.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.0.tgz#b9e2a6a72a129d81ab317202d93c7691df727e61" + integrity sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw== lru_map@^0.3.3: version "0.3.3" @@ -5464,7 +5489,7 @@ merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -micro-starknet@^0.2.1: +micro-starknet@~0.2.1: version "0.2.3" resolved "https://registry.yarnpkg.com/micro-starknet/-/micro-starknet-0.2.3.tgz#ff4e7caf599255d2110e9c57bb483dfaf493ccb3" integrity sha512-6XBcC+GerlwJSR4iA0VaeXtS2wrayWFcA4PEzrJPMuFmWCaUtuGIq5K/DB5F/XgnL54/zl2Bxo690Lj7mYVA8A== @@ -5538,10 +5563,10 @@ minimatch@5.0.1: dependencies: brace-expansion "^2.0.1" -minimatch@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.0.tgz#bfc8e88a1c40ffd40c172ddac3decb8451503b56" - integrity sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w== +minimatch@^9.0.1: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== dependencies: brace-expansion "^2.0.1" @@ -5564,10 +5589,10 @@ minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -minipass@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" - integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": + version "7.0.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.2.tgz#58a82b7d81c7010da5bd4b2c0c85ac4b4ec5131e" + integrity sha512-eL79dXrE1q9dBbDCLg7xfn/vl7MS4F1gvJAgjJrQli/jbQWdUttuVawphqpffoIYfRdq78LHx6GP4bU/EQ2ATA== mixme@^0.5.1: version "0.5.4" @@ -5755,9 +5780,9 @@ node-fetch@2.6.7, node-fetch@^2.6.6: whatwg-url "^5.0.0" node-fetch@^2.6.0, node-fetch@^2.6.1: - version "2.6.9" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6" - integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== + version "2.6.12" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.12.tgz#02eb8e22074018e3d5a83016649d04df0e348fba" + integrity sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g== dependencies: whatwg-url "^5.0.0" @@ -6056,13 +6081,13 @@ path-parse@^1.0.6, path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-scurry@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.7.0.tgz#99c741a2cfbce782294a39994d63748b5a24f6db" - integrity sha512-UkZUeDjczjYRE495+9thsgcVgsaCPkaw80slmfVFgllxY+IO8ubTsOpFVjDPROBqJdHfVPUFRHPBV/WciOVfWg== +path-scurry@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" + integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== dependencies: - lru-cache "^9.0.0" - minipass "^5.0.0" + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" path-type@^4.0.0: version "4.0.0" @@ -6263,13 +6288,6 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -qs@^6.7.0: - version "6.11.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.1.tgz#6c29dff97f0c0060765911ba65cbc9764186109f" - integrity sha512-0wsrzgTz/kAVIeuxSjnpGC56rzYtr6JT/2BwEvMaPhFIoYa1aGO8LbzuU1R0uUYQkLpWBTOj0l/CLAJB64J6nQ== - dependencies: - side-channel "^1.0.4" - queue-microtask@^1.2.2, queue-microtask@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -6436,6 +6454,11 @@ regenerator-runtime@^0.13.10: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz#ed07b19616bcbec5da6274ebc75ae95634bfc2ee" integrity sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw== +regenerator-runtime@^0.13.11: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + regexp.prototype.flags@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" @@ -6489,7 +6512,16 @@ resolve@1.17.0: dependencies: path-parse "^1.0.6" -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.20.0, resolve@^1.22.0: +resolve@^1.1.6: + version "1.22.2" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" + integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== + dependencies: + is-core-module "^2.11.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +resolve@^1.10.0, resolve@^1.20.0, resolve@^1.22.0: version "1.22.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== @@ -6616,7 +6648,7 @@ secp256k1@^4.0.1: node-addon-api "^2.0.0" node-gyp-build "^4.2.0" -"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.7.0: +"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.7.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -6628,11 +6660,21 @@ semver@7.x, semver@^7.3.4, semver@^7.3.5: dependencies: lru-cache "^6.0.0" -semver@^6.0.0, semver@^6.3.0: +semver@^5.5.0: + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +semver@^6.0.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^6.3.0: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + serialize-javascript@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -6711,9 +6753,9 @@ signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== signal-exit@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.0.1.tgz#96a61033896120ec9335d96851d902cc98f0ba2a" - integrity sha512-uUWsN4aOxJAS8KOuf3QMyFtgm1pkb6I+KRZbRF/ghdf5T7sM+B1lLLzPDxswUjkmHyxQAVzEgG35E3NzDM9GVw== + version "4.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.0.2.tgz#ff55bb1d9ff2114c13b400688fa544ac63c36967" + integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== simple-concat@^1.0.0: version "1.0.1" @@ -6912,15 +6954,15 @@ starknet@^4.17.1, starknet@^4.22.0: ts-custom-error "^3.3.1" url-join "^4.0.1" -starknet@^5.10.0: - version "5.10.0" - resolved "https://registry.yarnpkg.com/starknet/-/starknet-5.10.0.tgz#e76dbd802b962b6daf7f5452795e3e332a50c56a" - integrity sha512-yN8mjUKI4nK4+SXdqXXL9H+6CRUWLmw2zCBrNgokwL19dXzim63eqwEBJdZZcSaE2GzAe4J9PqLPm4ri8Ews+Q== +starknet@^5.17.0: + version "5.17.0" + resolved "https://registry.yarnpkg.com/starknet/-/starknet-5.17.0.tgz#27660f06b61f6d131816f604bafd69cfa41f75c7" + integrity sha512-gvIgk63Le0QQ20mU5RVcckz0BLjnVG5Q1SWbapErAlWVY2xknpWnrNXIcCYYh0c6eKG0+ogirLyNqm40+U6yHg== dependencies: - "@noble/curves" "^0.8.2" + "@noble/curves" "~1.0.0" isomorphic-fetch "^3.0.0" lossless-json "^2.0.8" - micro-starknet "^0.2.1" + micro-starknet "~0.2.1" pako "^2.0.4" url-join "^4.0.1" @@ -7091,9 +7133,9 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: ansi-regex "^4.1.0" strip-ansi@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" - integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== dependencies: ansi-regex "^6.0.1" @@ -7449,9 +7491,9 @@ unbox-primitive@^1.0.2: which-boxed-primitive "^1.0.2" undici@^5.14.0: - version "5.21.2" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.21.2.tgz#329f628aaea3f1539a28b9325dccc72097d29acd" - integrity sha512-f6pTQ9RF4DQtwoWSaC42P/NKlUjvezVvd9r155ohqkwFNRyBKM3f3pcty3ouusefNRyM25XhIQEbeQ46sZDJfQ== + version "5.22.1" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.22.1.tgz#877d512effef2ac8be65e695f3586922e1a57d7b" + integrity sha512-Ji2IJhFXZY0x/0tVBXeQwgPlLWw13GVzpsWPQ3rV50IFMMof2I55PZZxtm4P6iNq+L5znYN9nSTAq0ZyE6lSJw== dependencies: busboy "^1.6.0" @@ -7561,9 +7603,9 @@ webidl-conversions@^3.0.0: integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== whatwg-fetch@^3.4.1: - version "3.6.2" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" - integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== + version "3.6.17" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.17.tgz#009bbbfc122b227b74ba1ff31536b3a1a0e0e212" + integrity sha512-c4ghIvG6th0eudYwKZY5keb81wtFz9/WeAHAoy8+r18kcWlitUIrmGFQ2rWEl4UCKUilD3zCLHOIPheHx5ypRQ== whatwg-url@^5.0.0: version "5.0.0"