diff --git a/packages/packages.json b/packages/packages.json index 212ea8a6..7e57d478 100644 --- a/packages/packages.json +++ b/packages/packages.json @@ -1,26 +1,27 @@ { "dev": { "contract/valory/keep3r_v1_library/0.1.0": "bafybeiguyavczsaebbh5docth3o6e36b24s46jynhvysewnk3hqim3a4qe", - "contract/valory/keep3r_test_job/0.1.0": "bafybeiey4oiqiugcbvvvxyy4pm7qhiidmxl22ilg4wmsvbfag2tjptvnrq", + "contract/valory/keep3r_test_job/0.1.0": "bafybeifdpote2zjamgsqc5ix24p4gppj3knb23uxckobr5za7p6gpjpoqa", "contract/valory/keep3r_v1/0.1.0": "bafybeidbdfpmzxyw5n47nstnoxhwmtph7nysdiou5snabtpcjsykopwr24", - "skill/valory/keep3r_job/0.1.0": "bafybeiflbm45r3gr2nv7pebwwq2vbapy7okoqj57nynfsq6m3yzghsbjka", - "skill/valory/keep3r_abci/0.1.0": "bafybeihakxp2zvfmvynybkciuf5tsbkdzaym7mbbulyo4itfsl7ou3ovve", - "agent/valory/keep3r_bot/0.1.0": "bafybeiczanoqalggxexil6b7ibikkfkyrmwxsj2okasdwootn53ehndgem", + "skill/valory/keep3r_job/0.1.0": "bafybeiezok7h2j7tjkzxpm4qk35rnszretvrkv3dzpqn3kuvbymlvstoua", + "skill/valory/keep3r_abci/0.1.0": "bafybeifm6xhwi47zkqxdtsoh2ich2xtdioqpx6jj3hgskoljo6q4zxaqzm", + "agent/valory/keep3r_bot/0.1.0": "bafybeiaudehe2roq4yauufe7x5lyy3t3h2db4cxkum4iy7g5bznf5mqn4y", "contract/valory/keep3r_job/0.1.0": "bafybeiajy32pvqdzbecg2obmlnzdg756srtsmfzn4ujl5ybclx4hfvceli", "contract/valory/keep3r_for_testnet/0.1.0": "bafybeifytr77v27emxwwoklkytt63h46z4ntedfrvop5tjdq2swxl2tkv4", - "contract/valory/deposit_manager_job/0.1.0": "bafybeihef6awneikf7vulps5vo25xjrbis6fuo5ol3zj67s5eeqr5ki24u", - "contract/valory/phuture_harvesting_job/0.1.0": "bafybeieby42jubdphepg54szpcltoxrirxriohxgobyjsjlop6mbxetlwq", - "contract/valory/keep3r_my_job/0.1.0": "bafybeica2bp4ahe3c4zrgjjo4t6ende7tdxeml63rtpp2d3fcvwif4b3dq", - "service/valory/keep3r_bot/0.1.0": "bafybeifljg667gwr3id3nvzdpynppuhjchc7oknmgz5m34txtxszrqlzwm", - "service/valory/keep3r_bot_goerli/0.1.0": "bafybeicy64ewk2r7pmlfswasyewbjortwtus4qf4khj43cjmeakd7verem", - "contract/valory/yearn_factory_harvest_job/0.1.0": "bafybeihdhbpuhopvf54y6agodpmyki7fgxhvtg2accsp3aqv37ryjqaghu", + "contract/valory/deposit_manager_job/0.1.0": "bafybeiaawvyxk75ljmf5bdlfofijl5a3ji4rc3aywpess56dmnho4vxzvm", + "contract/valory/phuture_harvesting_job/0.1.0": "bafybeieg2v6pztx4jlafdo3cdydrjnhgnxctbraticzs5dh3my3ue5ztue", + "contract/valory/keep3r_my_job/0.1.0": "bafybeicgw4mudefo3opa4udbw67qznfkqoewifg3dc2rwtayef7ctwakbq", + "service/valory/keep3r_bot/0.1.0": "bafybeib63p2dxexph77q22gw4erlzh5fuemmtv5t344tvekc47mcevrk6q", + "service/valory/keep3r_bot_goerli/0.1.0": "bafybeigge7ubbuld4lgs6tg6bhwb2ypzmarjuseh46jxapuo47bdwgc72m", + "contract/valory/yearn_factory_harvest_job/0.1.0": "bafybeiarfp4m4id77tsbpprcmcm5nv6ihwkeenrgrb6kth47uvkqhmh5za", "protocol/valory/ledger_api/1.0.0": "bafybeieylbg4qb3dmjlm3zufqcwq4qbygsdgj3jzc53eyoqmd25mdz2pkq", - "connection/valory/ledger/0.19.0": "bafybeiez7rieszhh3kmgvz6tvii2ysgx4lbyrhyfujrx3hkmj2gn52b6zu", - "skill/valory/abstract_round_abci/0.1.0": "bafybeibw7khdmdxinnugbjdirh5q4cb4rirf5aqzfj6ai6zbhe7aavr7gy", - "skill/valory/registration_abci/0.1.0": "bafybeigijk6tyixlbb3jhrlgxfzk7wqopegqbdbklflvor27n3ysu42zty", - "skill/valory/reset_pause_abci/0.1.0": "bafybeid4atrdi3mflnkg6hiylnmjbfqa323i3wkjhuj4jispxbchukwwiq", - "skill/valory/transaction_settlement_abci/0.1.0": "bafybeie6mefwzprsqd6n45aleswygs76oekvdlzblq72omjsjtmwdaqwly", - "skill/valory/termination_abci/0.1.0": "bafybeibluiaftasozzpixxhpdcqnxglpmmyfneya7qdi2lc4pnoqzzj7wq" + "connection/valory/ledger/0.19.0": "bafybeih4yf73bwvn3cn44b7on2riqe2lbvixcgw3nze63asvwbmyfqyrc4", + "skill/valory/abstract_round_abci/0.1.0": "bafybeibbxka2c4mvlo2msxi3wtk654fczkfcnbopftyskmd727pjpbty3e", + "skill/valory/registration_abci/0.1.0": "bafybeicjvmdle7qkrid6hpr4nepnvt6pl7oznntfhxy2ftrrciu5vb6sqm", + "skill/valory/reset_pause_abci/0.1.0": "bafybeiay3qgd7jp5xtxqxmbe2net2tm762av42nobosx4atxfjlbe665mi", + "skill/valory/transaction_settlement_abci/0.1.0": "bafybeie5lp57jwtum4uyq4rdkmoue442l6ssdjabi5rbc2di7wtzixw64i", + "skill/valory/termination_abci/0.1.0": "bafybeibpogd2xmkxby7qtst2jyftidnoxqaaaqmvohuphwlyf5tw6ztgwa", + "contract/valory/connext_propagate_job/0.1.0": "bafybeiesmwltwgyexwavl4x4kw37vwsn5igy5bkpwgn5jisombwfgojosq" }, "third_party": { "protocol/valory/abci/0.1.0": "bafybeig3dj5jhsowlvg3t73kgobf6xn4nka7rkttakdb2gwsg5bp7rt7q4", diff --git a/packages/valory/agents/keep3r_bot/aea-config.yaml b/packages/valory/agents/keep3r_bot/aea-config.yaml index 7ebe3b6c..2b2259e5 100644 --- a/packages/valory/agents/keep3r_bot/aea-config.yaml +++ b/packages/valory/agents/keep3r_bot/aea-config.yaml @@ -131,7 +131,7 @@ connections: - valory/abci:0.1.0:bafybeienpqzsym3rg7nnomd6mxgbt4didwd4wfj72oadde27trdmcgsu5y - valory/http_client:0.23.0:bafybeidykl4elwbcjkqn32wt5h4h7tlpeqovrcq3c5bcplt6nhpznhgczi - valory/ipfs:0.1.0:bafybeie46fu7mv64q72dwzoxg77zbiv3pzsigzjk3rehjpm47cf3y77mha -- valory/ledger:0.19.0:bafybeiez7rieszhh3kmgvz6tvii2ysgx4lbyrhyfujrx3hkmj2gn52b6zu +- valory/ledger:0.19.0:bafybeih4yf73bwvn3cn44b7on2riqe2lbvixcgw3nze63asvwbmyfqyrc4 - valory/p2p_libp2p_client:0.1.0:bafybeidwcobzb7ut3efegoedad7jfckvt2n6prcmd4g7xnkm6hp6aafrva contracts: - valory/gnosis_safe:0.1.0:bafybeicwzsjalj4puagecus525fbdusaljccn4fi62nmr4zp5fhim6oyr4 @@ -147,12 +147,12 @@ protocols: - valory/tendermint:0.1.0:bafybeicusvezoqlmyt6iqomcbwaz3xkhk2qf3d56q5zprmj3xdxfy64k54 skills: - valory/abstract_abci:0.1.0:bafybeigg5ofide2gxwgjvljjgpyy6ombby7ph6pg7erj3h6itduwpn6pqu -- valory/abstract_round_abci:0.1.0:bafybeibw7khdmdxinnugbjdirh5q4cb4rirf5aqzfj6ai6zbhe7aavr7gy -- valory/keep3r_abci:0.1.0:bafybeihakxp2zvfmvynybkciuf5tsbkdzaym7mbbulyo4itfsl7ou3ovve -- valory/keep3r_job:0.1.0:bafybeiflbm45r3gr2nv7pebwwq2vbapy7okoqj57nynfsq6m3yzghsbjka -- valory/registration_abci:0.1.0:bafybeigijk6tyixlbb3jhrlgxfzk7wqopegqbdbklflvor27n3ysu42zty -- valory/reset_pause_abci:0.1.0:bafybeid4atrdi3mflnkg6hiylnmjbfqa323i3wkjhuj4jispxbchukwwiq -- valory/transaction_settlement_abci:0.1.0:bafybeie6mefwzprsqd6n45aleswygs76oekvdlzblq72omjsjtmwdaqwly +- valory/abstract_round_abci:0.1.0:bafybeibbxka2c4mvlo2msxi3wtk654fczkfcnbopftyskmd727pjpbty3e +- valory/keep3r_abci:0.1.0:bafybeifm6xhwi47zkqxdtsoh2ich2xtdioqpx6jj3hgskoljo6q4zxaqzm +- valory/keep3r_job:0.1.0:bafybeiezok7h2j7tjkzxpm4qk35rnszretvrkv3dzpqn3kuvbymlvstoua +- valory/registration_abci:0.1.0:bafybeicjvmdle7qkrid6hpr4nepnvt6pl7oznntfhxy2ftrrciu5vb6sqm +- valory/reset_pause_abci:0.1.0:bafybeiay3qgd7jp5xtxqxmbe2net2tm762av42nobosx4atxfjlbe665mi +- valory/transaction_settlement_abci:0.1.0:bafybeie5lp57jwtum4uyq4rdkmoue442l6ssdjabi5rbc2di7wtzixw64i default_ledger: ethereum required_ledgers: - ethereum @@ -194,9 +194,9 @@ public_id: valory/abci:0.1.0 type: connection config: target_skill_id: valory/keep3r_abci:0.1.0 - host: ${ABCI_HOST:str:localhost} - port: ${ABCI_PORT:int:26658} - use_tendermint: ${ABCI_USE_TENDERMINT:bool:false} + host: ${str:localhost} + port: ${int:26658} + use_tendermint: ${bool:false} --- public_id: valory/keep3r_abci:0.1.0 type: skill @@ -247,6 +247,31 @@ config: default_gas_price_strategy: ${CONNECTION_LEDGER_CONFIG_LEDGER_APIS_ETHEREUM_DEFAULT_GAS_PRICE_STRATEGY:str:eip1559} authentication_private_key: ${str:null} flashbot_relayer_uri: ${str:null} + arbitrum: + address: ${str:http://localhost:8545} + chain_id: ${int:421611} + poa_chain: ${bool:false} + default_gas_price_strategy: ${str:eip1559} + consensys: + address: ${str:http://localhost:8545} + chain_id: ${int:1337} + default_gas_price_strategy: eip1559 + poa_chain: false + bnb: + address: ${str:http://localhost:8545} + chain_id: ${int:1337} + poa_chain: ${bool:false} + default_gas_price_strategy: ${str:eip1559} + gnosis: + address: ${str:http://localhost:8545} + chain_id: ${int:1337} + poa_chain: ${bool:false} + default_gas_price_strategy: ${str:eip1559} + zksync: + address: ${str:http://localhost:8545} + chain_id: ${int:1337} + poa_chain: ${bool:false} + default_gas_price_strategy: ${str:eip1559} --- public_id: valory/p2p_libp2p_client:0.1.0 type: connection diff --git a/packages/valory/connections/ledger/base.py b/packages/valory/connections/ledger/base.py index 49a1c4c6..fdd47d41 100644 --- a/packages/valory/connections/ledger/base.py +++ b/packages/valory/connections/ledger/base.py @@ -132,6 +132,17 @@ async def wait_for( func_result = await asyncio.wait_for(running_func, timeout=timeout) return func_result + def set_extra_kwargs(self, message: Message) -> None: + """ + Set extra kwargs for the provided message. + + By default, this method does nothing. Override it in subclasses to set extra kwargs. + + :param message: the message that will be decorated with the extra kwargs. + :return: None + """ + return + def dispatch(self, envelope: Envelope) -> Task: """ Dispatch the request to the right sender handler. @@ -143,7 +154,9 @@ def dispatch(self, envelope: Envelope) -> Task: raise ValueError("Ledger connection expects non-serialized messages.") message = envelope.message ledger_id = self.get_ledger_id(message) - api = self.ledger_api_registry.make(ledger_id, **self.api_config(ledger_id)) + chain_id = self.get_chain_id(message) + self.set_extra_kwargs(message) + api = self.ledger_api_registry.make(ledger_id, **self.api_config(chain_id)) dialogue = self.dialogues.update(message) if dialogue is None: raise ValueError( # pragma: nocover @@ -196,3 +209,7 @@ def ledger_api_registry(self) -> Registry: @abstractmethod def get_ledger_id(self, message: Message) -> str: """Extract the ledger id from the message.""" + + @abstractmethod + def get_chain_id(self, message: Message) -> str: + """Extract the chain id from the message.""" diff --git a/packages/valory/connections/ledger/connection.yaml b/packages/valory/connections/ledger/connection.yaml index 53ddc91e..692f0c18 100644 --- a/packages/valory/connections/ledger/connection.yaml +++ b/packages/valory/connections/ledger/connection.yaml @@ -8,10 +8,10 @@ aea_version: '>=1.0.0, <2.0.0' fingerprint: README.md: bafybeihkgodu7o7v6pfazm7u6orlspsfrae3cyz36yc46x67phfmw3l57e __init__.py: bafybeierqitcqk7oy6m3qp7jgs67lcg55mzt3arltkwimuii2ynfejccwi - base.py: bafybeicpyhus3h2t5urzldnjns2sfwae64uinethqnlunudclbdg4xftnq + base.py: bafybeifxma5dyzyiodirigplulj736ydtexd4kxyjchjiax4nssbfnugei connection.py: bafybeicydkymhz2feqmihtkiwdfg7pp4pww2elqv4tijuhjcplyvawdk74 - contract_dispatcher.py: bafybeigqgqe6zef335t2ygp4celx7445etwjsr42yroc2qmrynwfslgjhq - ledger_dispatcher.py: bafybeibz2uwhgekwov6cw3dalpzokm6kq2bi52c5dkphkwefsz62jrviei + contract_dispatcher.py: bafybeifgtj3ovcu4i7vsanbn5xwntd5eij7i6vgau5tfiycbrftgimkasi + ledger_dispatcher.py: bafybeibx46iad5xvbvo4p7tmwmfwdyscpuwgni262iwrqf5kc46xvs2fiq tests/__init__.py: bafybeieyhttiwruutk6574yzj7dk2afamgdum5vktyv54gsax7dlkuqtc4 tests/conftest.py: bafybeid7vo7e2m76ey5beeadtbxywxx5ukefd5slwbc362rwmhht6i45ou tests/test_contract_dispatcher.py: bafybeidpwcnitn5gzgmbtaur3mevme72rsdaax27nu4bs3aqxwixyn4cvy @@ -62,6 +62,41 @@ config: gas_price_strategies: *id001 is_gas_estimation_enabled: true poa_chain: false + arbitrum: + address: http://127.0.0.1:8545 + chain_id: 1337 + default_gas_price_strategy: eip1559 + gas_price_strategies: *id001 + is_gas_estimation_enabled: true + poa_chain: false + zksync: + address: http://127.0.0.1:8545 + chain_id: 1337 + default_gas_price_strategy: eip1559 + gas_price_strategies: *id001 + is_gas_estimation_enabled: true + poa_chain: false + bnb: + address: http://127.0.0.1:8545 + chain_id: 1337 + default_gas_price_strategy: eip1559 + gas_price_strategies: *id001 + is_gas_estimation_enabled: true + poa_chain: false + gnosis: + address: http://127.0.0.1:8545 + chain_id: 1337 + default_gas_price_strategy: eip1559 + gas_price_strategies: *id001 + is_gas_estimation_enabled: true + poa_chain: false + consensys: + address: http://127.0.0.1:8545 + chain_id: 1337 + default_gas_price_strategy: eip1559 + gas_price_strategies: *id001 + is_gas_estimation_enabled: true + poa_chain: false retry_attempts: 240 retry_timeout: 3 excluded_protocols: [] diff --git a/packages/valory/connections/ledger/contract_dispatcher.py b/packages/valory/connections/ledger/contract_dispatcher.py index 4fb3013b..968c53fa 100644 --- a/packages/valory/connections/ledger/contract_dispatcher.py +++ b/packages/valory/connections/ledger/contract_dispatcher.py @@ -415,3 +415,34 @@ def _validate_and_call_callable( raise AEAException( # pragma: nocover f"Unexpected performative: {message.performative}" ) + + def get_chain_id(self, message: Message) -> str: + """ + Get the chain id. For ledger messages this is the same as the ledger id, for now. + + :param message: the message + :return: the chain id + """ + if not isinstance(message, ContractApiMessage): # pragma: nocover + raise ValueError("argument is not a ContractApiMessage instance.") + message = cast(ContractApiMessage, message) + kwargs = cast(JSONLike, message.kwargs.body) + # if the chain id is specified in the message, use it. + # otherwise, use the ledger id. + chain_id = kwargs.get("chain_id", self.get_ledger_id(message)) + return chain_id + + def set_extra_kwargs(self, message: Message) -> None: + """ + Set extra kwargs for the contract api message. + + :param message: the message + :return: None + """ + if not isinstance(message, ContractApiMessage): + raise ValueError("argument is not a ContractApiMessage instance.") + message = cast(ContractApiMessage, message) + if message.kwargs.body is not None and message.kwargs.body.get( + "set_ledger_api_configs", False + ): + message.kwargs.body.update({"ledger_api_configs": self._api_configs.copy()}) diff --git a/packages/valory/connections/ledger/ledger_dispatcher.py b/packages/valory/connections/ledger/ledger_dispatcher.py index 5f983aec..39ad5a07 100644 --- a/packages/valory/connections/ledger/ledger_dispatcher.py +++ b/packages/valory/connections/ledger/ledger_dispatcher.py @@ -453,3 +453,12 @@ def get_error_message( ), ) return response + + def get_chain_id(self, message: Message) -> str: + """ + Get the chain id. For ledger messages this is the same as the ledger id, for now. + + :param message: the message + :return: the chain id + """ + return self.get_ledger_id(message) diff --git a/packages/valory/contracts/connext_propagate_job/RelayerProxyHub.json b/packages/valory/contracts/connext_propagate_job/RelayerProxyHub.json new file mode 100644 index 00000000..983743ed --- /dev/null +++ b/packages/valory/contracts/connext_propagate_job/RelayerProxyHub.json @@ -0,0 +1,4 @@ +{ + "abi": [{"inputs":[{"internalType":"address","name":"_connext","type":"address"},{"internalType":"address","name":"_spokeConnector","type":"address"},{"internalType":"address","name":"_gelatoRelayer","type":"address"},{"internalType":"address","name":"_feeCollector","type":"address"},{"internalType":"address","name":"_rootManager","type":"address"},{"internalType":"address","name":"_keep3r","type":"address"},{"internalType":"address","name":"_autonolas","type":"address"},{"internalType":"uint8","name":"_autonolasPriority","type":"uint8"},{"internalType":"uint256","name":"_propagateCooldown","type":"uint256"},{"internalType":"address[]","name":"_hubConnectors","type":"address[]"},{"internalType":"uint32[]","name":"_hubConnectorChains","type":"uint32[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ProposedOwnable__onlyOwner_notOwner","type":"error"},{"inputs":[],"name":"ProposedOwnable__onlyProposed_notProposedOwner","type":"error"},{"inputs":[],"name":"ProposedOwnable__ownershipDelayElapsed_delayNotElapsed","type":"error"},{"inputs":[],"name":"ProposedOwnable__proposeNewOwner_invalidProposal","type":"error"},{"inputs":[],"name":"ProposedOwnable__proposeNewOwner_noOwnershipChange","type":"error"},{"inputs":[],"name":"ProposedOwnable__renounceOwnership_invalidProposal","type":"error"},{"inputs":[],"name":"ProposedOwnable__renounceOwnership_noProposal","type":"error"},{"inputs":[{"internalType":"uint32","name":"chain","type":"uint32"},{"internalType":"bytes32","name":"l2Hash","type":"bytes32"}],"name":"RelayerProxyHub__processFromRoot_alreadyProcessed","type":"error"},{"inputs":[{"internalType":"uint32","name":"chain","type":"uint32"}],"name":"RelayerProxyHub__processFromRoot_noHubConnector","type":"error"},{"inputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"nextWorkable","type":"uint256"}],"name":"RelayerProxyHub__propagateWorkable_failed","type":"error"},{"inputs":[{"internalType":"address","name":"_relayer","type":"address"}],"name":"RelayerProxy__addRelayer_relayerAdded","type":"error"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"RelayerProxy__definedAddress_empty","type":"error"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"}],"name":"RelayerProxy__isWorkableBySender_notWorkable","type":"error"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"}],"name":"RelayerProxy__onlyRelayer_notRelayer","type":"error"},{"inputs":[{"internalType":"address","name":"_relayer","type":"address"}],"name":"RelayerProxy__removeRelayer_relayerNotAdded","type":"error"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"}],"name":"RelayerProxy__validateAndPayWithCredits_notKeep3r","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updated","type":"address"},{"indexed":false,"internalType":"address","name":"previous","type":"address"}],"name":"AutonolasChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"updated","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"previous","type":"uint8"}],"name":"AutonolasPriorityChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updated","type":"address"},{"indexed":false,"internalType":"address","name":"previous","type":"address"}],"name":"ConnextChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updated","type":"address"},{"indexed":false,"internalType":"address","name":"previous","type":"address"}],"name":"FeeCollectorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"}],"name":"FundsDeducted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"}],"name":"FundsReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updated","type":"address"},{"indexed":false,"internalType":"address","name":"previous","type":"address"}],"name":"GelatoRelayerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"hubConnector","type":"address"},{"indexed":false,"internalType":"address","name":"oldHubConnector","type":"address"},{"indexed":false,"internalType":"uint32","name":"chain","type":"uint32"}],"name":"HubConnectorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updated","type":"address"},{"indexed":false,"internalType":"address","name":"previous","type":"address"}],"name":"Keep3rChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"proposedOwner","type":"address"}],"name":"OwnershipProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"propagateCooldown","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldPropagateCooldown","type":"uint256"}],"name":"PropagateCooldownChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"relayer","type":"address"}],"name":"RelayerAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"relayer","type":"address"}],"name":"RelayerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"rootManager","type":"address"},{"indexed":false,"internalType":"address","name":"oldRootManager","type":"address"}],"name":"RootManagerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updated","type":"address"},{"indexed":false,"internalType":"address","name":"previous","type":"address"}],"name":"SpokeConnectorChanged","type":"event"},{"inputs":[],"name":"acceptProposedOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_relayer","type":"address"}],"name":"addRelayer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowedRelayer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"autonolas","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"autonolasPriority","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"connext","outputs":[{"internalType":"contract IConnext","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"delay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"uint32","name":"originDomain","type":"uint32"},{"internalType":"uint32","name":"destinationDomain","type":"uint32"},{"internalType":"uint32","name":"canonicalDomain","type":"uint32"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"delegate","type":"address"},{"internalType":"bool","name":"receiveLocal","type":"bool"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"uint256","name":"slippage","type":"uint256"},{"internalType":"address","name":"originSender","type":"address"},{"internalType":"uint256","name":"bridgedAmt","type":"uint256"},{"internalType":"uint256","name":"normalizedIn","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes32","name":"canonicalId","type":"bytes32"}],"internalType":"struct TransferInfo","name":"params","type":"tuple"},{"internalType":"address[]","name":"routers","type":"address[]"},{"internalType":"bytes[]","name":"routerSignatures","type":"bytes[]"},{"internalType":"address","name":"sequencer","type":"address"},{"internalType":"bytes","name":"sequencerSignature","type":"bytes"}],"internalType":"struct ExecuteArgs","name":"_args","type":"tuple"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"execute","outputs":[{"internalType":"bytes32","name":"transferId","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeCollector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gelatoRelayer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"hubConnectors","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"keep3r","outputs":[{"internalType":"contract IKeep3rV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastPropagateAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"priorityKeepers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_encodedData","type":"bytes"},{"internalType":"uint32","name":"_fromChain","type":"uint32"},{"internalType":"bytes32","name":"_l2Hash","type":"bytes32"}],"name":"processFromRootKeep3r","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"processedRootMessages","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_connectors","type":"address[]"},{"internalType":"uint256[]","name":"_messageFees","type":"uint256[]"},{"internalType":"bytes[]","name":"_encodedData","type":"bytes[]"},{"internalType":"uint256","name":"_relayerFee","type":"uint256"}],"name":"propagate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"propagateCooldown","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_connectors","type":"address[]"},{"internalType":"uint256[]","name":"_messageFees","type":"uint256[]"},{"internalType":"bytes[]","name":"_encodedData","type":"bytes[]"}],"name":"propagateKeep3r","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newlyProposed","type":"address"}],"name":"proposeNewOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proposed","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposedTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"message","type":"bytes"},{"internalType":"bytes32[32]","name":"path","type":"bytes32[32]"},{"internalType":"uint256","name":"index","type":"uint256"}],"internalType":"struct ISpokeConnector.Proof[]","name":"_proofs","type":"tuple[]"},{"internalType":"bytes32","name":"_aggregateRoot","type":"bytes32"},{"internalType":"bytes32[32]","name":"_aggregatePath","type":"bytes32[32]"},{"internalType":"uint256","name":"_aggregateIndex","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"proveAndProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_relayer","type":"address"}],"name":"removeRelayer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounced","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rootManager","outputs":[{"internalType":"contract IRootManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_encodedData","type":"bytes"},{"internalType":"uint256","name":"_messageFee","type":"uint256"},{"internalType":"uint256","name":"_relayerFee","type":"uint256"}],"name":"send","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_autonolas","type":"address"}],"name":"setAutonolas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_autonolasPriority","type":"uint8"}],"name":"setAutonolasPriority","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_connext","type":"address"}],"name":"setConnext","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeCollector","type":"address"}],"name":"setFeeCollector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gelatoRelayer","type":"address"}],"name":"setGelatoRelayer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_hubConnector","type":"address"},{"internalType":"uint32","name":"_chain","type":"uint32"}],"name":"setHubConnector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_keep3r","type":"address"}],"name":"setKeep3r","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_propagateCooldown","type":"uint256"}],"name":"setPropagateCooldown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rootManager","type":"address"}],"name":"setRootManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_spokeConnector","type":"address"}],"name":"setSpokeConnector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"spokeConnector","outputs":[{"internalType":"contract ISpokeConnector","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}], + "bytecode": "60806040523480156200001157600080fd5b5060405162003f3f38038062003f3f833981016040819052620000349162000800565b60016003558a8a8a8a8989896200004b3362000144565b6200005687620001a9565b620000618662000212565b6200006c856200027b565b6200007784620002e4565b62000082836200034d565b6200008d82620003b6565b62000098816200041f565b620000a38562000488565b50505050505050620000bb876200052c60201b60201c565b620000c68362000595565b60005b825181101562000132576200011d838281518110620000ec57620000ec62000913565b602002602001015183838151811062000109576200010962000913565b6020026020010151620005d760201b60201c565b80620001298162000929565b915050620000c9565b50505050505050505050505062000951565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b039092166001600160a01b0319928316178155600255600180549091169055565b600754604080516001600160a01b03808516825290921660208301527f87539ad41983c0ecff8f321db8edf4dd9e830593562770bdacdda085b83e3bb2910160405180910390a1600780546001600160a01b0319166001600160a01b0392909216919091179055565b600854604080516001600160a01b03808516825290921660208301527f66948d99d8431a8416af2202bc301823b7cdd87beb9bddaa274aedac0611a5fd910160405180910390a1600880546001600160a01b0319166001600160a01b0392909216919091179055565b600454604080516001600160a01b03808516825290921660208301527f5db4a067a1f787c3269642464a2a1560868b50b0873e7dec83939ae2359f6128910160405180910390a1600480546001600160a01b0319166001600160a01b0392909216919091179055565b600554604080516001600160a01b03808516825290921660208301527f649c5e3d0ed183894196148e193af316452b0037e77d2ff0fef23b7dc722bed0910160405180910390a1600580546001600160a01b0319166001600160a01b0392909216919091179055565b600654604080516001600160a01b03808516825290921660208301527f711d2a81db157c0acede64f080708460163dfaddcd4266c2c609efb458d3e4c0910160405180910390a1600680546001600160a01b0319166001600160a01b0392909216919091179055565b600954604080516001600160a01b03808516825290921660208301527f17da78d98886c3b8819430ab0693a44c32dfa6426a4db4601ce45bc4bc2385ec910160405180910390a1600980546001600160a01b0319166001600160a01b0392909216919091179055565b6009546040805160ff8085168252600160a01b90930490921660208301527f65b4d060a802296de931fb313ab2ca65155e7a26b0ea83e41044f3036d5ac3f3910160405180910390a16009805460ff909216600160a01b0260ff60a01b19909216919091179055565b6001600160a01b0381166000908152600a602052604090205460ff1615620004d257604051633d85ded560e11b81526001600160a01b038216600482015260240160405180910390fd5b6001600160a01b0381166000818152600a6020908152604091829020805460ff1916600117905590519182527f03580ee9f53a62b7cb409a2cb56f9be87747dd15017afc5cef6eef321e4fb2c5910160405180910390a150565b600c54604080516001600160a01b03808516825290921660208301527f3124eaf4f16c6ddd81951200c6d8f65d5800753bef06584bd672c8b22c76b487910160405180910390a1600c80546001600160a01b0319166001600160a01b0392909216919091179055565b600d546040805183815260208101929092527f5d93bbdda0d794fed18c39a7b776dc86cbf6ed443032e6baac71373996b85010910160405180910390a1600d55565b63ffffffff81166000818152601060209081526040918290205482516001600160a01b0387811682529091169181019190915280820192909252517ff3f83f3e1df056d9be522e74b3fe84add98c686289a646ae55708277434240929181900360600190a163ffffffff16600090815260106020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b80516001600160a01b03811681146200068857600080fd5b919050565b805160ff811681146200068857600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620006e057620006e06200069f565b604052919050565b60006001600160401b038211156200070457620007046200069f565b5060051b60200190565b600082601f8301126200072057600080fd5b81516020620007396200073383620006e8565b620006b5565b82815260059290921b840181019181810190868411156200075957600080fd5b8286015b848110156200077f57620007718162000670565b83529183019183016200075d565b509695505050505050565b600082601f8301126200079c57600080fd5b81516020620007af6200073383620006e8565b82815260059290921b84018101918181019086841115620007cf57600080fd5b8286015b848110156200077f57805163ffffffff81168114620007f25760008081fd5b8352918301918301620007d3565b60008060008060008060008060008060006101608c8e0312156200082357600080fd5b6200082e8c62000670565b9a506200083e60208d0162000670565b99506200084e60408d0162000670565b98506200085e60608d0162000670565b97506200086e60808d0162000670565b96506200087e60a08d0162000670565b95506200088e60c08d0162000670565b94506200089e60e08d016200068d565b6101008d01516101208e015191955093506001600160401b03811115620008c457600080fd5b620008d28e828f016200070e565b6101408e015190935090506001600160401b03811115620008f257600080fd5b620009008e828f016200078a565b9150509295989b509295989b9093969950565b634e487b7160e01b600052603260045260246000fd5b6000600182016200094a57634e487b7160e01b600052601160045260246000fd5b5060010190565b6135de80620009616000396000f3fe60806040526004361061024a5760003560e01c80639c166c0b11610139578063d232c220116100b6578063dd39f00d1161007a578063dd39f00d14610737578063de4b054814610757578063e79457f114610777578063e7dc209814610797578063f0a67eba146107ad578063f9aa7645146107cd57600080fd5b8063d232c22014610698578063d9ef0bee146106b7578063dad837a8146106d7578063db205635146106f7578063dbd8848d1461071757600080fd5b8063b1f8100d116100fd578063b1f8100d146105f5578063ba6fef6114610615578063c415b95c14610645578063c5b350df14610665578063d1851c921461067a57600080fd5b80639c166c0b146105555780639cadce00146105755780639f645a0314610595578063a42dce80146105b5578063a91b8fb8146105d557600080fd5b8063622520bb116101c7578063890997171161018b57806389099717146104b75780638c976851146104d75780638da5cb5b146104f75780638efed127146105155780639a2652db1461053557600080fd5b8063622520bb146103fe578063634c7bb51461044c5780636a42b8f81461046c5780636eba787f14610482578063715018a6146104a257600080fd5b80633cf52ffb1161020e5780633cf52ffb146103695780634cc18e571461037e5780634d6f20131461039e5780635e21966a146103be57806360f0a5ac146103de57600080fd5b80631acde6281461028e57806321444433146102de5780632d484bcc146103025780632f55b98d146103245780633ccfd60b1461035457600080fd5b3661028957604080513481524760208201527f063d07ee72a7483b8e07ca09054bb686775c5c030f945dde3823a5257a0a93eb910160405180910390a1005b600080fd5b34801561029a57600080fd5b506102c96102a9366004612200565b600f60209081526000928352604080842090915290825290205460ff1681565b60405190151581526020015b60405180910390f35b3480156102ea57600080fd5b506102f4600e5481565b6040519081526020016102d5565b34801561030e57600080fd5b5061032261031d36600461222a565b610800565b005b34801561033057600080fd5b506102c961033f36600461225a565b600a6020526000908152604090205460ff1681565b34801561036057600080fd5b50610322610837565b34801561037557600080fd5b506002546102f4565b34801561038a57600080fd5b5061032261039936600461225a565b6108a8565b3480156103aa57600080fd5b506103226103b936600461225a565b610918565b3480156103ca57600080fd5b506103226103d936600461225a565b61097f565b3480156103ea57600080fd5b506103226103f936600461225a565b6109e6565b34801561040a57600080fd5b5061043461041936600461227c565b6010602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020016102d5565b34801561045857600080fd5b50600654610434906001600160a01b031681565b34801561047857600080fd5b5062093a806102f4565b34801561048e57600080fd5b50600454610434906001600160a01b031681565b3480156104ae57600080fd5b50610322610a4d565b3480156104c357600080fd5b506103226104d236600461225a565b610aff565b3480156104e357600080fd5b506103226104f23660046124d7565b610b66565b34801561050357600080fd5b506000546001600160a01b0316610434565b34801561052157600080fd5b506102f461053036600461256a565b610d48565b34801561054157600080fd5b506103226105503660046125a5565b610e10565b34801561056157600080fd5b50600954610434906001600160a01b031681565b34801561058157600080fd5b50600854610434906001600160a01b031681565b3480156105a157600080fd5b506103226105b036600461225a565b610e9e565b3480156105c157600080fd5b506103226105d036600461225a565b610f05565b3480156105e157600080fd5b506103226105f0366004612640565b610f6c565b34801561060157600080fd5b5061032261061036600461225a565b610fd9565b34801561062157600080fd5b506102c961063036600461225a565b600b6020526000908152604090205460ff1681565b34801561065157600080fd5b50600554610434906001600160a01b031681565b34801561067157600080fd5b50610322611077565b34801561068657600080fd5b506001546001600160a01b0316610434565b3480156106a457600080fd5b506000546001600160a01b0316156102c9565b3480156106c357600080fd5b506103226106d2366004612673565b6110e7565b3480156106e357600080fd5b506103226106f23660046126c0565b6111c5565b34801561070357600080fd5b50600c54610434906001600160a01b031681565b34801561072357600080fd5b506103226107323660046126e3565b6111f9565b34801561074357600080fd5b5061032261075236600461225a565b611379565b34801561076357600080fd5b50600754610434906001600160a01b031681565b34801561078357600080fd5b5061032261079236600461276b565b6113e0565b3480156107a357600080fd5b506102f4600d5481565b3480156107b957600080fd5b506103226107c836600461225a565b611497565b3480156107d957600080fd5b506009546107ee90600160a01b900460ff1681565b60405160ff90911681526020016102d5565b6000546001600160a01b0316331461082b576040516311a8a1bb60e31b815260040160405180910390fd5b610834816114fe565b50565b6000546001600160a01b03163314610862576040516311a8a1bb60e31b815260040160405180910390fd5b61086a611540565b476108753382611599565b60408051828152476020820152600080516020613589833981519152910160405180910390a1506108a66001600355565b565b6000546001600160a01b031633146108d3576040516311a8a1bb60e31b815260040160405180910390fd5b806001600160a01b03811661090b57604051633a930fdf60e01b81526001600160a01b03821660048201526024015b60405180910390fd5b610914826116b2565b5050565b6000546001600160a01b03163314610943576040516311a8a1bb60e31b815260040160405180910390fd5b806001600160a01b03811661097657604051633a930fdf60e01b81526001600160a01b0382166004820152602401610902565b6109148261171b565b6000546001600160a01b031633146109aa576040516311a8a1bb60e31b815260040160405180910390fd5b806001600160a01b0381166109dd57604051633a930fdf60e01b81526001600160a01b0382166004820152602401610902565b61091482611784565b6000546001600160a01b03163314610a11576040516311a8a1bb60e31b815260040160405180910390fd5b806001600160a01b038116610a4457604051633a930fdf60e01b81526001600160a01b0382166004820152602401610902565b610914826117ed565b6000546001600160a01b03163314610a78576040516311a8a1bb60e31b815260040160405180910390fd5b62093a8060025442610a8a91906127f8565b11610aa8576040516324e0285f60e21b815260040160405180910390fd5b600254600003610acb57604051630e4b303f60e21b815260040160405180910390fd5b6001546001600160a01b031615610af5576040516323295ef960e01b815260040160405180910390fd5b6108a66000611889565b6000546001600160a01b03163314610b2a576040516311a8a1bb60e31b815260040160405180910390fd5b806001600160a01b038116610b5d57604051633a930fdf60e01b81526001600160a01b0382166004820152602401610902565b610914826118ee565b600d54600e54610b76919061280b565b4211610baf5742600d54600e54610b8d919061280b565b604051632856ee5160e01b815260048101929092526024820152604401610902565b60095433906001600160a01b03168114610be257600954600160a01b900460ff16610bdb600a4361281e565b1115610bfc565b600954600160a01b900460ff16610bfa600a4361281e565b115b15610c255760405163cd6ff7a160e01b81526001600160a01b0382166004820152602401610902565b6006546040516335d2155560e11b81523360048201819052916001600160a01b031690636ba42aaa906024016020604051808303816000875af1158015610c70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c94919061284e565b610cbc576040516398eac98560e01b81526001600160a01b0382166004820152602401610902565b610cc4611540565b610cd18787878787611957565b5042600e55610ce06001600355565b6006546040516317fbade560e21b81526001600160a01b03838116600483015290911690635feeb79490602401600060405180830381600087803b158015610d2757600080fd5b505af1158015610d3b573d6000803e3d6000fd5b5050505050505050505050565b336000908152600a602052604081205460ff16610d7a57604051630981f7d560e21b8152336004820152602401610902565b610d82611540565b6007546040516331f1f3e960e11b81526001600160a01b03909116906363e3e7d290610db29086906004016129d0565b6020604051808303816000875af1158015610dd1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df59190612bc3565b9050610e0082611a18565b610e0a6001600355565b92915050565b336000908152600a602052604090205460ff16610e4257604051630981f7d560e21b8152336004820152602401610902565b610e4a611540565b6000610e598787878787611957565b60408051828152476020820152919250600080516020613589833981519152910160405180910390a1610e8b82611a18565b50610e966001600355565b505050505050565b6000546001600160a01b03163314610ec9576040516311a8a1bb60e31b815260040160405180910390fd5b806001600160a01b038116610efc57604051633a930fdf60e01b81526001600160a01b0382166004820152602401610902565b61091482611a72565b6000546001600160a01b03163314610f30576040516311a8a1bb60e31b815260040160405180910390fd5b806001600160a01b038116610f6357604051633a930fdf60e01b81526001600160a01b0382166004820152602401610902565b61091482611adb565b6000546001600160a01b03163314610f97576040516311a8a1bb60e31b815260040160405180910390fd5b816001600160a01b038116610fca57604051633a930fdf60e01b81526001600160a01b0382166004820152602401610902565b610fd48383611b44565b505050565b6000546001600160a01b03163314611004576040516311a8a1bb60e31b815260040160405180910390fd5b6001546001600160a01b038281169116148015611022575060025415155b15611040576040516311bc066560e11b815260040160405180910390fd5b6000546001600160a01b0380831691160361106e57604051634a2fb73f60e11b815260040160405180910390fd5b61083481611bdd565b6001546001600160a01b031633146110a2576040516311a7f27160e11b815260040160405180910390fd5b62093a80600254426110b491906127f8565b116110d2576040516324e0285f60e21b815260040160405180910390fd5b6001546108a6906001600160a01b0316611889565b336000908152600a602052604090205460ff1661111957604051630981f7d560e21b8152336004820152602401610902565b611121611540565b600854604051630aec6b9f60e21b81526001600160a01b0390911690632bb1ae7c908490611153908790600401612c22565b6000604051808303818588803b15801561116c57600080fd5b505af1158015611180573d6000803e3d6000fd5b50506040805186815247602082015260008051602061358983398151915294500191506111aa9050565b60405180910390a16111bb81611a18565b610fd46001600355565b6000546001600160a01b031633146111f0576040516311a8a1bb60e31b815260040160405180910390fd5b61083481611c2b565b60095433906001600160a01b0316811461122c57600954600160a01b900460ff16611225600a4361281e565b1115611246565b600954600160a01b900460ff16611244600a4361281e565b115b1561126f5760405163cd6ff7a160e01b81526001600160a01b0382166004820152602401610902565b6006546040516335d2155560e11b81523360048201819052916001600160a01b031690636ba42aaa906024016020604051808303816000875af11580156112ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112de919061284e565b611306576040516398eac98560e01b81526001600160a01b0382166004820152602401610902565b61131286868686611c94565b6006546040516317fbade560e21b81526001600160a01b03838116600483015290911690635feeb79490602401600060405180830381600087803b15801561135957600080fd5b505af115801561136d573d6000803e3d6000fd5b50505050505050505050565b6000546001600160a01b031633146113a4576040516311a8a1bb60e31b815260040160405180910390fd5b806001600160a01b0381166113d757604051633a930fdf60e01b81526001600160a01b0382166004820152602401610902565b610914826120e5565b336000908152600a602052604090205460ff1661141257604051630981f7d560e21b8152336004820152602401610902565b61141a611540565b60085460405163508a109b60e01b81526001600160a01b039091169063508a109b906114529089908990899089908990600401612c3f565b600060405180830381600087803b15801561146c57600080fd5b505af1158015611480573d6000803e3d6000fd5b5050505061148d81611a18565b610e966001600355565b6000546001600160a01b031633146114c2576040516311a8a1bb60e31b815260040160405180910390fd5b806001600160a01b0381166114f557604051633a930fdf60e01b81526001600160a01b0382166004820152602401610902565b6109148261217e565b600d546040805183815260208101929092527f5d93bbdda0d794fed18c39a7b776dc86cbf6ed443032e6baac71373996b85010910160405180910390a1600d55565b6002600354036115925760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610902565b6002600355565b804710156115e95760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610902565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611636576040519150601f19603f3d011682016040523d82523d6000602084013e61163b565b606091505b5050905080610fd45760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610902565b600654604080516001600160a01b03808516825290921660208301527f711d2a81db157c0acede64f080708460163dfaddcd4266c2c609efb458d3e4c0910160405180910390a1600680546001600160a01b0319166001600160a01b0392909216919091179055565b600754604080516001600160a01b03808516825290921660208301527f87539ad41983c0ecff8f321db8edf4dd9e830593562770bdacdda085b83e3bb2910160405180910390a1600780546001600160a01b0319166001600160a01b0392909216919091179055565b600454604080516001600160a01b03808516825290921660208301527f5db4a067a1f787c3269642464a2a1560868b50b0873e7dec83939ae2359f6128910160405180910390a1600480546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0381166000908152600a602052604090205460ff16611831576040516309fbf0f560e31b81526001600160a01b0382166004820152602401610902565b6001600160a01b0381166000818152600a6020908152604091829020805460ff1916905590519182527f10e1f7ce9fd7d1b90a66d13a2ab3cb8dd7f29f3f8d520b143b063ccfbab6906b91015b60405180910390a150565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b039092166001600160a01b0319928316178155600255600180549091169055565b600954604080516001600160a01b03808516825290921660208301527f17da78d98886c3b8819430ab0693a44c32dfa6426a4db4601ce45bc4bc2385ec910160405180910390a1600980546001600160a01b0319166001600160a01b0392909216919091179055565b60008085815b818163ffffffff16101561199f5786868263ffffffff1681811061198357611983612d01565b9050602002013583611995919061280b565b925060010161195d565b50600c5460405163412e12db60e01b81526001600160a01b039091169063412e12db9084906119da908c908c908c908c908c90600401612d5f565b6000604051808303818588803b1580156119f357600080fd5b505af1158015611a07573d6000803e3d6000fd5b50949b9a5050505050505050505050565b6004546001600160a01b03163303611a4557600554611a40906001600160a01b031682611599565b611a4f565b611a4f3382611599565b60408051828152476020820152600080516020613589833981519152910161187e565b600854604080516001600160a01b03808516825290921660208301527f66948d99d8431a8416af2202bc301823b7cdd87beb9bddaa274aedac0611a5fd910160405180910390a1600880546001600160a01b0319166001600160a01b0392909216919091179055565b600554604080516001600160a01b03808516825290921660208301527f649c5e3d0ed183894196148e193af316452b0037e77d2ff0fef23b7dc722bed0910160405180910390a1600580546001600160a01b0319166001600160a01b0392909216919091179055565b63ffffffff81166000818152601060209081526040918290205482516001600160a01b0387811682529091169181019190915280820192909252517ff3f83f3e1df056d9be522e74b3fe84add98c686289a646ae55708277434240929181900360600190a163ffffffff16600090815260106020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b42600255600180546001600160a01b0319166001600160a01b0383169081179091556040517f6ab4d119f23076e8ad491bc65ce85f017fb0591dce08755ba8591059cc51737a90600090a250565b6009546040805160ff8085168252600160a01b90930490921660208301527f65b4d060a802296de931fb313ab2ca65155e7a26b0ea83e41044f3036d5ac3f3910160405180910390a16009805460ff909216600160a01b0260ff60a01b19909216919091179055565b63ffffffff82166000908152600f6020908152604080832084845290915290205460ff1615611ce55760405163307de84960e01b815263ffffffff8316600482015260248101829052604401610902565b63ffffffff82166000908152601060205260409020546001600160a01b0316611d2957604051637ab6707160e01b815263ffffffff83166004820152602401610902565b63ffffffff82166000818152600f602090815260408083208584529091529020805460ff1916600117905560641480611d6957508163ffffffff166127d8145b15611dfc576000611d7c84860186612df3565b63ffffffff8416600090815260106020908152604091829020548351918401519251633f7658fd60e01b81529394506001600160a01b031692633f7658fd92611dc89291600401612e83565b600060405180830381600087803b158015611de257600080fd5b505af1158015611df6573d6000803e3d6000fd5b50505050505b8163ffffffff1661a4b11480611e1a57508163ffffffff1662066eed145b15611ec3576000611e2d84860186612fb4565b63ffffffff841660009081526010602090815260409182902054835191840151838501516060860151608087015160a08801519651632750dce960e21b81529798506001600160a01b0390941696639d4373a496611e8f9695916004016130a3565b600060405180830381600087803b158015611ea957600080fd5b505af1158015611ebd573d6000803e3d6000fd5b50505050505b8163ffffffff16600a1480611edf57508163ffffffff166101a4145b15611f83576000611ef284860186613208565b63ffffffff841660009081526010602090815260409182902054835191840151838501516060860151608087015195516337176da760e11b81529697506001600160a01b0390931695636e2edb4e95611f4f959491600401613394565b600060405180830381600087803b158015611f6957600080fd5b505af1158015611f7d573d6000803e3d6000fd5b50505050505b8163ffffffff166101441480611fa057508163ffffffff16610118145b15612044576000611fb38486018661346e565b63ffffffff8416600090815260106020908152604091829020548351918401518385015160608601516080870151955163e92a492f60e01b81529697506001600160a01b039093169563e92a492f95612010959491600401613533565b600060405180830381600087803b15801561202a57600080fd5b505af115801561203e573d6000803e3d6000fd5b50505050505b8163ffffffff166089148061206157508163ffffffff1662013881145b156120df5763ffffffff82166000908152601060205260409081902054905163f953cec760e01b81526001600160a01b039091169063f953cec7906120ac9087908790600401613574565b600060405180830381600087803b1580156120c657600080fd5b505af11580156120da573d6000803e3d6000fd5b505050505b50505050565b6001600160a01b0381166000908152600a602052604090205460ff161561212a57604051633d85ded560e11b81526001600160a01b0382166004820152602401610902565b6001600160a01b0381166000818152600a6020908152604091829020805460ff1916600117905590519182527f03580ee9f53a62b7cb409a2cb56f9be87747dd15017afc5cef6eef321e4fb2c5910161187e565b600c54604080516001600160a01b03808516825290921660208301527f3124eaf4f16c6ddd81951200c6d8f65d5800753bef06584bd672c8b22c76b487910160405180910390a1600c80546001600160a01b0319166001600160a01b0392909216919091179055565b803563ffffffff811681146121fb57600080fd5b919050565b6000806040838503121561221357600080fd5b61221c836121e7565b946020939093013593505050565b60006020828403121561223c57600080fd5b5035919050565b80356001600160a01b03811681146121fb57600080fd5b60006020828403121561226c57600080fd5b61227582612243565b9392505050565b60006020828403121561228e57600080fd5b612275826121e7565b60008083601f8401126122a957600080fd5b5081356001600160401b038111156122c057600080fd5b6020830191508360208260051b85010111156122db57600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171561231a5761231a6122e2565b60405290565b60405160e081016001600160401b038111828210171561231a5761231a6122e2565b60405160c081016001600160401b038111828210171561231a5761231a6122e2565b60405160a081016001600160401b038111828210171561231a5761231a6122e2565b604051601f8201601f191681016001600160401b03811182821017156123ae576123ae6122e2565b604052919050565b60006001600160401b038211156123cf576123cf6122e2565b5060051b60200190565b600082601f8301126123ea57600080fd5b81356001600160401b03811115612403576124036122e2565b612416601f8201601f1916602001612386565b81815284602083860101111561242b57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261245957600080fd5b8135602061246e612469836123b6565b612386565b82815260059290921b8401810191818101908684111561248d57600080fd5b8286015b848110156124cc5780356001600160401b038111156124b05760008081fd5b6124be8986838b01016123d9565b845250918301918301612491565b509695505050505050565b6000806000806000606086880312156124ef57600080fd5b85356001600160401b038082111561250657600080fd5b61251289838a01612297565b9097509550602088013591508082111561252b57600080fd5b61253789838a01612297565b9095509350604088013591508082111561255057600080fd5b5061255d88828901612448565b9150509295509295909350565b6000806040838503121561257d57600080fd5b82356001600160401b0381111561259357600080fd5b830160a0818603121561221c57600080fd5b600080600080600080608087890312156125be57600080fd5b86356001600160401b03808211156125d557600080fd5b6125e18a838b01612297565b909850965060208901359150808211156125fa57600080fd5b6126068a838b01612297565b9096509450604089013591508082111561261f57600080fd5b5061262c89828a01612448565b925050606087013590509295509295509295565b6000806040838503121561265357600080fd5b61265c83612243565b915061266a602084016121e7565b90509250929050565b60008060006060848603121561268857600080fd5b83356001600160401b0381111561269e57600080fd5b6126aa868287016123d9565b9660208601359650604090950135949350505050565b6000602082840312156126d257600080fd5b813560ff8116811461227557600080fd5b600080600080606085870312156126f957600080fd5b84356001600160401b038082111561271057600080fd5b818701915087601f83011261272457600080fd5b81358181111561273357600080fd5b88602082850101111561274557600080fd5b60209283019650945061275b91870190506121e7565b9396929550929360400135925050565b600080600080600080610480878903121561278557600080fd5b86356001600160401b0381111561279b57600080fd5b6127a789828a01612297565b909750955050602087013593506104408701888111156127c657600080fd5b9598949750929560408101953594610460909101359350915050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610e0a57610e0a6127e2565b80820180821115610e0a57610e0a6127e2565b60008261283b57634e487b7160e01b600052601260045260246000fd5b500690565b801515811461083457600080fd5b60006020828403121561286057600080fd5b815161227581612840565b80356121fb81612840565b6000808335601e1984360301811261288d57600080fd5b83016020810192503590506001600160401b038111156128ac57600080fd5b8036038213156122db57600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6000808335601e198436030181126128fb57600080fd5b83016020810192503590506001600160401b0381111561291a57600080fd5b8060051b36038213156122db57600080fd5b8183526000602080850194508260005b85811015612968576001600160a01b0361295583612243565b168752958201959082019060010161293c565b509495945050505050565b81835260006020808501808196508560051b810191508460005b878110156129c35782840389526129a48288612876565b6129af8682846128bb565b9a87019a955050509084019060010161298d565b5091979650505050505050565b602081526000823561019e198436030181126129eb57600080fd5b60a060208401528301612a0e60c08401612a04836121e7565b63ffffffff169052565b612a1a602082016121e7565b63ffffffff1660e0840152612a31604082016121e7565b610100612a458186018363ffffffff169052565b612a5160608401612243565b9150610120612a6a818701846001600160a01b03169052565b612a7660808501612243565b9250610140612a8f818801856001600160a01b03169052565b612a9b60a0860161286b565b9350610160612aad8189018615159052565b612aba60c0870187612876565b95506101a061018081818c0152612ad66102608c0189856128bb565b975060e0890135828c0152612aec878a01612243565b6001600160a01b03166101c08c0152948801356101e08b015250509085013561020088015284013561022087015283013561024086015250612b3160208601866128e4565b9250601f1980868403016040870152612b4b83858461292c565b9350612b5a60408801886128e4565b9350915080868503016060870152612b73848484612973565b9350612b8160608801612243565b6001600160a01b03811660808801529250612b9f6080880188612876565b93509150808685030160a087015250612bb98383836128bb565b9695505050505050565b600060208284031215612bd557600080fd5b5051919050565b6000815180845260005b81811015612c0257602081850181015186830182015201612be6565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006122756020830184612bdc565b6104008183375050565b6104608082528101859052600061048080830190600588901b8401018883805b8a811015612cd55786840361047f190185528235368d900361043e19018112612c86578283fd5b8c01610440612c958280612876565b828852612ca583890182846128bb565b92505050602061040081840182890137610420928301359690920195909552948501949290920191600101612c5f565b5050508092505050846020830152612cf06040830185612c35565b826104408301529695505050505050565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501808196508360051b8101915082860160005b858110156129c3578284038952612d4d848351612bdc565b98850198935090840190600101612d35565b6060808252810185905260008660808301825b88811015612da0576001600160a01b03612d8b84612243565b16825260209283019290910190600101612d72565b5083810360208501528581526001600160fb1b03861115612dc057600080fd5b8560051b9150818760208301370182810360209081016040850152612de790820185612d17565b98975050505050505050565b600060208284031215612e0557600080fd5b81356001600160401b0380821115612e1c57600080fd5b9083019060408286031215612e3057600080fd5b612e386122f8565b823582811115612e4757600080fd5b612e53878286016123d9565b825250602083013582811115612e6857600080fd5b612e74878286016123d9565b60208301525095945050505050565b604081526000612e966040830185612bdc565b8281036020840152612ea88185612bdc565b95945050505050565b80356001600160401b03811681146121fb57600080fd5b600082601f830112612ed957600080fd5b81356020612ee9612469836123b6565b82815260059290921b84018101918181019086841115612f0857600080fd5b8286015b848110156124cc5780358352918301918301612f0c565b600060e08284031215612f3557600080fd5b612f3d612320565b9050612f4882612243565b8152612f5660208301612243565b602082015260408201356040820152606082013560608201526080820135608082015260a082013560a082015260c08201356001600160401b03811115612f9c57600080fd5b612fa8848285016123d9565b60c08301525092915050565b600060208284031215612fc657600080fd5b81356001600160401b0380821115612fdd57600080fd5b9083019060c08286031215612ff157600080fd5b612ff9612342565b61300283612eb1565b8152602083013560208201526040830135604082015260608301358281111561302a57600080fd5b61303687828601612ec8565b6060830152506080830135608082015260a08301358281111561305857600080fd5b61306487828601612f23565b60a08301525095945050505050565b600081518084526020808501945080840160005b8381101561296857815187529582019590820190600101613087565b6001600160401b038716815285602082015284604082015260c0606082015260006130d160c0830186613073565b84608084015282810360a084015260018060a01b038085511682528060208601511660208301525060408401516040820152606084015160608201526080840151608082015260a084015160a082015260c084015160e060c083015261313a60e0830182612bdc565b9a9950505050505050505050565b600060a0828403121561315a57600080fd5b613162612364565b90508135815260208201356020820152604082013560408201526060820135606082015260808201356001600160401b0381111561319f57600080fd5b6131ab848285016123d9565b60808301525092915050565b6000604082840312156131c957600080fd5b6131d16122f8565b90508135815260208201356001600160401b038111156131f057600080fd5b6131fc84828501612ec8565b60208301525092915050565b60006020828403121561321a57600080fd5b81356001600160401b038082111561323157600080fd5b9083019060a0828603121561324557600080fd5b61324d612364565b61325683612243565b815261326460208401612243565b602082015260408301358281111561327b57600080fd5b613287878286016123d9565b604083015250606083013560608201526080830135828111156132a957600080fd5b929092019160a083870312156132be57600080fd5b6132c6612364565b833581526020840135838111156132dc57600080fd5b6132e888828701613148565b60208301525060408401358381111561330057600080fd5b61330c888287016131b7565b60408301525060608401358381111561332457600080fd5b613330888287016123d9565b60608301525060808401358381111561334857600080fd5b613354888287016123d9565b6080830152508060808301525080935050505092915050565b80518252600060208201516040602085015261338c6040850182613073565b949350505050565b6001600160a01b0386811682528516602082015260a0604082018190526000906133c090830186612bdc565b846060840152828103608084015283518152602084015160a06020830152805160a0830152602081015160c0830152604081015160e083015260608101516101008301526080810151905060a0610120830152613421610140830182612bdc565b90506040850151828203604084015261343a828261336d565b915050606085015182820360608401526134548282612bdc565b9150506080850151828203608084015261313a8282612bdc565b60006020828403121561348057600080fd5b81356001600160401b038082111561349757600080fd5b9083019060a082860312156134ab57600080fd5b6134b3612364565b6134bc836121e7565b815260208301356020820152604083013561ffff811681146134dd57600080fd5b60408201526060830135828111156134f457600080fd5b613500878286016123d9565b60608301525060808301358281111561351857600080fd5b61352487828601612ec8565b60808301525095945050505050565b63ffffffff8616815284602082015261ffff8416604082015260a06060820152600061356260a0830185612bdc565b8281036080840152612de78185613073565b60208152600061338c6020830184866128bb56fe9826a73d0fd7186bda6a15195ac17571869cab151bfe9a8fed3f9407fffe5b18a26469706673582212207f78ae11239b3f684889d2328b46ebd4da58879e6168ebe8495f8782534453ce64736f6c63430008110033000000000000000000000000fca08024a6d4bcc87275b1e4a1e22b71fad7f649000000000000000000000000e9c7095c956f9f75e21dd99027adf6bfffa9ba9a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000094e1c90fb33fec184b183625bbf096f713ca74a300000000000000000000000085063437c02ba7f4f82f898859e4992380ded3bb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000708000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000006000000000000000000000000e9c7095c956f9f75e21dd99027adf6bfffa9ba9a00000000000000000000000080231092091d752e1506d4aab393675ebe388e9e000000000000000000000000a9eb35ebc739e753bcb5b75d2753a9023a0ac1d80000000000000000000000009f02b394d8f0e2df3f6913f375cd1f919c03987d0000000000000000000000009060e2b92a4e8d4ead05b7f3d736e3da33955fa500000000000000000000000058d3464e5aab9c598a7059d182720a04ad59b01f00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000011800000000000000000000000000000000000000000000000000000000000001a4000000000000000000000000000000000000000000000000000000000000e70400000000000000000000000000000000000000000000000000000000000138810000000000000000000000000000000000000000000000000000000000066eed" +} \ No newline at end of file diff --git a/packages/valory/contracts/connext_propagate_job/__init__.py b/packages/valory/contracts/connext_propagate_job/__init__.py new file mode 100644 index 00000000..1f9e5a24 --- /dev/null +++ b/packages/valory/contracts/connext_propagate_job/__init__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2023 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""This module represents a package for the ConnextPropagateJob contract.""" diff --git a/packages/valory/contracts/connext_propagate_job/contract.py b/packages/valory/contracts/connext_propagate_job/contract.py new file mode 100644 index 00000000..610f3927 --- /dev/null +++ b/packages/valory/contracts/connext_propagate_job/contract.py @@ -0,0 +1,630 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2023 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""This module contains a class for the ConnextPropagateJob contract.""" +import json +import logging +from abc import ABC, abstractmethod +from dataclasses import dataclass +from typing import Any, Dict, List, Optional, Tuple, Type, cast + +from aea.common import JSONLike +from aea.configurations.base import PublicId +from aea.contracts.base import Contract +from aea.crypto.registries import ledger_apis_registry +from aea_ledger_ethereum import EthereumApi +from web3.types import RPCEndpoint + + +PUBLIC_ID = PublicId.from_str("valory/connext_propagate_job:0.1.0") + +_logger = logging.getLogger( + f"aea.packages.{PUBLIC_ID.author}.contracts.{PUBLIC_ID.name}.contract" +) + +ONE_ETH = 10**18 +ZERO_ETH = 0 +ETHEREUM_L1 = "ethereum" +ARBITRUM = "arbitrum" +ZKSYNC = "zksync" +REQUIRED_LEDGER_APIS = [ + ETHEREUM_L1, + ARBITRUM, + ZKSYNC, +] + + +@dataclass +class CallData: + """A class to represent call data for a given connector.""" + + encoded_data: bytes + fee: int + + +class L2Network(ABC): + """A class to represent a L2 network.""" + + def __init__(self, ledger_apis: Dict[str, EthereumApi]) -> None: + """Instantiate a L2 network.""" + self._ledger_apis = ledger_apis + + @property + def l1(self) -> EthereumApi: + """Get the L1 ledger api.""" + return self._ledger_apis[ETHEREUM_L1] + + @property + def l2(self) -> EthereumApi: + """Get the L2 ledger api.""" + raise NotImplementedError + + def _get_base_fee(self, ledger_api: EthereumApi) -> int: # noqa + """Return the base fee for the current block.""" + last_block = ledger_api.api.eth.get_block("latest") + return last_block["baseFeePerGas"] + + def _get_gas_price(self, ledger_api: EthereumApi) -> int: # noqa + """Return the gas price for the current block.""" + gas_price = ledger_api.api.eth.gas_price + return gas_price + + @abstractmethod + def get_call_data(self) -> CallData: + """Get the call data for an L2 network.""" + + +class Arbitrum(L2Network): + """A class that represents arbitrum.""" + + gas_price_percent_increase = 2 # 200% + submission_fee_percent_increase = 3 # 300% + node_interface_address = "0x00000000000000000000000000000000000000C8" + node_interface_abi = """[{ + "inputs": [ + { + "internalType":"address", + "name":"sender", + "type":"address" + }, + { + "internalType":"uint256", + "name":"deposit", + "type":"uint256" + }, + { + "internalType":"address", + "name":"to", + "type":"address" + }, + { + "internalType":"uint256", + "name":"l2CallValue", + "type":"uint256" + }, + { + "internalType":"address", + "name":"excessFeeRefundAddress", + "type":"address" + }, + { + "internalType":"address", + "name":"callValueRefundAddress", + "type":"address" + }, + { + "internalType":"bytes", + "name":"data", + "type":"bytes" + } + ], + "name":"estimateRetryableTicket", + "outputs":[], + "stateMutability":"nonpayable", + "type":"function" + }]""" + arbitrum_hub_connector = "0xd151C9ef49cE2d30B829a98A07767E3280F70961" + arbitrum_spoke_connector = "0xFD81392229b6252cF761459d370C239Be3aFc54F" + spoke_connector_call_data = bytes.fromhex( + "4ff746f6000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001" + ) + multiplier = 5 + + @dataclass + class L1ToL2Estimate: + """A dataclass representing an L1->L2 message estimate.""" + + gas_limit: int + max_submission_fee: int + max_fee_per_gas: int + total_l2_gas_costs: int + + def __init__(self, ledger_apis: Dict[str, EthereumApi]): + """Setup an arbitrum instance.""" + super().__init__(ledger_apis) + self._node_interface_address = self.l1.api.toChecksumAddress( + self.node_interface_address + ) + self._node_interface_abi = json.loads(self.node_interface_abi) + + @property + def l2(self) -> EthereumApi: + """Get the L2 ledger api.""" + return self._ledger_apis[ARBITRUM] + + def estimate_submission_fee( + self, data_length: int, base_fee: int + ) -> int: # pylint: disable=no-self-use; # noqa + """ + Estimates the submission fee. + + Imitates the logic here (https://etherscan.io/address/0x5aed5f8a1e3607476f1f81c3d8fe126deb0afe94#code#F1#L361). + :param data_length: the length of the data + :param base_fee: the base fee + :return: the submission fee + """ + return (1400 + 6 * data_length) * base_fee + + def estimate_retryable_ticket_gas_limit( + self, + sender: str, + destination: str, + l2_call_value: int, + excess_fee_refund_address: str, + call_value_refund_address: str, + calldata: bytes, + ) -> int: + """ + Estimate the amount of L2 gas required for putting the transaction in the L2 inbox, and executing it. + + Note: This method should be called against Arbitrum, i.e. ledger_api needs to point to arbitrum. + + :param sender: the sender of the L2 transaction + :param destination: target + :param l2_call_value: the amount to transfer + :param excess_fee_refund_address: where to send the refund of fees + :param call_value_refund_address: where to send the refund of call value + :param calldata: the data to be estimated. + :returns: the gas limit + """ + sender_deposit = ONE_ETH + l2_call_value + contract = self.l2.api.eth.contract( + self._node_interface_address, abi=self._node_interface_abi + ) + estimated_gas = contract.functions.estimateRetryableTicket( + sender, + sender_deposit, + destination, + l2_call_value, + excess_fee_refund_address, + call_value_refund_address, + calldata, + ).estimateGas() + return estimated_gas + + def estimate_all( + self, + sender: str, + l2_call_to: str, + l2_call_data: bytes, + l2_call_value: int, + l1_base_fee: int, + excess_fee_refund_address: str, + call_value_refund_address: str, + ) -> L1ToL2Estimate: + """ + Get gas limit, gas price and submission price estimates for sending an L1->L2 message. + + :param sender: Sender of the L1 to L2 transaction + :param l2_call_to: Destination L2 contract address + :param l2_call_data: The hex call data to be sent in the request + :param l2_call_value: The value to be sent on L2 as part of the L2 transaction + :param l1_base_fee: Current l1 base fee + :param excess_fee_refund_address: The address to send excess fee refunds too + :param call_value_refund_address: The address to send the call value + :returns: the estimates for an L1->L2 message. + """ + l2_gas_price = self._get_gas_price(self.l2) + max_fee_per_gas = l2_gas_price * (1 + self.gas_price_percent_increase) + data_length = len(l2_call_data) + submission_fee = self.estimate_submission_fee(data_length, l1_base_fee) + max_submission_fee = submission_fee * (1 + self.submission_fee_percent_increase) + gas_limit = self.estimate_retryable_ticket_gas_limit( + sender, + l2_call_to, + l2_call_value, + excess_fee_refund_address, + call_value_refund_address, + l2_call_data, + ) + total_l2_gas_costs = max_submission_fee + (gas_limit * max_fee_per_gas) + return self.L1ToL2Estimate( + gas_limit, + max_submission_fee, + max_fee_per_gas, + total_l2_gas_costs, + ) + + def get_call_data(self) -> CallData: + """Get call data for Arbitrum.""" + l1_base_fee = self._get_base_fee(self.l1) + gas_price_bid = self._get_gas_price(self.l1) + estimation = self.estimate_all( + self.arbitrum_hub_connector, + self.arbitrum_spoke_connector, + self.spoke_connector_call_data, + ZERO_ETH, + l1_base_fee, + self.arbitrum_spoke_connector, + self.arbitrum_spoke_connector, + ) + + # multiply gas_limit by 5 to be successful in auto-redeem + max_gas = estimation.gas_limit * self.multiplier + submission_price_wei = estimation.max_submission_fee * self.multiplier + fee = submission_price_wei + (max_gas * gas_price_bid) + + encoded_data = self.l2.api.codec.encode_abi( + ["uint256", "uint256", "uint256"], + [submission_price_wei, max_gas, gas_price_bid], + ) + return CallData( + encoded_data, + fee, + ) + + +class ZkSync(L2Network): + """ZkSync network.""" + + gas_limit = 10_000_000 + gas_per_pubdata_byte = 800 + zksync_abi = [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_gasPrice", + "type": "uint256", + }, + { + "internalType": "uint256", + "name": "_l2GasLimit", + "type": "uint256", + }, + { + "internalType": "uint256", + "name": "_l2GasPerPubdataByteLimit", + "type": "uint256", + }, + ], + "name": "l2TransactionBaseCost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + ] + + @property + def l2(self) -> EthereumApi: + """Get the L2 ledger api.""" + return self._ledger_apis[ZKSYNC] + + def _get_mainnet_contract_address(self) -> str: + """Get ZkSync mainnet contract.""" + get_main_contract = RPCEndpoint("zks_getMainContract") + res = self.l2.api.provider.make_request(get_main_contract, []) + contract = res.get("result", None) + if contract is None: + raise ValueError("ZkSync mainnet contract not found.") + return contract + + def _get_tx_cost_price(self) -> int: + """Get the transaction cost price.""" + contract_address = self._get_mainnet_contract_address() + contract = self.l1.api.eth.contract( + address=self.l1.api.toChecksumAddress(contract_address), + abi=self.zksync_abi, + ) + l1_gas_price = self._get_gas_price(self.l1) + tx_cost_price = contract.functions.l2TransactionBaseCost( + l1_gas_price, + self.gas_limit, + self.gas_per_pubdata_byte, + ).call() + return tx_cost_price + + def get_call_data(self) -> CallData: + """Get call data for ZkSync.""" + encoded_data = self.l1.api.codec.encode_abi(["uint256"], [self.gas_limit]) + fee = self._get_tx_cost_price() + return CallData( + encoded_data, + fee, + ) + + +class Consensys(L2Network): + """Consensys L2 network.""" + + fee = 10**16 # 0.01ETH + encoded_data = b"" + + def get_call_data(self) -> CallData: + """Get call data for Consensys.""" + return CallData( + self.encoded_data, + self.fee, + ) + + +class Bnb(L2Network): + """BnB L2 network.""" + + amb_address = "0xC10Ef9F491C9B59f936957026020C321651ac078" + encoded_data = b"" + app_id = "" + target_chain_id = 56 + data_length = 32 + amb_partial_abi = [ + { + "inputs": [ + {"internalType": "string", "name": "_appID", "type": "string"}, + {"internalType": "uint256", "name": "_toChainID", "type": "uint256"}, + {"internalType": "uint256", "name": "_dataLength", "type": "uint256"}, + ], + "name": "calcSrcFees", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function", + } + ] + + def _get_fee(self) -> int: + """Get the transaction cost price.""" + amb_contract = self.l1.api.eth.contract( + self.l1.api.toChecksumAddress(self.amb_address), + abi=self.amb_partial_abi, + ) + fee = amb_contract.functions.calcSrcFees( + self.app_id, self.target_chain_id, self.data_length + ).call() + return fee + + def get_call_data(self) -> CallData: + """Get call data for BnB.""" + fee = self._get_fee() + return CallData( + self.encoded_data, + fee, + ) + + +class Gnosis(L2Network): + """Gnosis L2 network.""" + + fee = 0 + amb_address = "0x4C36d2919e407f0Cc2Ee3c993ccF8ac26d9CE64e" + amb_partial_abi = [ + { + "constant": True, + "inputs": [], + "name": "maxGasPerTx", + "outputs": [{"name": "", "type": "uint256"}], + "payable": False, + "stateMutability": "view", + "type": "function", + } + ] + encoded_data = b"" + + def _get_fee(self) -> int: + """Get the transaction cost price.""" + amb_contract = self.l1.api.eth.contract( + self.l1.api.toChecksumAddress(self.amb_address), + abi=self.amb_partial_abi, + ) + fee = amb_contract.functions.maxGasPerTx().call() + return fee + + def get_call_data(self) -> CallData: + """Get call data for Gnosis.""" + fee = self._get_fee() + encoded_data = self.l1.api.codec.encode_abi(["uint256"], [fee]) + return CallData( + encoded_data, + self.fee, + ) + + +GOERLI_CONFIG = [ + ( + "0xd045f03686575f042b21d0b3d20ffae4d3a3482f", + None, + ), + ( + "0x9060e2b92a4e8d4ead05b7f3d736e3da33955fa5", + None, + ), + ( + "0xe9c7095c956f9f75e21dd99027adf6bfffa9ba9a", + None, + ), + ( + "0x58d3464e5aab9c598a7059d182720a04ad59b01f", + Arbitrum, + ), + ( + "0x9f02b394d8f0e2df3f6913f375cd1f919c03987d", + Consensys, + ), + ( + "0x80231092091d752e1506d4aab393675ebe388e9e", + ZkSync, + ), + ( + "0x49174424e29950ad18d07b4d9ad2f77d0cbdda2a", + None, + ), +] +MAINNET_CONFIG = [ + ("0xfaf539a73659feaec96ec7242f075be0445526a8", Bnb), + ("0x245F757d660C3ec65416168690431076d58d6413", Gnosis), + ("0x4a0126ee88018393b1ad2455060bc350ead9908a", None), + ("0xb01bc38909413f5dbb8f18a9b5787a62ce1282ae", None), + ("0xf7c4d7dcec2c09a15f2db5831d6d25eaef0a296c", None), + ("0xd151c9ef49ce2d30b829a98a07767e3280f70961", Arbitrum), +] +MAINNET_ID = 1 +GOERLI_ID = 5 + + +CONNECTOR_CONFIGS: Dict[int, List[Tuple[str, Optional[Type[L2Network]]]]] = { + MAINNET_ID: MAINNET_CONFIG, + GOERLI_ID: GOERLI_CONFIG, +} + + +class ConnextPropagateJobContract(Contract): + """Class for the ConnextPropagateJob contract.""" + + contract_id = PUBLIC_ID + + def get_off_chain_data( + self, ledger_api: EthereumApi, contract_address: str, **kwargs: Any + ) -> JSONLike: + """ + Get the off chain data from the contract. + + :param ledger_api: the ledger API object + :param contract_address: the contract address + :param kwargs: other keyword arguments + :return: the off chain data + """ + return dict(set_ledger_api_configs=True) + + @staticmethod + def _get_call_data( + ledger_apis: Dict[str, EthereumApi], + chain_id: int, + ) -> Tuple[List[str], List[bytes], List[int]]: + """Get the call data""" + connector_config = CONNECTOR_CONFIGS[chain_id] + connectors, encoded_data, fees = [], [], [] + for connector, l2_network in connector_config: + single_encoded_data, fee = b"", 0 + if l2_network is not None: + l2_network_instance = l2_network(ledger_apis) + call_data = l2_network_instance.get_call_data() + single_encoded_data = call_data.encoded_data + fee = call_data.fee + connectors.append(ledger_apis[ETHEREUM_L1].api.toChecksumAddress(connector)) + encoded_data.append(single_encoded_data) + fees.append(fee) + return connectors, encoded_data, fees + + @classmethod + def _get_ledger_apis( + cls, api_configs: Dict[str, Dict[str, Any]] + ) -> Dict[str, EthereumApi]: + """Get the ledger APIs.""" + ledgers: Dict[str, EthereumApi] = {} + for ledger_api_id in REQUIRED_LEDGER_APIS: + if ledger_api_id not in api_configs: + raise ValueError(f"Ledger API '{ledger_api_id}' not found in configs.") + ledger_api = ledger_apis_registry.make( + ETHEREUM_L1, **api_configs[ledger_api_id] + ) + ledgers[ledger_api_id] = cast(EthereumApi, ledger_api) + return ledgers + + @classmethod + def workable( + cls, + ledger_api: EthereumApi, + contract_address: str, + **kwargs: Any, + ) -> JSONLike: + """Get the workable flag from the contract.""" + # this job is always assumed workable + # whether its actually workable or not is determined by the simulation + is_workable = True + return dict(data=is_workable) + + @classmethod + def build_work_tx( # pylint: disable=too-many-arguments,too-many-locals + cls, + ledger_api: EthereumApi, + contract_address: str, + **kwargs: Any, + ) -> JSONLike: + """ + Get the raw work transaction + + :param ledger_api: the ledger API object + :param contract_address: the contract address + :param kwargs: keyword arguments + + :return: the raw transaction + """ + contract = cls.get_instance(ledger_api, contract_address) + ledger_api_configs = kwargs.get("ledger_api_configs", None) + if ledger_api_configs is None: + raise ValueError("'ledger_api_configs' is required.") + ledger_apis = cls._get_ledger_apis(ledger_api_configs) + chain_id = ledger_api.api.eth.chainId + connectors, encoded_data, fees = cls._get_call_data(ledger_apis, chain_id) + data = contract.encodeABI( + fn_name="propagateKeep3r", + args=[connectors, fees, encoded_data], + ) + return dict(data=data) + + @classmethod + def simulate_tx( + cls, + ledger_api: EthereumApi, + contract_address: str, + data: bytes, + **kwargs: Any, + ) -> JSONLike: + """Simulate the transaction.""" + keep3r_address = kwargs.get("keep3r_address", None) + if keep3r_address is None: + raise ValueError("'keep3r_address' is required.") + try: + ledger_api.api.eth.call( + { + "from": ledger_api.api.toChecksumAddress(keep3r_address), + "to": ledger_api.api.toChecksumAddress(contract_address), + "data": data.hex(), + } + ) + simulation_ok = True + except ValueError as e: + _logger.info(f"Simulation failed: {str(e)}") + simulation_ok = False + + return dict(data=simulation_ok) diff --git a/packages/valory/contracts/connext_propagate_job/contract.yaml b/packages/valory/contracts/connext_propagate_job/contract.yaml new file mode 100644 index 00000000..cadc7169 --- /dev/null +++ b/packages/valory/contracts/connext_propagate_job/contract.yaml @@ -0,0 +1,21 @@ +name: connext_propagate_job +author: valory +version: 0.1.0 +type: contract +description: Connext Propagate (Keep3r) Job Contract +license: Apache-2.0 +aea_version: '>=1.0.0, <2.0.0' +fingerprint: + RelayerProxyHub.json: bafybeiemclag3uctrlaq4vzfqnbf4zgeiolkeo2ntc4vyjo7gcztcy3gim + __init__.py: bafybeihk6gcwr2k35nlz3jmhsuassxkwswvgiwf44bc3s7kqq55ga5vjgu + contract.py: bafybeiedewfjoxe7oueydqkc5rbhyipev5fborqpc5mm3tleam3ltlie2e +fingerprint_ignore_patterns: [] +contracts: [] +class_name: ConnextPropagateJobContract +contract_interface_paths: + ethereum: RelayerProxyHub.json +dependencies: + open-aea-ledger-ethereum: + version: ==1.31.0 + web3: + version: ==5.25.0 diff --git a/packages/valory/contracts/deposit_manager_job/contract.py b/packages/valory/contracts/deposit_manager_job/contract.py index 4ec63d76..01b7affa 100644 --- a/packages/valory/contracts/deposit_manager_job/contract.py +++ b/packages/valory/contracts/deposit_manager_job/contract.py @@ -40,6 +40,21 @@ class DepositManagerJobContract(Contract): contract_id = PUBLIC_ID + def get_off_chain_data( + self, ledger_api: EthereumApi, contract_address: str, **kwargs: Any + ) -> JSONLike: + """ + Get the off chain data from the contract. + + This contract doesn't have any off-chain data. + + :param ledger_api: the ledger API object + :param contract_address: the contract address + :param kwargs: other keyword arguments + :return: the off chain data + """ + return dict() + @classmethod def workable( cls, @@ -77,3 +92,30 @@ def build_work_tx( # pylint: disable=too-many-arguments,too-many-locals return dict( data=data, ) + + @classmethod + def simulate_tx( + cls, + ledger_api: EthereumApi, + contract_address: str, + data: bytes, + **kwargs: Any, + ) -> JSONLike: + """Simulate the transaction.""" + keep3r_address = kwargs.get("keep3r_address", None) + if keep3r_address is None: + raise ValueError("'keep3r_address' is required.") + try: + ledger_api.api.eth.call( + { + "from": ledger_api.api.toChecksumAddress(keep3r_address), + "to": ledger_api.api.toChecksumAddress(contract_address), + "data": data.hex(), + } + ) + simulation_ok = True + except ValueError as e: + _logger.info(f"Simulation failed: {str(e)}") + simulation_ok = False + + return dict(data=simulation_ok) diff --git a/packages/valory/contracts/deposit_manager_job/contract.yaml b/packages/valory/contracts/deposit_manager_job/contract.yaml index f82b249c..a028aad6 100644 --- a/packages/valory/contracts/deposit_manager_job/contract.yaml +++ b/packages/valory/contracts/deposit_manager_job/contract.yaml @@ -8,7 +8,7 @@ aea_version: '>=1.0.0, <2.0.0' fingerprint: DepositManager.json: bafybeigprsi6ehxjbhl7qu4c67c7pvkbyybpr5tgbokdpffawvhi36a25u __init__.py: bafybeihkofb3skgfaeylolyzstwqc35jjf6clolnxme354mxswpecs244y - contract.py: bafybeicbmflz5fvsnen53wgkp6vq2vi2l24j7zjimty3snx7c6tcmycf4e + contract.py: bafybeicnfwkpst55hg2eqipp5cilwpfkno5lvvc32aelnilnatbt2tiwje fingerprint_ignore_patterns: [] contracts: [] class_name: DepositManagerJobContract diff --git a/packages/valory/contracts/keep3r_my_job/contract.py b/packages/valory/contracts/keep3r_my_job/contract.py index 477c935d..d4a48319 100644 --- a/packages/valory/contracts/keep3r_my_job/contract.py +++ b/packages/valory/contracts/keep3r_my_job/contract.py @@ -40,6 +40,21 @@ class Keep3rMyJobContract(Contract): contract_id = PUBLIC_ID + def get_off_chain_data( + self, ledger_api: EthereumApi, contract_address: str, **kwargs: Any + ) -> JSONLike: + """ + Get the off chain data from the contract. + + This contract doesn't have any off-chain data. + + :param ledger_api: the ledger API object + :param contract_address: the contract address + :param kwargs: other keyword arguments + :return: the off chain data + """ + return dict() + @classmethod def workable( cls, @@ -77,3 +92,30 @@ def build_work_tx( # pylint: disable=too-many-arguments,too-many-locals return dict( data=data, ) + + @classmethod + def simulate_tx( + cls, + ledger_api: EthereumApi, + contract_address: str, + data: bytes, + **kwargs: Any, + ) -> JSONLike: + """Simulate the transaction.""" + keep3r_address = kwargs.get("keep3r_address", None) + if keep3r_address is None: + raise ValueError("'keep3r_address' is required.") + try: + ledger_api.api.eth.call( + { + "from": ledger_api.api.toChecksumAddress(keep3r_address), + "to": ledger_api.api.toChecksumAddress(contract_address), + "data": data.hex(), + } + ) + simulation_ok = True + except ValueError as e: + _logger.info(f"Simulation failed: {str(e)}") + simulation_ok = False + + return dict(data=simulation_ok) diff --git a/packages/valory/contracts/keep3r_my_job/contract.yaml b/packages/valory/contracts/keep3r_my_job/contract.yaml index 5c061daa..1a0fc9a2 100644 --- a/packages/valory/contracts/keep3r_my_job/contract.yaml +++ b/packages/valory/contracts/keep3r_my_job/contract.yaml @@ -8,7 +8,7 @@ aea_version: '>=1.0.0, <2.0.0' fingerprint: MyJob.json: bafybeificactlkmcctad2xh5zj2j5tevjz64uzzhcp6epcubajzhto5ppy __init__.py: bafybeibrrtb3cxckcos5bjl3kff7rzdbal2rtibntjvwhchwyu3m3p72ti - contract.py: bafybeidewku7ksfx45yw6axskfkfakqtseg33znwzzjosmrrvtaxkgu4lm + contract.py: bafybeig3i5ewamiz6oa5dlqm6f3u5gaic3fdtdiyy744vtxmrte5fnrm7m fingerprint_ignore_patterns: [] contracts: [] class_name: Keep3rMyJobContract diff --git a/packages/valory/contracts/keep3r_test_job/contract.py b/packages/valory/contracts/keep3r_test_job/contract.py index 8ee15bcb..4f6e1cf1 100644 --- a/packages/valory/contracts/keep3r_test_job/contract.py +++ b/packages/valory/contracts/keep3r_test_job/contract.py @@ -40,6 +40,21 @@ class Keep3rTestJobContract(Contract): contract_id = PUBLIC_ID + def get_off_chain_data( + self, ledger_api: EthereumApi, contract_address: str, **kwargs: Any + ) -> JSONLike: + """ + Get the off chain data from the contract. + + This contract doesn't have any off-chain data. + + :param ledger_api: the ledger API object + :param contract_address: the contract address + :param kwargs: other keyword arguments + :return: the off chain data + """ + return dict() + @classmethod def workable( cls, @@ -77,3 +92,30 @@ def build_work_tx( # pylint: disable=too-many-arguments,too-many-locals return dict( data=data, ) + + @classmethod + def simulate_tx( + cls, + ledger_api: EthereumApi, + contract_address: str, + data: bytes, + **kwargs: Any, + ) -> JSONLike: + """Simulate the transaction.""" + keep3r_address = kwargs.get("keep3r_address", None) + if keep3r_address is None: + raise ValueError("'keep3r_address' is required.") + try: + ledger_api.api.eth.call( + { + "from": ledger_api.api.toChecksumAddress(keep3r_address), + "to": ledger_api.api.toChecksumAddress(contract_address), + "data": data.hex(), + } + ) + simulation_ok = True + except ValueError as e: + _logger.info(f"Simulation failed: {str(e)}") + simulation_ok = False + + return dict(data=simulation_ok) diff --git a/packages/valory/contracts/keep3r_test_job/contract.yaml b/packages/valory/contracts/keep3r_test_job/contract.yaml index ef73d987..e91449fc 100644 --- a/packages/valory/contracts/keep3r_test_job/contract.yaml +++ b/packages/valory/contracts/keep3r_test_job/contract.yaml @@ -8,7 +8,7 @@ aea_version: '>=1.0.0, <2.0.0' fingerprint: TestJob.json: bafybeid2jbxe2rfsfvjysvv6bv6cgj6doysl3qswhdljzkevazvuih3jki __init__.py: bafybeicyhinax5gjp2li37yug35u4aef2z3afrznmlr2rsvdpmh6m4g3sy - contract.py: bafybeibbd4s4nzpug62xaq53fg34v5hxaxxopkax2xsr5jhfx3spgfur2u + contract.py: bafybeigq3mrzyzxwxf3qdjxpsqqflwzxqrpjvaewimvi5dlafubmn6eu24 fingerprint_ignore_patterns: [] contracts: [] class_name: Keep3rTestJobContract diff --git a/packages/valory/contracts/phuture_harvesting_job/contract.py b/packages/valory/contracts/phuture_harvesting_job/contract.py index 9062340f..bd227421 100644 --- a/packages/valory/contracts/phuture_harvesting_job/contract.py +++ b/packages/valory/contracts/phuture_harvesting_job/contract.py @@ -43,6 +43,21 @@ class PhutureHarvestingJobContract(Contract): contract_id = PUBLIC_ID + def get_off_chain_data( + self, ledger_api: EthereumApi, contract_address: str, **kwargs: Any + ) -> JSONLike: + """ + Get the off chain data from the contract. + + This contract doesn't have any off-chain data. + + :param ledger_api: the ledger API object + :param contract_address: the contract address + :param kwargs: other keyword arguments + :return: the off chain data + """ + return dict() + @classmethod def _has_deposits(cls, ledger_api: EthereumApi, config_address: str) -> bool: """Check if there are depoists in the vault.""" @@ -125,3 +140,30 @@ def build_work_tx( # pylint: disable=too-many-arguments,too-many-locals return dict( data=data, ) + + @classmethod + def simulate_tx( + cls, + ledger_api: EthereumApi, + contract_address: str, + data: bytes, + **kwargs: Any, + ) -> JSONLike: + """Simulate the transaction.""" + keep3r_address = kwargs.get("keep3r_address", None) + if keep3r_address is None: + raise ValueError("'keep3r_address' is required.") + try: + ledger_api.api.eth.call( + { + "from": ledger_api.api.toChecksumAddress(keep3r_address), + "to": ledger_api.api.toChecksumAddress(contract_address), + "data": data.hex(), + } + ) + simulation_ok = True + except ValueError as e: + _logger.info(f"Simulation failed: {str(e)}") + simulation_ok = False + + return dict(data=simulation_ok) diff --git a/packages/valory/contracts/phuture_harvesting_job/contract.yaml b/packages/valory/contracts/phuture_harvesting_job/contract.yaml index 9e8d9133..1fd04387 100644 --- a/packages/valory/contracts/phuture_harvesting_job/contract.yaml +++ b/packages/valory/contracts/phuture_harvesting_job/contract.yaml @@ -8,7 +8,7 @@ aea_version: '>=1.0.0, <2.0.0' fingerprint: PhutureJob.json: bafybeidzaxpbdkn3cnxcdanxuoj7klp23u6spd6wsj4ogtfiofzhr3mhhi __init__.py: bafybeiflwdigkqjdp33usxkaozixd5cwyq35jy6eyf2lcr2gtp5kjbs6re - contract.py: bafybeiee5ujtxbmbatb5pt3zivvibfr6dgtw6jet7p46igsxp5szlholai + contract.py: bafybeifunj3jzqrka3ndgmszxqz7dwioglrtu5udor5cvtr3fvtgb57fim test_contract.py: bafybeibaxbkneiubpg4rmtojgzbz4vqrtluye7cmvpmgur5hbvoz4kvz2q fingerprint_ignore_patterns: [] contracts: [] diff --git a/packages/valory/contracts/yearn_factory_harvest_job/contract.py b/packages/valory/contracts/yearn_factory_harvest_job/contract.py index 6d054bee..4328be54 100644 --- a/packages/valory/contracts/yearn_factory_harvest_job/contract.py +++ b/packages/valory/contracts/yearn_factory_harvest_job/contract.py @@ -80,6 +80,21 @@ class YearnFactoryHarvestJobContract(Contract): contract_id = PUBLIC_ID + def get_off_chain_data( + self, ledger_api: EthereumApi, contract_address: str, **kwargs: Any + ) -> JSONLike: + """ + Get the off chain data from the contract. + + This contract doesn't have any off-chain data. + + :param ledger_api: the ledger API object + :param contract_address: the contract address + :param kwargs: other keyword arguments + :return: the off chain data + """ + return dict(chain_id="arbitrum") + @classmethod def workable( cls, @@ -251,3 +266,30 @@ def static_work(strategy: str) -> bool: if static_work(strategy) ] return workable_strategies + + @classmethod + def simulate_tx( + cls, + ledger_api: EthereumApi, + contract_address: str, + data: bytes, + **kwargs: Any, + ) -> JSONLike: + """Simulate the transaction.""" + keep3r_address = kwargs.get("keep3r_address", None) + if keep3r_address is None: + raise ValueError("'keep3r_address' is required.") + try: + ledger_api.api.eth.call( + { + "from": ledger_api.api.toChecksumAddress(keep3r_address), + "to": ledger_api.api.toChecksumAddress(contract_address), + "data": data.hex(), + } + ) + simulation_ok = True + except ValueError as e: + _logger.info(f"Simulation failed: {str(e)}") + simulation_ok = False + + return dict(data=simulation_ok) diff --git a/packages/valory/contracts/yearn_factory_harvest_job/contract.yaml b/packages/valory/contracts/yearn_factory_harvest_job/contract.yaml index 4d9363f2..6fbe0234 100644 --- a/packages/valory/contracts/yearn_factory_harvest_job/contract.yaml +++ b/packages/valory/contracts/yearn_factory_harvest_job/contract.yaml @@ -8,7 +8,7 @@ aea_version: '>=1.0.0, <2.0.0' fingerprint: YearnFactoryHarvestJob.json: bafybeihgjjq6ttbccz3utl23gdvyige6bcdwwvi5wo2tuu3qv4wqxr4qra __init__.py: bafybeiflwdigkqjdp33usxkaozixd5cwyq35jy6eyf2lcr2gtp5kjbs6re - contract.py: bafybeiadfmg2guy3hd7ieakul2m4u5rt5a45sy37oclx5i4hynr5lmstg4 + contract.py: bafybeiazxzufydrzph4at5mqqg2bh4hoxikocp7fhm7rxn4kog2urcldfm test_contract.py: bafybeihue7ijmrxyxhq3wkch5cxrwwhn6kwo47avelyrzld345fws6ntfm fingerprint_ignore_patterns: [] contracts: [] diff --git a/packages/valory/services/keep3r_bot/service.yaml b/packages/valory/services/keep3r_bot/service.yaml index d9475d24..94f1d799 100644 --- a/packages/valory/services/keep3r_bot/service.yaml +++ b/packages/valory/services/keep3r_bot/service.yaml @@ -7,7 +7,7 @@ license: Apache-2.0 fingerprint: README.md: bafybeig26ntff2vdtmum3crflwqrybmonwdxahvlrst2brnazbo3mjvtqu fingerprint_ignore_patterns: [] -agent: valory/keep3r_bot:0.1.0:bafybeiczanoqalggxexil6b7ibikkfkyrmwxsj2okasdwootn53ehndgem +agent: valory/keep3r_bot:0.1.0:bafybeiaudehe2roq4yauufe7x5lyy3t3h2db4cxkum4iy7g5bznf5mqn4y number_of_agents: 1 deployment: {} --- @@ -18,7 +18,7 @@ models: args: setup: all_participants: ${ALL_PARTICIPANTS:list:["0x0000000000000000000000000000000000000000"]} - safe_contract_address: ${SAFE_CONTRACT_ADDRESS:list:"0x0000000000000000000000000000000000000000"} + safe_contract_address: ${SAFE_CONTRACT_ADDRESS:str:0x0000000000000000000000000000000000000000} bonding_asset: ${BONDING_ASSET:str:0x0000000000000000000000000000000000000000} bond_amount: ${BOND_AMOUNT:int:1} reset_pause_duration: ${RESET_PAUSE_DURATION:int:15} diff --git a/packages/valory/services/keep3r_bot_goerli/service.yaml b/packages/valory/services/keep3r_bot_goerli/service.yaml index 05e6e512..0bd3cfe9 100644 --- a/packages/valory/services/keep3r_bot_goerli/service.yaml +++ b/packages/valory/services/keep3r_bot_goerli/service.yaml @@ -7,7 +7,7 @@ license: Apache-2.0 fingerprint: README.md: bafybeiblcg3qti2cyz4ytufdkmqzcm6svbo5cwgsu2srjovvljdi35iz6i fingerprint_ignore_patterns: [] -agent: valory/keep3r_bot:0.1.0:bafybeiczanoqalggxexil6b7ibikkfkyrmwxsj2okasdwootn53ehndgem +agent: valory/keep3r_bot:0.1.0:bafybeiaudehe2roq4yauufe7x5lyy3t3h2db4cxkum4iy7g5bznf5mqn4y number_of_agents: 1 deployment: {} --- @@ -18,7 +18,7 @@ models: args: setup: all_participants: ${ALL_PARTICIPANTS:list:["0x0000000000000000000000000000000000000000"]} - safe_contract_address: ${SAFE_CONTRACT_ADDRESS:list:"0x0000000000000000000000000000000000000000"} + safe_contract_address: ${SAFE_CONTRACT_ADDRESS:str:0x0000000000000000000000000000000000000000} bonding_asset: ${BONDING_ASSET:str:0x0000000000000000000000000000000000000000} bond_amount: ${BOND_AMOUNT:int:1} reset_pause_duration: ${RESET_PAUSE_DURATION:int:60} diff --git a/packages/valory/skills/abstract_round_abci/skill.yaml b/packages/valory/skills/abstract_round_abci/skill.yaml index a2d08229..844ef949 100644 --- a/packages/valory/skills/abstract_round_abci/skill.yaml +++ b/packages/valory/skills/abstract_round_abci/skill.yaml @@ -63,7 +63,7 @@ connections: - valory/abci:0.1.0:bafybeienpqzsym3rg7nnomd6mxgbt4didwd4wfj72oadde27trdmcgsu5y - valory/http_client:0.23.0:bafybeidykl4elwbcjkqn32wt5h4h7tlpeqovrcq3c5bcplt6nhpznhgczi - valory/ipfs:0.1.0:bafybeie46fu7mv64q72dwzoxg77zbiv3pzsigzjk3rehjpm47cf3y77mha -- valory/ledger:0.19.0:bafybeiez7rieszhh3kmgvz6tvii2ysgx4lbyrhyfujrx3hkmj2gn52b6zu +- valory/ledger:0.19.0:bafybeih4yf73bwvn3cn44b7on2riqe2lbvixcgw3nze63asvwbmyfqyrc4 - valory/p2p_libp2p_client:0.1.0:bafybeidwcobzb7ut3efegoedad7jfckvt2n6prcmd4g7xnkm6hp6aafrva contracts: - valory/service_registry:0.1.0:bafybeigvob5pgz527goh2cgibjejnmbu6xz2e3knjsocjq533m3xe5uzti diff --git a/packages/valory/skills/keep3r_abci/fsm_specification.yaml b/packages/valory/skills/keep3r_abci/fsm_specification.yaml index 05f31622..3fa383ed 100644 --- a/packages/valory/skills/keep3r_abci/fsm_specification.yaml +++ b/packages/valory/skills/keep3r_abci/fsm_specification.yaml @@ -25,6 +25,7 @@ alphabet_in: - RESET_AND_PAUSE_TIMEOUT - RESET_TIMEOUT - ROUND_TIMEOUT +- SIMULATION_FAILED - SUSPICIOUS_ACTIVITY - TOP_UP - UNKNOWN_HEALTH_ISSUE @@ -129,6 +130,7 @@ transition_func: (PerformWorkRound, INSUFFICIENT_FUNDS): PathSelectionRound (PerformWorkRound, NO_MAJORITY): PerformWorkRound (PerformWorkRound, ROUND_TIMEOUT): PerformWorkRound + (PerformWorkRound, SIMULATION_FAILED): JobSelectionRound (PerformWorkRound, WORK_TX): RandomnessTransactionSubmissionRound (RandomnessTransactionSubmissionRound, DONE): SelectKeeperTransactionSubmissionARound (RandomnessTransactionSubmissionRound, NO_MAJORITY): RandomnessTransactionSubmissionRound diff --git a/packages/valory/skills/keep3r_abci/skill.yaml b/packages/valory/skills/keep3r_abci/skill.yaml index d36cfa96..e3b78416 100644 --- a/packages/valory/skills/keep3r_abci/skill.yaml +++ b/packages/valory/skills/keep3r_abci/skill.yaml @@ -11,7 +11,7 @@ fingerprint: behaviours.py: bafybeicqbpkfy2oevhj64rwmfujlxawr3rqbfcw7anzb5p7a35rygzz4qm composition.py: bafybeicjcwhyzaosx5fcvlit4fxbr3i54z2as2kcbdorilqje3obybhviy dialogues.py: bafybeidfvafboay732zd7ez4yblojbzohujfwtp3e5elit7ztenepk6q3a - fsm_specification.yaml: bafybeifzlmodoxdtwmki7lxwt6b7gi5tzdu5cfpn3kopqvcmz5rvtxfhzm + fsm_specification.yaml: bafybeiglxtz2wcczhyl2zirrrc7aq6recrvkwzczvzujvapjdsm556kwbu handlers.py: bafybeihrnok2s2oztglt7on7g5icbugmibikb3y2kqz2imbe23yoij7a5y models.py: bafybeid66pob3so4azlyqqdfpw2edxkjygs36ycrur3zu6hcd4hx6juji4 payloads.py: bafybeifumkl5b5sns5x2freipdoe4yvymr3gbfhcjrv5vawas42qht2ygy @@ -20,11 +20,11 @@ connections: [] contracts: [] protocols: [] skills: -- valory/abstract_round_abci:0.1.0:bafybeibw7khdmdxinnugbjdirh5q4cb4rirf5aqzfj6ai6zbhe7aavr7gy -- valory/keep3r_job:0.1.0:bafybeiflbm45r3gr2nv7pebwwq2vbapy7okoqj57nynfsq6m3yzghsbjka -- valory/registration_abci:0.1.0:bafybeigijk6tyixlbb3jhrlgxfzk7wqopegqbdbklflvor27n3ysu42zty -- valory/reset_pause_abci:0.1.0:bafybeid4atrdi3mflnkg6hiylnmjbfqa323i3wkjhuj4jispxbchukwwiq -- valory/transaction_settlement_abci:0.1.0:bafybeie6mefwzprsqd6n45aleswygs76oekvdlzblq72omjsjtmwdaqwly +- valory/abstract_round_abci:0.1.0:bafybeibbxka2c4mvlo2msxi3wtk654fczkfcnbopftyskmd727pjpbty3e +- valory/keep3r_job:0.1.0:bafybeiezok7h2j7tjkzxpm4qk35rnszretvrkv3dzpqn3kuvbymlvstoua +- valory/registration_abci:0.1.0:bafybeicjvmdle7qkrid6hpr4nepnvt6pl7oznntfhxy2ftrrciu5vb6sqm +- valory/reset_pause_abci:0.1.0:bafybeiay3qgd7jp5xtxqxmbe2net2tm762av42nobosx4atxfjlbe665mi +- valory/transaction_settlement_abci:0.1.0:bafybeie5lp57jwtum4uyq4rdkmoue442l6ssdjabi5rbc2di7wtzixw64i behaviours: main: args: {} diff --git a/packages/valory/skills/keep3r_job/behaviours.py b/packages/valory/skills/keep3r_job/behaviours.py index 6f1ec114..596ca03d 100644 --- a/packages/valory/skills/keep3r_job/behaviours.py +++ b/packages/valory/skills/keep3r_job/behaviours.py @@ -318,11 +318,58 @@ def has_pending_bond( return None return pending_bond > 0 + def get_off_chain_data( + self, + contract_address: str, + contract_id: PublicId, + ) -> Generator[None, None, Optional[Dict[str, Any]]]: + """Get off-chain data""" + contract_api_response = yield from self.get_contract_api_response( + performative=ContractApiMessage.Performative.GET_STATE, + contract_address=contract_address, + contract_id=str(contract_id), + contract_callable="get_off_chain_data", + ) + if contract_api_response.performative != ContractApiMessage.Performative.STATE: + self.context.logger.error( + f"Failed get_off_chain_data: {contract_api_response}" + ) + return None + log_msg = ( + f"`get_off_chain_data` contract api response on {contract_api_response}" + ) + self.context.logger.info(f"{log_msg}: {contract_api_response}") + return cast(Dict[str, Any], contract_api_response.state.body) + + def simulate_tx( + self, + contract_address: str, + contract_id: PublicId, + data: bytes, + safe_address: str, + ) -> Generator[None, None, Optional[bool]]: + """Get off-chain data""" + contract_api_response = yield from self.get_contract_api_response( + performative=ContractApiMessage.Performative.GET_STATE, + contract_address=contract_address, + contract_id=str(contract_id), + contract_callable="simulate_tx", + keep3r_address=safe_address, + data=data, + ) + if contract_api_response.performative != ContractApiMessage.Performative.STATE: + self.context.logger.error(f"Failed simulate_tx: {contract_api_response}") + return None + log_msg = f"`simulate_tx` contract api response on {contract_api_response}" + self.context.logger.info(f"{log_msg}: {contract_api_response}") + return cast(bool, contract_api_response.state.body.get("data", False)) + def is_workable_job( self, contract_address: str, contract_id: PublicId, safe_address: str, + **kwargs: Any, ) -> Generator[None, None, Optional[bool]]: """Check if job contract is workable""" contract_api_response = yield from self.get_contract_api_response( @@ -331,12 +378,13 @@ def is_workable_job( keep3r_address=safe_address, contract_id=str(contract_id), contract_callable="workable", + **kwargs, ) if contract_api_response.performative != ContractApiMessage.Performative.STATE: self.context.logger.error( f"Failed is_workable_job: {contract_api_response}" ) - return True + return False log_msg = f"`workable` contract api response on {contract_api_response}" self.context.logger.info(f"{log_msg}: {contract_api_response}") return cast(bool, contract_api_response.state.body.get("data")) @@ -376,6 +424,8 @@ def build_work_raw_tx( self, job_address: str, contract_id: PublicId, + safe_address: str, + **kwargs: Any, ) -> Generator[None, None, Optional[SafeTx]]: """Build raw work transaction for a job contract""" contract_api_response = yield from self.get_contract_api_response( @@ -383,6 +433,8 @@ def build_work_raw_tx( contract_id=str(contract_id), contract_callable="build_work_tx", contract_address=job_address, + keep3r_address=safe_address, + **kwargs, ) if contract_api_response.performative != ContractApiMessage.Performative.STATE: self.context.logger.error( @@ -785,10 +837,19 @@ def async_act(self) -> Generator: contract_public_id = self.context.state.job_address_to_public_id[ current_job ] + off_chain_data = yield from self.get_off_chain_data( + current_job, + contract_public_id, + ) + if off_chain_data is None: + # something went wrong + yield from self.sleep(self.context.params.sleep_time) + return is_workable = yield from self.is_workable_job( current_job, contract_public_id, self.synchronized_data.safe_contract_address, + **off_chain_data, ) if is_workable is None: # something went wrong @@ -845,14 +906,48 @@ def async_act(self) -> Generator: contract_public_id = self.context.state.job_address_to_public_id[ current_job ] - raw_tx = yield from self.build_work_raw_tx(current_job, contract_public_id) + off_chain_data = yield from self.get_off_chain_data( + current_job, + contract_public_id, + ) + if off_chain_data is None: + # something went wrong + yield from self.sleep(self.context.params.sleep_time) + return + safe_address = self.synchronized_data.safe_contract_address + raw_tx = yield from self.build_work_raw_tx( + current_job, + contract_public_id, + safe_address, + **off_chain_data, + ) if raw_tx is None: yield from self.sleep(self.context.params.sleep_time) return - work_tx = yield from self.build_safe_raw_tx(raw_tx) - if work_tx is None: + + simulation_ok = yield from self.simulate_tx( + current_job, + contract_public_id, + raw_tx.get("data"), + safe_address, + ) + if simulation_ok is None: + # something went wrong while simulating yield from self.sleep(self.context.params.sleep_time) return + if not simulation_ok: + # simulation failed, i.e. a bad tx + self.context.logger.info( + f"Simulating a work tx for job {current_job} failed." + ) + work_tx = cast( + PerformWorkRound, self.matching_round + ).SIMULATION_FAILED_PAYLOAD + else: + work_tx = yield from self.build_safe_raw_tx(raw_tx) + if work_tx is None: + yield from self.sleep(self.context.params.sleep_time) + return payload = WorkTxPayload(self.context.agent_address, work_tx) with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): diff --git a/packages/valory/skills/keep3r_job/fsm_specification.yaml b/packages/valory/skills/keep3r_job/fsm_specification.yaml index 2ad57916..fb1fd712 100644 --- a/packages/valory/skills/keep3r_job/fsm_specification.yaml +++ b/packages/valory/skills/keep3r_job/fsm_specification.yaml @@ -15,6 +15,7 @@ alphabet_in: - NO_MAJORITY - PROFITABLE - ROUND_TIMEOUT +- SIMULATION_FAILED - TOP_UP - UNKNOWN_HEALTH_ISSUE - WORKABLE @@ -89,6 +90,7 @@ transition_func: (PerformWorkRound, INSUFFICIENT_FUNDS): PathSelectionRound (PerformWorkRound, NO_MAJORITY): PerformWorkRound (PerformWorkRound, ROUND_TIMEOUT): PerformWorkRound + (PerformWorkRound, SIMULATION_FAILED): JobSelectionRound (PerformWorkRound, WORK_TX): FinalizeWorkRound (WaitingRound, DONE): ActivationRound (WaitingRound, NO_MAJORITY): WaitingRound diff --git a/packages/valory/skills/keep3r_job/rounds.py b/packages/valory/skills/keep3r_job/rounds.py index de2f6462..95faa76e 100644 --- a/packages/valory/skills/keep3r_job/rounds.py +++ b/packages/valory/skills/keep3r_job/rounds.py @@ -72,6 +72,7 @@ class Event(Enum): TOP_UP = "top_up" NO_MAJORITY = "no_majority" ROUND_TIMEOUT = "round_timeout" + SIMULATION_FAILED = "simulation_failed" class SynchronizedData(BaseSynchronizedData): @@ -341,12 +342,18 @@ class PerformWorkRound(Keep3rJobAbstractRound): payload_class = WorkTxPayload payload_attribute: str = "work_tx" + SIMULATION_FAILED_PAYLOAD = "simulation_failed" + def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Event]]: """Process the end of the block.""" _ = (Event.INSUFFICIENT_FUNDS,) if self.threshold_reached and self.most_voted_payload: work_tx = self.most_voted_payload + if work_tx == self.SIMULATION_FAILED_PAYLOAD: + # if the simulation failed for this job, we go back to job selection + return self.synchronized_data, Event.SIMULATION_FAILED + state = self.synchronized_data.update( **{ get_name(SynchronizedData.most_voted_tx_hash): work_tx, @@ -538,6 +545,7 @@ class Keep3rJobAbciApp(AbciApp[Event]): Event.INSUFFICIENT_FUNDS: PathSelectionRound, Event.NO_MAJORITY: PerformWorkRound, Event.ROUND_TIMEOUT: PerformWorkRound, + Event.SIMULATION_FAILED: JobSelectionRound, }, AwaitTopUpRound: { Event.TOP_UP: PathSelectionRound, diff --git a/packages/valory/skills/keep3r_job/skill.yaml b/packages/valory/skills/keep3r_job/skill.yaml index 97c2ccf7..dcc6d0be 100644 --- a/packages/valory/skills/keep3r_job/skill.yaml +++ b/packages/valory/skills/keep3r_job/skill.yaml @@ -8,19 +8,19 @@ aea_version: '>=1.0.0, <2.0.0' fingerprint: README.md: bafybeidq32yfua6bopvzlo7xwpfdiz4bwr7txkv4vo4vxmjmvdthkr2cwe __init__.py: bafybeigksusqhnsx4dupxnfwj663ofpnhgw7gtkc72iscf5blcczvz6fiq - behaviours.py: bafybeid3r7sb2ujycome7klz2ghi2ffjcon55ryyyo5stfazk7kfbmu3vy + behaviours.py: bafybeidd2xh5aonjma2vvijis3jee7zdg653rnssbxhv47idvqbqcqewqy dialogues.py: bafybeidfvafboay732zd7ez4yblojbzohujfwtp3e5elit7ztenepk6q3a dynamic_package_loader.py: bafybeifdp6ym6jjjqbcu4qcg5vkh2kksvowryvrfcjbklvhvs36653troe - fsm_specification.yaml: bafybeihno5san6zewjsmzpi2mdkud2whgohglaejcnbejblpfaa6nhnlhu + fsm_specification.yaml: bafybeibir4dmfv37ileg54lr7mpr7deq6ex5yy5xf5i2jllhlbauxejkp4 handlers.py: bafybeig7pj6f2gadyirmwp6mu7bce6yqyn2gupdvqtcpnlbcr5wuat465y io_/__init__.py: bafybeifxgmmwjqzezzn3e6keh2bfo4cyo7y5dq2ept3stfmgglbrzfl5rq io_/loader.py: bafybeidbnhostvbufwc4z2ulcgzw3weyps4obpnofkuglaehz2jpwstpbq models.py: bafybeiatjdb5qmk552fpchzt5gwsuranm4v5tjgmnnffcazvculbgo2h6a payloads.py: bafybeid52iwsyzxpauezgr4rxxknjwxb673qqjxxytzlkqvxu3zpz7uonq - rounds.py: bafybeigh6btqavg4cgtszev52xeitdev4opym66fym3p3k6j76uhru6qc4 + rounds.py: bafybeig4tl5fypo7oy6deuj5vkl2tfva6fty5asl5eoixq5fgckxf66yii tests/__init__.py: bafybeihax7nv5wb5pb72cxwemjk5sz55ecsghh4zi3vbmziz2pacyqbrym tests/helpers.py: bafybeigwnsg3r4mqo2rrai56ju4yknd6tvi3edkterbvbnptst5uwz6oa4 - tests/test_behaviours.py: bafybeieb4rxde6ioet4h5cug23c4lswvqktl5fdzmsvtifojh5wfuoxisq + tests/test_behaviours.py: bafybeicqfgdlqvq6ufeymx6vklfqamemlddia46nii2otiqowfgrnctisu tests/test_dialogues.py: bafybeig6ifm5xslmj2k5leitgxeah3wow6vfb7w6zqnckzbxvgdxsc3oae tests/test_payloads.py: bafybeig7xcopncbirln7dzbpsm44cvmmh2iqbh7qaiosfg7gpnqkdmfpna tests/test_rounds.py: bafybeihujqsizzft66trlhgvzgd337pzy6xhjy632bztmr443d456l5qzm @@ -34,8 +34,8 @@ protocols: - valory/contract_api:1.0.0:bafybeidv6wxpjyb2sdyibnmmum45et4zcla6tl63bnol6ztyoqvpl4spmy - valory/ledger_api:1.0.0:bafybeieylbg4qb3dmjlm3zufqcwq4qbygsdgj3jzc53eyoqmd25mdz2pkq skills: -- valory/abstract_round_abci:0.1.0:bafybeibw7khdmdxinnugbjdirh5q4cb4rirf5aqzfj6ai6zbhe7aavr7gy -- valory/transaction_settlement_abci:0.1.0:bafybeie6mefwzprsqd6n45aleswygs76oekvdlzblq72omjsjtmwdaqwly +- valory/abstract_round_abci:0.1.0:bafybeibbxka2c4mvlo2msxi3wtk654fczkfcnbopftyskmd727pjpbty3e +- valory/transaction_settlement_abci:0.1.0:bafybeie5lp57jwtum4uyq4rdkmoue442l6ssdjabi5rbc2di7wtzixw64i behaviours: main: args: {} diff --git a/packages/valory/skills/keep3r_job/tests/test_behaviours.py b/packages/valory/skills/keep3r_job/tests/test_behaviours.py index beeb1243..a6b5ff97 100644 --- a/packages/valory/skills/keep3r_job/tests/test_behaviours.py +++ b/packages/valory/skills/keep3r_job/tests/test_behaviours.py @@ -225,6 +225,46 @@ def mock_workable_call(self, data: bool) -> None: ), ) + def mock_get_off_chain_data(self) -> None: + """Mock "get_off_chain_data" contract call""" + + contract_callable = "get_off_chain_data" + self.mock_contract_api_request( + request_kwargs=dict( + performative=ContractApiMessage.Performative.GET_STATE, + callable=contract_callable, + ), + contract_id=str(TEST_JOB_CONTRACT_ID), + response_kwargs=dict( + performative=ContractApiMessage.Performative.STATE, + callable=contract_callable, + state=ContractApiMessage.State( + ledger_id="ethereum", + body={"data": {}}, + ), + ), + ) + + def mock_simulate_tx(self, simulation_ok: bool) -> None: + """Mock "get_off_chain_data" contract call""" + + contract_callable = "simulate_tx" + self.mock_contract_api_request( + request_kwargs=dict( + performative=ContractApiMessage.Performative.GET_STATE, + callable=contract_callable, + ), + contract_id=str(TEST_JOB_CONTRACT_ID), + response_kwargs=dict( + performative=ContractApiMessage.Performative.STATE, + callable=contract_callable, + state=ContractApiMessage.State( + ledger_id="ethereum", + body={"data": simulation_ok}, + ), + ), + ) + def mock_build_work_tx_call(self, data: str) -> None: """Mock build work transaction""" @@ -495,14 +535,26 @@ class TestPerformWorkBehaviour(Keep3rJobFSMBehaviourBaseCase): behaviour_class: Type[BaseBehaviour] = PerformWorkBehaviour - def test_run(self) -> None: + @pytest.mark.parametrize( + "simulation_ok, event, next_round", + [ + (True, Event.WORK_TX, IsProfitableRound), + (False, Event.SIMULATION_FAILED, JobSelectionRound), + ], + ) + def test_run( + self, simulation_ok: bool, event: Event, next_round: Keep3rJobAbstractRound + ) -> None: """Test perform work.""" self.behaviour.context.state.job_address_to_public_id[ DUMMY_CONTRACT ] = TEST_JOB_CONTRACT_ID self.behaviour.act_wrapper() + self.mock_get_off_chain_data() self.mock_build_work_tx_call(DUMMY_DATA) - self.mock_build_safe_raw_tx() + self.mock_simulate_tx(simulation_ok) + if simulation_ok: + self.mock_build_safe_raw_tx() self.mock_a2a_transaction() self._test_done_flag_set() self.end_round(done_event=Event.WORK_TX) @@ -556,6 +608,7 @@ def test_is_workable( DUMMY_CONTRACT ] = TEST_JOB_CONTRACT_ID self.behaviour.act_wrapper() + self.mock_get_off_chain_data() self.mock_workable_call(is_workable) self.behaviour.act_wrapper() self.mock_a2a_transaction() diff --git a/packages/valory/skills/registration_abci/skill.yaml b/packages/valory/skills/registration_abci/skill.yaml index 9d802dd2..044884aa 100644 --- a/packages/valory/skills/registration_abci/skill.yaml +++ b/packages/valory/skills/registration_abci/skill.yaml @@ -32,7 +32,7 @@ protocols: - valory/http:1.0.0:bafybeifyoio7nlh5zzyn5yz7krkou56l22to3cwg7gw5v5o3vxwklibhty - valory/tendermint:0.1.0:bafybeicusvezoqlmyt6iqomcbwaz3xkhk2qf3d56q5zprmj3xdxfy64k54 skills: -- valory/abstract_round_abci:0.1.0:bafybeibw7khdmdxinnugbjdirh5q4cb4rirf5aqzfj6ai6zbhe7aavr7gy +- valory/abstract_round_abci:0.1.0:bafybeibbxka2c4mvlo2msxi3wtk654fczkfcnbopftyskmd727pjpbty3e behaviours: main: args: {} diff --git a/packages/valory/skills/reset_pause_abci/skill.yaml b/packages/valory/skills/reset_pause_abci/skill.yaml index 447ac539..a5cac0a6 100644 --- a/packages/valory/skills/reset_pause_abci/skill.yaml +++ b/packages/valory/skills/reset_pause_abci/skill.yaml @@ -26,7 +26,7 @@ connections: [] contracts: [] protocols: [] skills: -- valory/abstract_round_abci:0.1.0:bafybeibw7khdmdxinnugbjdirh5q4cb4rirf5aqzfj6ai6zbhe7aavr7gy +- valory/abstract_round_abci:0.1.0:bafybeibbxka2c4mvlo2msxi3wtk654fczkfcnbopftyskmd727pjpbty3e behaviours: main: args: {} diff --git a/packages/valory/skills/termination_abci/skill.yaml b/packages/valory/skills/termination_abci/skill.yaml index f4415de4..644e68ed 100644 --- a/packages/valory/skills/termination_abci/skill.yaml +++ b/packages/valory/skills/termination_abci/skill.yaml @@ -29,8 +29,8 @@ contracts: protocols: - valory/contract_api:1.0.0:bafybeidv6wxpjyb2sdyibnmmum45et4zcla6tl63bnol6ztyoqvpl4spmy skills: -- valory/abstract_round_abci:0.1.0:bafybeibw7khdmdxinnugbjdirh5q4cb4rirf5aqzfj6ai6zbhe7aavr7gy -- valory/transaction_settlement_abci:0.1.0:bafybeie6mefwzprsqd6n45aleswygs76oekvdlzblq72omjsjtmwdaqwly +- valory/abstract_round_abci:0.1.0:bafybeibbxka2c4mvlo2msxi3wtk654fczkfcnbopftyskmd727pjpbty3e +- valory/transaction_settlement_abci:0.1.0:bafybeie5lp57jwtum4uyq4rdkmoue442l6ssdjabi5rbc2di7wtzixw64i behaviours: main: args: {} diff --git a/packages/valory/skills/transaction_settlement_abci/skill.yaml b/packages/valory/skills/transaction_settlement_abci/skill.yaml index adaf1235..b5552c4f 100644 --- a/packages/valory/skills/transaction_settlement_abci/skill.yaml +++ b/packages/valory/skills/transaction_settlement_abci/skill.yaml @@ -38,7 +38,7 @@ protocols: - valory/contract_api:1.0.0:bafybeidv6wxpjyb2sdyibnmmum45et4zcla6tl63bnol6ztyoqvpl4spmy - valory/ledger_api:1.0.0:bafybeieylbg4qb3dmjlm3zufqcwq4qbygsdgj3jzc53eyoqmd25mdz2pkq skills: -- valory/abstract_round_abci:0.1.0:bafybeibw7khdmdxinnugbjdirh5q4cb4rirf5aqzfj6ai6zbhe7aavr7gy +- valory/abstract_round_abci:0.1.0:bafybeibbxka2c4mvlo2msxi3wtk654fczkfcnbopftyskmd727pjpbty3e behaviours: main: args: {} diff --git a/tox.ini b/tox.ini index d9280d1a..c59e6dfe 100644 --- a/tox.ini +++ b/tox.ini @@ -175,6 +175,7 @@ skipsdist = True skip_install = True deps = tomte[isort]==0.2.4 commands = + isort packages/valory/contracts/connext_propagate_job isort packages/valory/contracts/deposit_manager_job isort packages/valory/contracts/keep3r_for_testnet isort packages/valory/contracts/keep3r_my_job @@ -198,6 +199,7 @@ skipsdist = True skip_install = True deps = tomte[isort]==0.2.4 commands = + isort --check-only packages/valory/contracts/connext_propagate_job isort --check-only packages/valory/contracts/deposit_manager_job isort --check-only packages/valory/contracts/keep3r_for_testnet isort --check-only packages/valory/contracts/keep3r_my_job @@ -249,7 +251,7 @@ skip_install = True deps = tomte[flake8]==0.2.4 commands = - flake8 packages/valory/skills/keep3r_abci packages/valory/skills/keep3r_job packages/valory/contracts/deposit_manager_job packages/valory/contracts/keep3r_for_testnet packages/valory/contracts/keep3r_my_job packages/valory/contracts/keep3r_test_job packages/valory/contracts/keep3r_v1 packages/valory/contracts/keep3r_v1_library packages/valory/contracts/phuture_harvesting_job packages/valory/contracts/yearn_factory_harvest_job packages/valory/skills/registration_abci packages/valory/skills/reset_pause_abci packages/valory/skills/termination_abci packages/valory/skills/transaction_settlement_abci scripts + flake8 packages/valory/contracts/connext_propagate_job packages/valory/skills/keep3r_abci packages/valory/skills/keep3r_job packages/valory/contracts/deposit_manager_job packages/valory/contracts/keep3r_for_testnet packages/valory/contracts/keep3r_my_job packages/valory/contracts/keep3r_test_job packages/valory/contracts/keep3r_v1 packages/valory/contracts/keep3r_v1_library packages/valory/contracts/phuture_harvesting_job packages/valory/contracts/yearn_factory_harvest_job packages/valory/skills/registration_abci packages/valory/skills/reset_pause_abci packages/valory/skills/termination_abci packages/valory/skills/transaction_settlement_abci scripts [testenv:mypy] skipsdist = True @@ -261,7 +263,7 @@ deps = commands = autonomy init --reset --author ci --remote --ipfs --ipfs-node "/dns/registry.autonolas.tech/tcp/443/https" autonomy packages sync - mypy packages/valory/skills/keep3r_abci packages/valory/skills/keep3r_job packages/valory/contracts/deposit_manager_job packages/valory/contracts/keep3r_for_testnet packages/valory/contracts/keep3r_my_job packages/valory/contracts/keep3r_test_job packages/valory/contracts/keep3r_v1 packages/valory/contracts/keep3r_v1_library packages/valory/contracts/phuture_harvesting_job packages/valory/contracts/yearn_factory_harvest_job packages/valory/skills/registration_abci packages/valory/skills/reset_pause_abci packages/valory/skills/termination_abci packages/valory/skills/transaction_settlement_abci scripts + mypy packages/valory/skills/keep3r_abci packages/valory/skills/keep3r_job packages/valory/contracts/deposit_manager_job packages/valory/contracts/keep3r_for_testnet packages/valory/contracts/keep3r_my_job packages/valory/contracts/keep3r_test_job packages/valory/contracts/keep3r_v1 packages/valory/contracts/keep3r_v1_library packages/valory/contracts/phuture_harvesting_job packages/valory/contracts/yearn_factory_harvest_job packages/valory/contracts/connext_propagate_job packages/valory/skills/registration_abci packages/valory/skills/reset_pause_abci packages/valory/skills/termination_abci packages/valory/skills/transaction_settlement_abci scripts [testenv:pylint] whitelist_externals = /bin/sh @@ -270,7 +272,7 @@ deps = {[testenv]deps} tomte[pylint]==0.2.4 commands = - pylint packages/valory/skills/keep3r_abci packages/valory/skills/keep3r_job packages/valory/contracts/deposit_manager_job packages/valory/contracts/keep3r_for_testnet packages/valory/contracts/keep3r_my_job packages/valory/contracts/keep3r_test_job packages/valory/contracts/keep3r_v1 packages/valory/contracts/keep3r_v1_library packages/valory/contracts/phuture_harvesting_job packages/valory/contracts/yearn_factory_harvest_job packages/valory/skills/registration_abci packages/valory/skills/reset_pause_abci packages/valory/skills/termination_abci packages/valory/skills/transaction_settlement_abci scripts + pylint packages/valory/contracts/connext_propagate_job packages/valory/skills/keep3r_abci packages/valory/skills/keep3r_job packages/valory/contracts/deposit_manager_job packages/valory/contracts/keep3r_for_testnet packages/valory/contracts/keep3r_my_job packages/valory/contracts/keep3r_test_job packages/valory/contracts/keep3r_v1 packages/valory/contracts/keep3r_v1_library packages/valory/contracts/phuture_harvesting_job packages/valory/contracts/yearn_factory_harvest_job packages/valory/skills/registration_abci packages/valory/skills/reset_pause_abci packages/valory/skills/termination_abci packages/valory/skills/transaction_settlement_abci scripts [testenv:safety] skipsdist = True @@ -284,7 +286,7 @@ skipsdist = True skip_install = True deps = tomte[darglint]==0.2.4 -commands = darglint packages/valory/skills/keep3r_abci packages/valory/skills/keep3r_job packages/valory/contracts/deposit_manager_job packages/valory/contracts/keep3r_for_testnet packages/valory/contracts/keep3r_my_job packages/valory/contracts/keep3r_test_job packages/valory/contracts/keep3r_v1 packages/valory/contracts/keep3r_v1_library packages/valory/contracts/phuture_harvesting_job packages/valory/contracts/yearn_factory_harvest_job packages/valory/skills/registration_abci packages/valory/skills/reset_pause_abci packages/valory/skills/termination_abci packages/valory/skills/transaction_settlement_abci scripts +commands = darglint packages/valory/contracts/connext_propagate_job packages/valory/skills/keep3r_abci packages/valory/skills/keep3r_job packages/valory/contracts/deposit_manager_job packages/valory/contracts/keep3r_for_testnet packages/valory/contracts/keep3r_my_job packages/valory/contracts/keep3r_test_job packages/valory/contracts/keep3r_v1 packages/valory/contracts/keep3r_v1_library packages/valory/contracts/phuture_harvesting_job packages/valory/contracts/yearn_factory_harvest_job packages/valory/skills/registration_abci packages/valory/skills/reset_pause_abci packages/valory/skills/termination_abci packages/valory/skills/transaction_settlement_abci scripts [testenv:check-generate-all-protocols] skipsdist = True